ultimatepp/bazaar/Functions4U/QtfEquation.cpp
koldo cf8f23841a Functions4U: Added StaticPlugin
git-svn-id: svn://ultimatepp.org/upp/trunk@3247 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2011-02-25 16:27:43 +00:00

415 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//#pragma NO_BLITZ
#ifdef flagGUI
#include <CtrlLib/CtrlLib.h>
#include "Functions4U.h"
#include "Functions4U_Gui.h"
Drawing EquationDraw::Text(String text, bool italic, int offsetX, int offsetY, double betw)
{
Font fnt;
int _pos1, _pos2;
if ((_pos1 = text.Find('_', 0)) >= 0) {
String sub = text.Right(text.GetCount()-_pos1-1);
if ((_pos2 = sub.Find('_', 0)) >= 0)
sub = sub.Left(_pos2) + ',' + sub.Right(sub.GetCount()-_pos2-1);
return SubSup(text.Left(_pos1), sub, "");
}
fnt.Face(Font::ROMAN);
fnt.Height(400);
fnt.Italic(italic);
FontInfo fi = fnt.Info();
int width = 0;
WString wtext(text);
for (int i = 0; i < wtext.GetCount(); ++i)
width += fi[wtext[i]];
width += 10;
width = int(width*betw);
ImageDraw idw(width, fnt.GetHeight());
idw.DrawRect(Size(width, fnt.GetHeight()), White);
idw.DrawText(offsetX, offsetY, text, fnt);
DrawingDraw dw(width/3, fnt.GetHeight()/3);
dw.DrawImage(0, 0, width/3, fnt.GetHeight()/3, idw);
return dw;
}
Drawing EquationDraw::SubSup(Drawing &drwText, Drawing &drwSub, Drawing &drwSup)
{
Size szText = drwText.GetSize();
Size szSub = (2/3.)*drwSub.GetSize();
Size szSup = (2/3.)*drwSup.GetSize();
int width = szText.cx + max(szSup.cx, szSub.cx);
int deltay = szSup.cy/2;
DrawingDraw dw(width, szText.cy + szSup.cy/2 + szSub.cy/2);
dw.DrawDrawing(0, deltay, szText.cx, szText.cy, drwText);
dw.DrawDrawing(szText.cx, 0, szSup.cx, szSup.cy, drwSup);
dw.DrawDrawing(szText.cx, deltay + szText.cy - szSub.cy/2, szSub.cx, szSub.cy, drwSub);
return dw;
}
Drawing EquationDraw::SubSup(String text, String sub, String sup)
{
Drawing textdraw = Text(text, true);
Drawing subdraw = Text(sub, true);
Drawing supdraw = Text(sup, true);
return SubSup(textdraw, subdraw, supdraw);
}
Drawing EquationDraw::SubSup(Drawing &drwText, String sub, String sup)
{
Drawing subdraw = Text(sub, true);
Drawing supdraw = Text(sup, true);
return SubSup(drwText, subdraw, supdraw);
}
Drawing EquationDraw::SubSupInv(Drawing &drwText, Drawing &drwSub, Drawing &drwSup)
{
Size szText = drwText.GetSize();
Size szSub = (2/3.)*drwSub.GetSize();
Size szSup = (2/3.)*drwSup.GetSize();
int width = szText.cx + max(szSup.cx, szSub.cx);
int deltay = szSup.cy/2;
DrawingDraw dw(width, szText.cy + szSup.cy/2 + szSub.cy/2);
dw.DrawDrawing(width-szText.cx, deltay, szText.cx, szText.cy, drwText);
dw.DrawDrawing(0, 0, szSup.cx, szSup.cy, drwSup);
dw.DrawDrawing(0, deltay + szText.cy - szSub.cy/2, szSub.cx, szSub.cy, drwSub);
return dw;
}
Drawing EquationDraw::SubSupInv(String text, String sub, String sup)
{
Drawing textdraw = Text(text, true);
Drawing subdraw = Text(sub, true);
Drawing supdraw = Text(sup, true);
return SubSupInv(textdraw, subdraw, supdraw);
}
Drawing EquationDraw::SubSupInv(Drawing &drwText, String sub, String sup)
{
Drawing subdraw = Text(sub, true);
Drawing supdraw = Text(sup, true);
return SubSupInv(drwText, subdraw, supdraw);
}
Drawing EquationDraw::JoinCenter(Drawing &left, Drawing &right)
{
Size szLeft = left.GetSize();
Size szRight = right.GetSize();
int width = szLeft.cx + szRight.cx;
int height = max(szLeft.cy, szRight.cy);
DrawingDraw dw(width, height);
dw.DrawDrawing(0, height == szLeft.cy? 0: (height-szLeft.cy)/2, szLeft.cx, szLeft.cy, left);
dw.DrawDrawing(szLeft.cx, height == szRight.cy? 0: (height-szRight.cy)/2, szRight.cx, szRight.cy, right);
return dw;
}
Drawing EquationDraw::JoinFlex(Drawing &left, double betw1, Drawing &right, double betw2)
{
Size szLeft = left.GetSize();
Size szRight = right.GetSize();
int width = int(szLeft.cx*betw1 + szRight.cx*betw2);
int height = max(szLeft.cy, szRight.cy);
DrawingDraw dw(width, height);
dw.DrawDrawing(0, 0, szLeft.cx, height, left);
dw.DrawDrawing(int(szLeft.cx*betw1), 0, szRight.cx, height, right);
return dw;
}
Drawing EquationDraw::NumDenom(Drawing &num, Drawing &denom)
{
Size szNum = num.GetSize();
Size szDenom = denom.GetSize();
int width = max(szNum.cx, szDenom.cx);
int height = szNum.cy + szDenom.cy;
DrawingDraw dw(width, height);
dw.DrawDrawing(width == szNum.cx? 0: (width-szNum.cx)/2, 0, szNum.cx, szNum.cy, num);
dw.DrawDrawing(width == szDenom.cx? 0: (width-szDenom.cx)/2, szNum.cy, szDenom.cx, szDenom.cy, denom);
dw.DrawLine(0, szNum.cy, width, szNum.cy, 1);
return dw;
}
Drawing EquationDraw::Bracket(Drawing &data)
{
Drawing pizq = Text("(", true, 0, 0, 1.3);
Drawing pder = Text(")");
Drawing parizq = JoinFlex(pizq, 1, data, 1);
return JoinFlex(parizq, 1, pder, 1);
}
Drawing EquationDraw::Sqrt(Drawing &right)
{
Drawing left = Text("");
Size szLeft = left.GetSize();
Size szRight = right.GetSize();
int width = szLeft.cx + szRight.cx;
int height = max(szLeft.cy, szRight.cy);
DrawingDraw dw(width, height);
dw.DrawDrawing(0, 0, szLeft.cx, height, left);
dw.DrawDrawing(szLeft.cx, 1, szRight.cx, height-1, right);
dw.DrawLine(szLeft.cx, 0, width-szLeft.cx, 0, 1);
return dw;
}
Drawing EquationDraw::Integral(Drawing &data, Drawing &sub, Drawing &sup)
{
Drawing left = Text("");
Drawing right = SubSupInv(data, sub, sup);
Size szLeft = left.GetSize();
Size szRight = right.GetSize();
int sqWidth = szLeft.cx/3-20;
int width = sqWidth + szRight.cx;
int height = szRight.cy;
DrawingDraw dw(width, height);
dw.DrawDrawing(0, 0, (int)(szLeft.cx*1.5), height, left);
dw.DrawDrawing(sqWidth, 0, szRight.cx, height, right);
return dw;
}
Drawing EquationDraw::Summat(Drawing &data, Drawing &sub, Drawing &sup)
{
Drawing left = Text("", true, 0, -20);
Drawing right = SubSupInv(data, sub, sup);
Size szLeft = left.GetSize();
Size szRight = right.GetSize();
int sqWidth = szLeft.cx/3;
int width = sqWidth + szRight.cx;
int height = szRight.cy;
DrawingDraw dw(width, height);
dw.DrawDrawing(0, 0, (int)(szLeft.cx*1.1), height, left);
dw.DrawDrawing(sqWidth, 0, szRight.cx, height, right);
return dw;
}
Drawing EquationDraw::Exp(Drawing &data, Drawing &exp)
{
Drawing foo = Text("");
return SubSup(data, foo, exp);
}
Drawing EquationDraw::Function(String function, Drawing &content)
{
Drawing fundraw = Text(function);
Drawing pardraw = Bracket(content);
return JoinCenter(fundraw, pardraw);
}
Drawing EquationDraw::Equal(Drawing &left, Drawing &right)
{
Drawing equal = Text(" = ");
Drawing leftdraw = JoinCenter(left, equal);
return JoinCenter(leftdraw, right);
}
String EquationDraw::ReplaceSymbols(String var)
{
for (int i = 0; i < symbols.GetCount(); ++i) {
String letter = ToLower(symbols.GetKey(i));
if (var.Find(letter) >= 0)
var.Replace(letter, symbols[i].Mid(2));
letter = ToUpper(symbols.GetKey(i));
if (var.Find(letter) >= 0)
var.Replace(letter, symbols[i].Mid(0, 2));
}
return var;
}
Drawing EquationDraw::Term(CParser& p, bool noBracket)
{
if(p.Id("integral")) {
p.PassChar('(');
Drawing data = Exp(p);
p.PassChar(',');
Drawing sub = Exp(p);
p.PassChar(',');
Drawing sup = Exp(p);
p.PassChar(')');
return EquationDraw::Integral(data, sub, sup);
}
if(p.Id("summation")) {
p.PassChar('(');
Drawing data = Exp(p);
p.PassChar(',');
Drawing sub = Exp(p);
p.PassChar(',');
Drawing sup = Exp(p);
p.PassChar(')');
return EquationDraw::Summat(data, sub, sup);
}
if(p.Id("sqrt")) {
p.PassChar('(');
Drawing x = Exp(p);
p.PassChar(')');
return EquationDraw::Sqrt(x);
}
if(p.Id("cos")) {
p.PassChar('(');
Drawing x = Exp(p);
p.PassChar(')');
return EquationDraw::Function("cos", x);
}
if(p.IsId())
return EquationDraw::Text(ReplaceSymbols(p.ReadId()));
if(p.Char('(')) {
Drawing x = Exp(p);
p.PassChar(')');
if (noBracket)
return x;
else
return EquationDraw::Bracket(x);
}
return EquationDraw::Text(FormatDouble(p.ReadDouble()));
}
Drawing EquationDraw::Mul(CParser& p)
{
Drawing x = Term(p);
for(;;) {
if(p.Char('*')) {
Drawing mult = EquationDraw::Text(" ");
Drawing left = EquationDraw::JoinCenter(x, mult);
Drawing y = Term(p, false);
x = EquationDraw::JoinCenter(left, y);
} else if(p.Char('/')) {
Drawing y = Term(p, true);
x = EquationDraw::NumDenom(x, y);
} else if(p.Char('^')) {
Drawing y = Term(p, false);
x = EquationDraw::Exp(x, y);
} else
return x;
}
}
Drawing EquationDraw::Exp(CParser& p)
{
Drawing x = Mul(p);
for(;;) {
if(p.Char('+')) {
Drawing plus = EquationDraw::Text("+");
Drawing left = EquationDraw::JoinCenter(x, plus);
Drawing y = Mul(p);
x = EquationDraw::JoinCenter(left, y);
} else if(p.Char('-')) {
Drawing minus = EquationDraw::Text("-");
Drawing left = EquationDraw::JoinCenter(x, minus);
Drawing y = Mul(p);
x = EquationDraw::JoinCenter(left, y);
} else if(p.Char('=')) {
Drawing y = Mul(p);
x = EquationDraw::Equal(x, y);
} else
return x;
}
}
EquationDraw::EquationDraw()
{
symbols.GetAdd("alpha") = "Αα";
symbols.GetAdd("nu") = "Νν";
symbols.GetAdd("beta") = "Ββ";
symbols.GetAdd("xi") = "Ξξ";
symbols.GetAdd("gamma") = "Γγ";
symbols.GetAdd("omicron") = "Οο";
symbols.GetAdd("delta") = "Δδ";
symbols.GetAdd("pi") = "Ππ";
symbols.GetAdd("epsilon") = "Εε";
symbols.GetAdd("rho") = "Ρρ";
symbols.GetAdd("zeta") = "Ζζ";
symbols.GetAdd("sigma") = "Σσ";
symbols.GetAdd("eta") = " Ηη";
symbols.GetAdd("tau") = "Ττ";
symbols.GetAdd("theta") = "Θθ";
symbols.GetAdd("upsilon") = "Υυ";
symbols.GetAdd("iota") = "Ιι";
symbols.GetAdd("phi") = "Φφ";
symbols.GetAdd("kappa") = "Κκ";
symbols.GetAdd("chi") = "Χχ";
symbols.GetAdd("lambda") = "Λλ";
symbols.GetAdd("psi") = "Ψψ";
symbols.GetAdd("mu") = "Μμ";
symbols.GetAdd("omega") = "Ωω";
}
Drawing DrawEquation(String str)
{
EquationDraw equation;
CParser p(str);
try {
if(p.IsId()) {
String id;
CParser::Pos pos = p.GetPos();
id = p.ReadId();
p.SetPos(pos);
return equation.Exp(p);
} else
return equation.Exp(p);
}
catch(CParser::Error e) {
String res;
res << "ERROR: " << e << '\n';
return EquationDraw::Text(res);
}
}
QtfRichObject QtfEquation(String str)
{
Drawing drw = DrawEquation(str);
Size sz = drw.GetSize();
DrawingDraw dw(sz);
dw.DrawDrawing(0, 0, sz.cx, sz.cy, drw);
return QtfRichObject(CreateDrawingObject(dw.GetResult(), sz, sz));
}
#endif