diff --git a/doc/images/jkqtmathtext_MTlistNode_getSizeInternal_frac.cdr b/doc/images/jkqtmathtext_MTlistNode_getSizeInternal_frac.cdr deleted file mode 100644 index 7744a8acce..0000000000 Binary files a/doc/images/jkqtmathtext_MTlistNode_getSizeInternal_frac.cdr and /dev/null differ diff --git a/doc/images/jkqtmathtext_MTlistNode_getSizeInternal_frac.png b/doc/images/jkqtmathtext_MTlistNode_getSizeInternal_frac.png deleted file mode 100644 index fb3257f5f5..0000000000 Binary files a/doc/images/jkqtmathtext_MTlistNode_getSizeInternal_frac.png and /dev/null differ diff --git a/doc/images/jkqtmathtext_node_geo.cdr b/doc/images/jkqtmathtext_node_geo.cdr new file mode 100644 index 0000000000..155eccd4ef Binary files /dev/null and b/doc/images/jkqtmathtext_node_geo.cdr differ diff --git a/doc/images/jkqtmathtext_node_geo.png b/doc/images/jkqtmathtext_node_geo.png new file mode 100644 index 0000000000..925e9390a9 Binary files /dev/null and b/doc/images/jkqtmathtext_node_geo.png differ diff --git a/doc/images/jkqtmathtext_subscriptnode_getSizeInternal.cdr b/doc/images/jkqtmathtext_subscriptnode_getSizeInternal.cdr new file mode 100644 index 0000000000..5dd078c89c Binary files /dev/null and b/doc/images/jkqtmathtext_subscriptnode_getSizeInternal.cdr differ diff --git a/doc/images/jkqtmathtext_subscriptnode_getSizeInternal.png b/doc/images/jkqtmathtext_subscriptnode_getSizeInternal.png new file mode 100644 index 0000000000..49cb6ad6a5 Binary files /dev/null and b/doc/images/jkqtmathtext_subscriptnode_getSizeInternal.png differ diff --git a/doc/images/jkqtmathtext_superscriptnode_getSizeInternal.cdr b/doc/images/jkqtmathtext_superscriptnode_getSizeInternal.cdr new file mode 100644 index 0000000000..31b3efe455 Binary files /dev/null and b/doc/images/jkqtmathtext_superscriptnode_getSizeInternal.cdr differ diff --git a/doc/images/jkqtmathtext_superscriptnode_getSizeInternal.png b/doc/images/jkqtmathtext_superscriptnode_getSizeInternal.png new file mode 100644 index 0000000000..3edd1bf131 Binary files /dev/null and b/doc/images/jkqtmathtext_superscriptnode_getSizeInternal.png differ diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp index 8bacbd65df..5973556fe3 100644 --- a/examples/jkqtmathtext_test/testform.cpp +++ b/examples/jkqtmathtext_test/testform.cpp @@ -8,6 +8,7 @@ TestForm::TestForm(QWidget *parent) : ui(new Ui::TestForm) { ui->setupUi(this); + ui->cmbTestset->addItem("subsuperscript test", "$r_{123}^2$\\ \\ $r^2_{123}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_{123}^2$\\ \\ $\\left(\\stackrel{a}{b}\\right)^2_{123}$\\ \\ $r_{\\frac{1}{2}}^2$\\ \\ $r^2_{\\frac{1}{2}}$\\ \\ $r^{\\frac{1}{2}}_2$\\ \\ $r_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)^{\\frac{1}{2}}_2$"); ui->cmbTestset->addItem("simple relations", "$a{\\leq}b$, $a{\\geq}b$, $a{\\equiv}b$, $a=b$, $a{\\neq}b$, $ab$"); ui->cmbTestset->addItem("simple relations in different modes", "math: $a{\\leq}b$, math/no braces: $a\\leq b$, no math: a{\\leq}b, no math/no braces: a\\leq b"); ui->cmbTestset->addItem("named symbols 1", "ll: $\\ll$\\ gg: $\\gg$\\ leq: $\\leq$\\ geq: $\\geq$\\ pm: $\\pm$\\ mp: $\\mp$\\ "); @@ -41,7 +42,6 @@ TestForm::TestForm(QWidget *parent) : ui->cmbTestset->addItem("math: bf", "$\\mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); ui->cmbTestset->addItem("math: rm", "$\\mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); ui->cmbTestset->addItem("math: cal", "$\\mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("subsuperscript test", "$r_{123}^2$\\ \\ $r^2_{123}$\\ \\ $\\left(a\\right)_{123}^2$\\ \\ $\\left(a\\right)^2_{123}$\\ \\ $r_{\\frac{1}{2}}^2$\\ \\ $r^2_{\\frac{1}{2}}$\\ \\ $r^{\\frac{1}{2}}_2$\\ \\ $r_2^{\\frac{1}{2}}$\\ \\ $\\left(a\\right)_2^{\\frac{1}{2}}$\\ \\ $\\left(a\\right)^{\\frac{1}{2}}_2$"); ui->cmbTestset->addItem("subscript test", "$r_{123}\\ \\ r_{\\frac{1}{2}}$"); ui->cmbTestset->addItem("subscript0 test", "$r_{123}$"); ui->cmbTestset->addItem("subscript1 test", "$r_{123}\\ $"); diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp index 952709fd59..e1f8a3c474 100644 --- a/lib/jkqtmathtext/jkqtmathtext.cpp +++ b/lib/jkqtmathtext/jkqtmathtext.cpp @@ -198,10 +198,10 @@ JKQTMathText::MTnode::MTnode(JKQTMathText* parent) { JKQTMathText::MTnode::~MTnode() = default; -void JKQTMathText::MTnode::getSize(QPainter &painter, JKQTMathText::MTenvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos) +void JKQTMathText::MTnode::getSize(QPainter &painter, JKQTMathText::MTenvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, const MTnodeSize* prevNodeSize) { double w=width, b=baselineHeight, o=overallHeight, s=strikeoutPos; - getSizeInternal(painter, currentEv, w, b, o, s); + getSizeInternal(painter, currentEv, w, b, o, s, prevNodeSize); if (w<1e5) width=w; if (b<1e5) baselineHeight=b; @@ -213,6 +213,10 @@ bool JKQTMathText::MTnode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment return false; } +bool JKQTMathText::MTnode::getDrawBoxes() const { + return this->drawBoxes; +} + void JKQTMathText::MTnode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { if (drawBoxes) { @@ -263,7 +267,7 @@ JKQTMathText::MTtextNode::MTtextNode(JKQTMathText* parent, const QString& textIn JKQTMathText::MTtextNode::~MTtextNode() = default; -void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { QFont f=currentEv.getFont(parent); if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" || text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) || @@ -274,7 +278,7 @@ void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText:: QString txt=textTransform(text, currentEv, true); QFontMetricsF fm(f, painter.device()); QRectF br=fm.boundingRect(txt); - QRectF tbr=parent->getTBR(f, txt, painter.device()); //fm.tightBoundingRect(txt); + QRectF tbr=parent->getTightBoundingRect(f, txt, painter.device()); //fm.tightBoundingRect(txt); if (txt=="|") { br=fm.boundingRect("X"); tbr=QRect(0,0,fm.width("X"), fm.ascent());//fm.boundingRect("X"); @@ -293,7 +297,7 @@ void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText:: strikeoutPos=fm.strikeOutPos()*1.1; } -double JKQTMathText::MTtextNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTtextNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); double width=0; double baselineHeight=0; @@ -479,7 +483,7 @@ QString JKQTMathText::MTinstruction1Node::getTypeName() const return QLatin1String("MTinstruction1Node(")+name+")"; } -void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { JKQTMathText::MTenvironment ev=currentEv; setupMTenvironment(ev); @@ -494,7 +498,7 @@ void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMa } } -double JKQTMathText::MTinstruction1Node::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTinstruction1Node::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); JKQTMathText::MTenvironment ev=currentEv; @@ -578,39 +582,49 @@ JKQTMathText::MTsubscriptNode::~MTsubscriptNode() { if (child!=nullptr) delete child; } -void JKQTMathText::MTsubscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTsubscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { JKQTMathText::MTenvironment ev=currentEv; ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - QFontMetricsF fm(ev.getFont(parent), painter.device()); - double shift=parent->getSubShiftFactor()*parent->getTBR(ev.getFont(parent), "M", painter.device()).height(); - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - QFontMetricsF fmouter(currentEv.getFont(parent), painter.device()); - QRectF tbr=parent->getTBR(currentEv.getFont(parent), "M", painter.device()); - overallHeight=tbr.height()+shift+(overallHeight-baselineHeight); - baselineHeight=tbr.height(); - strikeoutPos=fmouter.strikeOutPos(); - if (currentEv.italic) width=width-double(fm.width(' '))*parent->getItalicCorrectionFactor(); + QFontMetricsF fm(ev.getFont(parent), painter.device()); + QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + double shift=parent->getSubShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { + shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); + } + + double yshift=baselineHeight-shift; + baselineHeight=shift; + strikeoutPos=fm.strikeOutPos()+yshift; + if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.width(' '))*parent->getItalicCorrectionFactor(); } -double JKQTMathText::MTsubscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTsubscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); JKQTMathText::MTenvironment ev=currentEv; ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - QFontMetricsF fm(ev.getFont(parent), painter.device()); + QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); - double shift=parent->getSubShiftFactor()*parent->getTBR(ev.getFont(parent), "M", painter.device()).height(); + double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; + child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + double shift=parent->getSubShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { + qDebug()<<"oldshift="<overallHeight="<overallHeight<<", prevNodeSize->baselineHeight="<baselineHeight; + shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); + qDebug()<<"newshift="<getItalicCorrectionFactor(); + return child->draw(painter, xx, y+yshift, ev);//+0.5*fm.boundingRect("A").width(); } QString JKQTMathText::MTsubscriptNode::getTypeName() const @@ -648,7 +662,7 @@ JKQTMathText::MTsqrtNode::~MTsqrtNode() { if (child!=nullptr) delete child; } -void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { QFontMetricsF fm(currentEv.getFont(parent), painter.device()); child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); @@ -658,7 +672,7 @@ void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText:: width=width+fm.boundingRect("A").width()*2; // 1.53 } -double JKQTMathText::MTsqrtNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTsqrtNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); double width=0, baselineHeight=0, overallHeight=0, sp=0; child->getSize(painter, currentEv, width, baselineHeight, overallHeight, sp); @@ -741,14 +755,14 @@ QString JKQTMathText::MTfracNode::getTypeName() const return "MTfracNode"; } -void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { QFontMetricsF fm(currentEv.getFont(parent), painter.device()); JKQTMathText::MTenvironment ev1=currentEv; JKQTMathText::MTenvironment ev2=currentEv; double xh=fm.xHeight(); //tightBoundingRect("x").height(); double sp=xh; - double Ah=parent->getTBR(currentEv.getFont(parent), "M", painter.device()).height();//fm.ascent(); + double Ah=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()).height();//fm.ascent(); double xw=fm.boundingRect("x").width(); if (mode==MTFMunderbrace || mode==MTFMoverbrace) { @@ -813,7 +827,7 @@ void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText:: } } -double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); QFont f=currentEv.getFont(parent); QFontMetricsF fm(f, painter.device()); @@ -821,10 +835,10 @@ double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQ JKQTMathText::MTenvironment ev2=currentEv; - double xh=parent->getTBR(f, "x", painter.device()).height(); //fm.xHeight(); + double xh=parent->getTightBoundingRect(f, "x", painter.device()).height(); //fm.xHeight(); double xw=fm.boundingRect("x").width(); double lw=qMax(0.0,ceil(currentEv.fontSize/16.0));//fm.lineWidth(); - double Ah=parent->getTBR(f, "M", painter.device()).height();//fm.ascent(); + double Ah=parent->getTightBoundingRect(f, "M", painter.device()).height();//fm.ascent(); double bw=Ah/2.0; if (mode==MTFMunderbrace || mode==MTFMoverbrace) { @@ -885,12 +899,13 @@ double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQ } else if (mode==MTFMoverbrace) { double ybrace=y-ascent1-bw/2.0; - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(x+xw/2.0+(width1)/2.0, ybrace); - painter.rotate(180); - QPainterPath path=makeHBracePath(0,0, width, bw); - painter.drawPath(path); - + { + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(x+xw/2.0+(width1)/2.0, ybrace); + painter.rotate(180); + QPainterPath path=makeHBracePath(0,0, width, bw); + painter.drawPath(path); + } child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-bw-descent2, ev2); @@ -951,7 +966,7 @@ QString JKQTMathText::MTmatrixNode::getTypeName() const return "MTmatrixNode"; } -void JKQTMathText::MTmatrixNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTmatrixNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { QFontMetricsF fm(currentEv.getFont(parent), painter.device()); JKQTMathText::MTenvironment ev1=currentEv; @@ -993,7 +1008,7 @@ void JKQTMathText::MTmatrixNode::getSizeInternal(QPainter& painter, JKQTMathText strikeoutPos=xh; } -double JKQTMathText::MTmatrixNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTmatrixNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); QFontMetricsF fm(currentEv.getFont(parent), painter.device()); @@ -1088,7 +1103,7 @@ JKQTMathText::MTdecoratedNode::~MTdecoratedNode() { if (child!=nullptr) delete child; } -void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { QFontMetricsF fm(currentEv.getFont(parent), painter.device()); double wc=fm.boundingRect("A").width(); double dheightfactor=1.0+parent->getDecorationHeightFactor()*2.0; @@ -1100,7 +1115,7 @@ void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathT width=width+0.3*wc; } -double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); MTenvironment ev=currentEv; double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; @@ -1248,39 +1263,47 @@ JKQTMathText::MTsuperscriptNode::~MTsuperscriptNode() { if (child!=nullptr) delete child; } -void JKQTMathText::MTsuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTsuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { JKQTMathText::MTenvironment ev=currentEv; ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - double shift=0;//parent->getSuperShiftFactor()*fm.ascent(); - overallHeight=overallHeight+shift; - strikeoutPos=fm.strikeOutPos(); - if (currentEv.italic) width=width+double(fm.width(' '))*parent->getItalicCorrectionFactor(); + double shift=parent->getSuperShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { + shift=prevNodeSize->baselineHeight-(overallHeight-baselineHeight)-shift; + } + + double yshift=shift+overallHeight-baselineHeight; + baselineHeight=overallHeight=overallHeight+shift; + strikeoutPos=strikeoutPos-yshift; + if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.width(' '))*parent->getItalicCorrectionFactor(); } -double JKQTMathText::MTsuperscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTsuperscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); JKQTMathText::MTenvironment ev=currentEv; ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - double cwidth, cbaselineHeight, coverallheight, cStrikeoutPos; - child->getSize(painter, ev, cwidth, cbaselineHeight, coverallheight, cStrikeoutPos); + double cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos; + child->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + double shift=parent->getSuperShiftFactor()*tbr.height(); - double shift=0;//parent->getSuperShiftFactor()*fm.ascent(); - //double shift=ev.; + if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { + shift=prevNodeSize->baselineHeight-(cOverallHeight-cBaselineHeight)-shift; + } + + double yshift=shift+cOverallHeight-cBaselineHeight; double xx=x; - if (currentEv.italic) xx=xx+double(fm.width(' '))*parent->getItalicCorrectionFactor(); + if (currentEv.italic && prevNodeSize==nullptr) xx=xx+double(fm.width(' '))*parent->getItalicCorrectionFactor(); - return child->draw(painter, xx, y-shift, ev);//+0.5*fm.boundingRect("A").width(); + return child->draw(painter, xx, y-yshift, ev);//+0.5*fm.boundingRect("A").width(); } -bool JKQTMathText::MTsuperscriptNode::isSubOrSuper() -{ - return true; -} QString JKQTMathText::MTsuperscriptNode::getTypeName() const { @@ -1321,7 +1344,7 @@ JKQTMathText::MTbraceNode::~MTbraceNode() { if (child!=nullptr) delete child; } -void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { JKQTMathText::MTenvironment ev=currentEv; child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); @@ -1339,7 +1362,7 @@ void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText: } -double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { //std::cout<<"drawing brace-node: '"<0) painter.drawLine(l); painter.drawPath(path); } else if (openbrace=="#" || openbrace=="||") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); if (l.length()>0) painter.drawLine(l); l=QLineF(xnew+brace_fraction*bracewidth-1.5*lw, y1, xnew+brace_fraction*bracewidth-1.5*lw, y2); if (l.length()>0) painter.drawLine(l); } else if (openbrace=="<") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; path.moveTo(xnew+brace_fraction*bracewidth, y1); path.lineTo(xnew, (y2+y1)/2.0); path.lineTo(xnew+brace_fraction*bracewidth, y2); @@ -1441,62 +1464,62 @@ double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JK painter.setPen(p); if (closebrace==")") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.cubicTo(xnew+bracewidth, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew+bracewidth, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+(1.0-brace_fraction)*bracewidth, y2); painter.drawPath(path); } else if (closebrace=="]") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.lineTo(xnew+bracewidth-lw/2.0, y1); path.lineTo(xnew+bracewidth-lw/2.0, y2); path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); painter.drawPath(path); } else if (closebrace=="}") { - QPainterPath path=makeHBracePath(0,0,coverallHeight, bracewidth*brace_fraction); + QPainterPath path=makeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(xnew+bracewidth*brace_fraction, y-cbaselineHeight+coverallHeight/2.0); + painter.translate(xnew+bracewidth*brace_fraction, y-cBaselineHeight+cOverallHeight/2.0); painter.rotate(270); painter.drawPath(path); } else if (closebrace=="_") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.lineTo(xnew+bracewidth, y1); path.lineTo(xnew+bracewidth, y2); painter.drawPath(path); } else if (closebrace=="~") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; path.moveTo(xnew+bracewidth, y1); path.lineTo(xnew+bracewidth, y2); path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); painter.drawPath(path); } else if (closebrace=="|") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); if (l.length()>0) painter.drawLine(l); painter.drawPath(path); } else if (closebrace=="#" || closebrace=="||") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); if (l.length()>0) painter.drawLine(l); l=QLineF(xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y1, xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y2); if (l.length()>0) painter.drawLine(l); } else if (closebrace==">") { QPainterPath path; - double y1=y+(coverallHeight-cbaselineHeight); - double y2=y-cbaselineHeight; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.lineTo(xnew+bracewidth, (y2+y1)/2.0); path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); @@ -1595,23 +1618,27 @@ QString JKQTMathText::MTlistNode::getTypeName() const return "MTlistNode"; } -void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { width=0; overallHeight=0; baselineHeight=0; strikeoutPos=0; QFontMetricsF fm(currentEv.getFont(parent)); - QRectF tbr=parent->getTBR(currentEv.getFont(parent), "M", painter.device()); + QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); double xnew=0; bool wasBrace=false; for (int i=0; igetSize(painter, currentEv, w1, bh, oh, sp); - //qDebug()<<"i="<getTypeName()<<" w1="<getTypeName()<<" w2="<getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr); + if (bh>baselineHeight) { + overallHeight=overallHeight+bh-baselineHeight; + baselineHeight=bh; + strikeoutPos=sp; + } + if (baselineHeight+oh-bh>overallHeight) { + overallHeight=baselineHeight+oh-bh; + strikeoutPos=sp; } - //qDebug()<<"sub_super: sub: "<getTypeName()<<" w1="<getTypeName()<<" w2="<getSuperShiftFactor()*tbr.height()+(oh-bh);//((overallHeight-baselineHeight)+(oh-bh)); - if (wasBrace) { - shift=baselineHeight-parent->getSuperShiftFactor()*tbr.height()+(oh-bh); - } - //qDebug()<<"+++ super: bh="<baselineHeight) { - double lheight=overallHeight-baselineHeight; - baselineHeight=shift+bh; - overallHeight=baselineHeight+lheight; - } - //qDebug()<<"### super"; - //qDebug()<<"### subsupop: super overallHeight="<overallHeight-baselineHeight) { - overallHeight=baselineHeight+shift+(oh-bh); - } - //qDebug()<<"### sub"; - //qDebug()<<"### subsupop: sub overallHeight="<getTBR(currentEv.getFont(parent), "M", painter.device()); bool wasBrace=false; for (int i=0; i0 && wasBrace) { + nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); + prevNodeSizePtr=&prevNodeSize; + } + + MTsymbolNode* smb=dynamic_cast(nodes[i]); // if we find a subscript/superscript node we check whether the next node is super/subscript // if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly if (dynamic_cast(nodes[i])) { - double ccwidth=0, ccbaselineHeight=0, ccoverallHeight=0, ccstrieoutPos=0; - nodes[i]->getSize(painter, currentEv, ccwidth, ccbaselineHeight, ccoverallHeight, ccstrieoutPos); if (i+1(nodes[i+1])) { // is this subscript? - double shift=-parent->getSuperShiftFactor()*tbr.height(); - if (wasBrace) { - shift=-cbaselineHeight+parent->getSuperShiftFactor()*tbr.height(); - } //painter.setPen(QPen("red")); - //painter.drawEllipse(xnew-4,ynew+shift-(ccoverallHeight-ccbaselineHeight)-4,8,8); - double xnew1=nodes[i]->draw(painter, xnew, ynew+shift-(ccoverallHeight-ccbaselineHeight), currentEv); + //painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8); + double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); i++; //painter.setPen(QPen("magenta")); //painter.drawEllipse(xnew-4,ynew-4,8,8); - double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv); + double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); //i++; xnew=qMax(xnew1, xnew2); doDraw=false; @@ -1864,20 +1873,13 @@ double JKQTMathText::MTlistNode::draw(QPainter& painter, double x, double y, JKQ } else if (dynamic_cast(nodes[i])) { if (i+1(nodes[i+1])) { // is this subscript? + //painter.setPen(QPen("red")); + //painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8); + double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); + i++; //painter.setPen(QPen("magenta")); //painter.drawEllipse(xnew-4,ynew-4,8,8); - double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv); - i++; - double ccwidth=0, ccbaselineHeight=0, ccoverallHeight=0, ccstrieoutPos=0; - nodes[i]->getSize(painter, currentEv, ccwidth, ccbaselineHeight, ccoverallHeight, ccstrieoutPos); - //QRectF tbr=fm.tightBoundingRect("M"); - double shift=-parent->getSuperShiftFactor()*tbr.height(); - if (wasBrace) { - shift=-cbaselineHeight+parent->getSuperShiftFactor()*tbr.height(); - } - //painter.setPen(QPen("red")); - //painter.drawEllipse(xnew-4,ynew+shift-(ccoverallHeight-ccbaselineHeight)-4,8,8); - double xnew2=nodes[i]->draw(painter, xnew, ynew+shift-(ccoverallHeight-ccbaselineHeight), currentEv); + double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); //i++; xnew=qMax(xnew1, xnew2); doDraw=false; @@ -1959,25 +1961,10 @@ double JKQTMathText::MTlistNode::draw(QPainter& painter, double x, double y, JKQ } } } - - nodes[i]->getSize(painter, currentEv, cwidth, cbaselineHeight, coverallHeight, cstrieoutPos); } if (i(nodes[i])) { // is this superscript? - double ccwidth=0, ccbaselineHeight=0, ccoverallHeight=0, ccstrieoutPos=0; - nodes[i]->getSize(painter, currentEv, ccwidth, ccbaselineHeight, ccoverallHeight, ccstrieoutPos); - //QRectF tbr=fm.tightBoundingRect("M"); - double shift=-parent->getSuperShiftFactor()*tbr.height(); - if (wasBrace) { - shift=-cbaselineHeight+parent->getSuperShiftFactor()*tbr.height(); - } - //painter.setPen(QPen("red")); - //painter.drawEllipse(xnew-4,ynew+shift-(ccoverallHeight-ccbaselineHeight)-4,8,8); - xnew=nodes[i]->draw(painter, xnew, ynew+shift-(ccoverallHeight-ccbaselineHeight), currentEv); - } else { - xnew=nodes[i]->draw(painter, xnew, ynew, currentEv); - } + xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); } wasBrace=dynamic_cast(nodes[i]); } @@ -2746,7 +2733,7 @@ QFont JKQTMathText::MTsymbolNode::getFontName(symbolFont f, QFont& fi) { return fr; } -void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { +void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { QFont f=currentEv.getFont(parent); f=getFontName(font, f); f.setPointSizeF(f.pointSizeF()*fontFactor); @@ -2757,7 +2744,7 @@ void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText QFontMetricsF fm(f, painter.device()); QString symb=symbol; width=0; - if (currentEv.insideMath) width=qMax(parent->getTBR(f, symb, painter.device()).width(),parent->getTBR(f, "i", painter.device()).width());//fm.width(symbol); + if (currentEv.insideMath) width=qMax(parent->getTightBoundingRect(f, symb, painter.device()).width(),parent->getTightBoundingRect(f, "i", painter.device()).width());//fm.width(symbol); else width=fm.boundingRect(symb).width();//fm.width(symbol); width=qMax(fm.width("j"), width); @@ -2765,20 +2752,20 @@ void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText width=fm.width("a"); if (symbolName=="|") width=fm.width("1")*0.8; else if (symbolName=="infty") width=fm.width("M"); - else if (symbolName=="quad") width=parent->getTBR(f, "M", painter.device()).width(); - else if (symbolName==" ") width=parent->getTBR(f, "x", painter.device()).width(); - else if (symbolName==";") width=parent->getTBR(f, "x", painter.device()).width()*0.75; - else if (symbolName==":") width=parent->getTBR(f, "x", painter.device()).width()*0.5; - else if (symbolName==",") width=parent->getTBR(f, "x", painter.device()).width()*0.25; - else if (symbolName=="!") width=-parent->getTBR(f, "x", painter.device()).width()*0.25; - else if (symbolName=="longleftarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="longrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="Longleftarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="Longrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="longleftrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="Longleftrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="quad") width=parent->getTightBoundingRect(f, "M", painter.device()).width(); + else if (symbolName==" ") width=parent->getTightBoundingRect(f, "x", painter.device()).width(); + else if (symbolName==";") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.75; + else if (symbolName==":") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.5; + else if (symbolName==",") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.25; + else if (symbolName=="!") width=-parent->getTightBoundingRect(f, "x", painter.device()).width()*0.25; + else if (symbolName=="longleftarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="longrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="Longleftarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="Longrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="longleftrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="Longleftrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } } - QRectF tbr=parent->getTBR(f, symb, painter.device()); + QRectF tbr=parent->getTightBoundingRect(f, symb, painter.device()); overallHeight=tbr.height();// fm.height(); baselineHeight=tbr.height()-tbr.bottom(); if (exactAscent) { @@ -2798,7 +2785,7 @@ void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText } -double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { +double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { doDrawBoxes(painter, x, y, currentEv); double width=0; double baselineHeight=0; @@ -2837,7 +2824,7 @@ double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, J // if the symbol has been recognized in the constructor: draw the symbol painter.drawText(QPointF(x+shift, y+yfactor*overallHeight), symbol); double xx=x+shift; - double yy=y-fm.xHeight()-(parent->getTBR(f, "M", painter.device()).height()-fm.xHeight())/3.0; + double yy=y-fm.xHeight()-(parent->getTightBoundingRect(f, "M", painter.device()).height()-fm.xHeight())/3.0; QLineF l(xx, yy, xx+xwi/3.0+((currentEv.italic)?(xwi/3.0):0), yy); if (drawBar&&l.length()>0) painter.drawLine(l); @@ -2872,43 +2859,43 @@ double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, J } else if (symbolName==",") { // 25% space } else if (symbolName=="!") { // -25% space } else if (symbolName=="longleftarrow") { - double width=parent->getTBR(f, "X", painter.device()).width()*3.0; - double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, false); + double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); painter.drawPath(path); } else if (symbolName=="longrightarrow"){ - double width=parent->getTBR(f, "X", painter.device()).width()*3.0; - double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, false, true); + double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); painter.drawPath(path); } else if (symbolName=="Longleftarrow") { - double width=parent->getTBR(f, "X", painter.device()).width()*3.0; - double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, false); + double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); painter.drawPath(path); } else if (symbolName=="Longrightarrow") { - double width=parent->getTBR(f, "X", painter.device()).width()*3.0; - double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, false, true); + double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); painter.drawPath(path); } else if (symbolName=="longleftrightarrow") { - double width=parent->getTBR(f, "X", painter.device()).width()*3.0; - double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, true); + double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); painter.drawPath(path); } else if (symbolName=="Longleftrightarrow") { - double width=parent->getTBR(f, "X", painter.device()).width()*3.0; - double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, true); + double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); painter.drawPath(path); } else { // draw a box to indicate an unavailable symbol - QRectF tbr=parent->getTBR(f, "M", painter.device()); + QRectF tbr=parent->getTightBoundingRect(f, "M", painter.device()); painter.drawRect(QRectF(x+shift,y-tbr.height(), xwi, tbr.height()*0.8)); } painter.setPen(pold); @@ -3199,15 +3186,15 @@ JKQTMathText::JKQTMathText(QObject* parent): default_brace_factor=brace_factor=1.04; default_subsuper_size_factor=subsuper_size_factor=0.7; default_italic_correction_factor=italic_correction_factor=0.4; - default_sub_shift_factor=sub_shift_factor=0.6; - default_super_shift_factor=super_shift_factor=0.5; + default_sub_shift_factor=sub_shift_factor=0.4; + default_super_shift_factor=super_shift_factor=0.6; default_brace_shrink_factor=brace_shrink_factor=0.6; default_fontColor=fontColor=QColor("black"); default_useSTIXfonts=useSTIXfonts=false; default_useXITSfonts=useXITSfonts=false; default_useASANAfonts=useASANAfonts=false; default_frac_factor=frac_factor=0.9; - default_frac_shift_factor=frac_shift_factor=0.5; + default_frac_shift_factor=frac_shift_factor=0.4; default_underbrace_factor=underbrace_factor=0.75; default_undersetFactor=undersetFactor=0.7; default_decoration_height_factor=decoration_height_factor=0.2; @@ -4039,7 +4026,7 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu QList JKQTMathText::tbrs=QList(); QHash JKQTMathText::tbrh=QHash(); -QRectF JKQTMathText::getTBR(const QFont &fm, const QString &text, QPaintDevice *pd) +QRectF JKQTMathText::getTightBoundingRect(const QFont &fm, const QString &text, QPaintDevice *pd) { JKQTMathText::tbrDataH dh(fm, text, pd); if (pd) { @@ -4406,3 +4393,5 @@ void initJKQTMathTextResources() { Q_INIT_RESOURCE(xits); } + +JKQTMathText::MTnodeSize::MTnodeSize(): width(0), baselineHeight(0),overallHeight(0),strikeoutPos() {} diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h index c2298848e1..c56c3e090a 100644 --- a/lib/jkqtmathtext/jkqtmathtext.h +++ b/lib/jkqtmathtext/jkqtmathtext.h @@ -666,51 +666,110 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { protected: /** \brief the available fonts */ - enum MTenvironmentFont { MTEroman, MTEsans, MTEtypewriter, MTEscript, MTEblackboard, MTEcaligraphic }; + enum MTenvironmentFont { + MTEroman, + MTEsans, + MTEtypewriter, + MTEscript, + MTEblackboard, + MTEcaligraphic + }; /** \brief describes the current drawing environment (base fontname ...) */ struct MTenvironment { MTenvironment(); + /** \brief current font color */ QColor color; + /** \brief current font */ MTenvironmentFont font; + /** \brief current font size [pt] */ double fontSize; + /** \brief is the text currently bold? */ bool bold; + /** \brief is the text currently italic? */ bool italic; + /** \brief is the text currently in small caps? */ bool smallCaps; + /** \brief is the text currently underlined? */ bool underlined; + /** \brief is the text currently overlined? */ bool overline; + /** \brief is the text currently stroke through? */ bool strike; + /** \brief is the text currently are we inside a math environment? */ bool insideMath; + /** \brief build a QFont object from the settings in this object */ QFont getFont(JKQTMathText* parent) const; + /** \brief generate a HTML prefix that formats the text after it according to the settings in this object + * + * \param defaultEv environment before applying the current object (to detect changes) + * \see toHtmlAfter() + */ QString toHtmlStart(MTenvironment defaultEv) const; + /** \brief generate a HTML postfix that formats the text in front of it according to the settings in this object + * + * \param defaultEv environment before applying the current object (to detect changes) + * \see toHtmlAfter() + */ QString toHtmlAfter(MTenvironment defaultEv) const; }; + /** \brief beschreibt die Größe eines Knotens */ + struct MTnodeSize { + MTnodeSize(); + double width; + double baselineHeight; + double overallHeight; + double strikeoutPos; + }; + public: - /** \brief subclass representing one node in the syntax tree */ + /** \brief subclass representing one node in the syntax tree + * + * \image html jkqtmathtext_node_geo.png + */ class MTnode { public: MTnode(JKQTMathText* parent); virtual ~MTnode(); - /** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal() */ - void getSize(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos); - /** \brief draw the contents at the designated position. returns the x position which to use for the next part of the text */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv)=0; - /** \brief returns true if node is subscript or superscript node */ - virtual bool isSubOrSuper() { return false; } - /** \brief convert node to HTML and returns \c true on success */ + /** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal() + * + * \param painter painter to use for determining the size + * \param currentEv current environment object + * \param[out] width width of the block/node + * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline + * \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight + * \param[out] strikeoutPos position of the strikeout-line + * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) + * + */ + void getSize(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr); + /** \brief draw the contents at the designated position + * + * \param painter QPainter to use + * \param x x-position, where the drawing starts [Pixel] + * \param y Y-position of the baseline, where the drawing starts [Pixel] + * \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings + * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) + * \return the x position which to use for the next part of the text + */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr)=0; + /** \brief convert node to HTML and returns \c true on success + * \param[out] html new HTML code is APPENDED to this string + * \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings + * \param defaultEv JKQTMathText::MTenvironment object describing the default drawing environment/settings when starting to interpret a node tree + * \return \c true on success + */ virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - /*! \brief returns the property drawBoxes ( \copybrief drawBoxes ). - \details Description of the parameter drawBoxes is:
\copydoc drawBoxes
. - \see drawBoxes for more information */ - inline bool getDrawBoxes() const { - return this->drawBoxes; - } + /** \brief returns the drawing of colored boxes (for DEBUGGING) around the actual output of the node is enabled */ + bool getDrawBoxes() const; + /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ virtual void setDrawBoxes(bool draw); + /** \brief return the name of this class as a string */ virtual QString getTypeName() const; protected: /** \brief determine the size of the node, overwrite this function in derived classes @@ -721,12 +780,22 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline * \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight * \param[out] strikeoutPos position of the strikeout-line + * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) * */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos)=0; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr)=0; + /** \brief parent JKQTMathText object (required for several drawing operations */ JKQTMathText* parent; + /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ bool drawBoxes; + /** \brief draws colored boxes (for DEBUGGING) around the actual output of the node + * + * \param painter QPainter to use + * \param x x-position, where the drawing starts [Pixel] + * \param y Y-position of the baseline, where the drawing starts [Pixel] + * \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings + */ void doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv); }; @@ -734,9 +803,11 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTtextNode: public MTnode { public: MTtextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); - virtual ~MTtextNode(); - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); + virtual ~MTtextNode() override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /*! \brief returns the property text ( \copybrief text ). \details Description of the parameter text is:
\copydoc text
. \see text for more information */ @@ -746,8 +817,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { virtual QString getTypeName() const override ; protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; QString text; + /** \brief transforms the text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */ virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false); }; @@ -755,28 +827,35 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTplainTextNode: public MTtextNode { public: MTplainTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); - virtual QString getTypeName() const; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; protected: - virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false); + /** \copydoc MTtextNode::textTransform() */ + virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false) override; }; /** \brief subclass representing one whitepsace node in the syntax tree */ class MTwhitespaceNode: public MTtextNode { public: MTwhitespaceNode(JKQTMathText* parent); - virtual ~MTwhitespaceNode(); - virtual QString getTypeName() const; + virtual ~MTwhitespaceNode() override; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; /** \brief convert node to HTML and returns \c true on success */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; }; /** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree */ class MTsymbolNode: public MTnode { public: MTsymbolNode(JKQTMathText* parent, const QString& name, bool addWhitespace); - virtual ~MTsymbolNode(); - virtual QString getTypeName() const; - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); + virtual ~MTsymbolNode() override; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /*! \brief returns the property symbolName ( \copybrief symbolName ). \details Description of the parameter symbolName is:
\copydoc symbolName
. \see symbolName for more information */ @@ -785,7 +864,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; /** \brief this string will be sent to the drawText method with properly set fonts */ QString symbol; /** \brief the symbol name supplied to the constructor */ @@ -812,18 +891,20 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { }; /** \brief subclass representing a list of nodes in the syntax tree - * - * \image html jkqtmathtext_MTlistNode_getSizeInternal_frac.png */ class MTlistNode: public MTnode { public: MTlistNode(JKQTMathText* parent); - virtual ~MTlistNode(); - virtual QString getTypeName() const; - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); + virtual ~MTlistNode() override; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; void addNode(MTnode* n) { nodes.append(n); } - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; /*! \brief returns the property nodes ( \copybrief nodes ). \details Description of the parameter nodes is:
\copydoc nodes
. \see nodes for more information */ @@ -832,7 +913,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; QList nodes; QSet subsupOperations; }; @@ -841,16 +922,18 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTinstruction1Node: public MTnode { public: MTinstruction1Node(JKQTMathText* parent, const QString& name, MTnode* child, const QStringList& parameters=QStringList()); - virtual ~MTinstruction1Node(); - virtual QString getTypeName() const; - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); + virtual ~MTinstruction1Node() override; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; /** \brief convert node to HTML and returns \c true on success */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); - /*! \brief returns the property child ( \copybrief child ). - \details Description of the parameter child is:
\copydoc child
. - \see child for more information */ - inline MTnode* getChild() const { + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /*! \brief returns the child node */ + inline MTnode* getChild() const { return this->child; } /*! \brief returns the property name ( \copybrief name ). @@ -867,7 +950,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; bool setupMTenvironment(JKQTMathText::MTenvironment &ev); MTnode* child; @@ -877,49 +960,56 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { - /** \brief subclass representing an subscript node with exactly one argument in the syntax tree */ + /** \brief subclass representing an subscript node with exactly one argument in the syntax tree + * + * \image html jkqtmathtext_subscriptnode_getSizeInternal.png + */ class MTsubscriptNode: public MTnode { public: MTsubscriptNode(JKQTMathText* parent, MTnode* child); - virtual ~MTsubscriptNode(); - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - /** \brief returns true if node is subscript or superscript node */ - virtual bool isSubOrSuper() ; - virtual QString getTypeName() const; - /*! \brief returns the property child ( \copybrief child ). - \details Description of the parameter child is:
\copydoc child
. - \see child for more information */ - inline MTnode* getChild() const { + virtual ~MTsubscriptNode() override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; /*! \brief returns the child node */ + inline MTnode* getChild() const { return this->child; } - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; MTnode* child; }; - /** \brief subclass representing an superscript node with exactly one argument in the syntax tree */ + /** \brief subclass representing an superscript node with exactly one argument in the syntax tree + * + * \image html jkqtmathtext_subscriptnode_getSizeInternal.png + * + * \note a MTlistNode might modify the positioning slightly for special cases (e.g. \c \\int , \c \\sum ... or after braces) + */ class MTsuperscriptNode: public MTnode { public: MTsuperscriptNode(JKQTMathText* parent, MTnode* child); - virtual ~MTsuperscriptNode(); - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - /** \brief returns true if node is subscript or superscript node */ - virtual bool isSubOrSuper(); - /*! \brief returns the property child ( \copybrief child ). - \details Description of the parameter child is:
\copydoc child
. - \see child for more information */ + virtual ~MTsuperscriptNode() override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /*! \brief returns the child node */ inline MTnode* getChild() const { return this->child; } - virtual QString getTypeName() const; - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; MTnode* child; }; @@ -927,15 +1017,17 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTbraceNode: public MTnode { public: MTbraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, MTnode* child, bool showRightBrace=true); - virtual ~MTbraceNode(); - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); - virtual QString getTypeName() const; - /*! \brief returns the property child ( \copybrief child ). - \details Description of the parameter child is:
\copydoc child
. - \see child for more information */ - inline MTnode* getChild() const { + virtual ~MTbraceNode() override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \copydoc MTnode::getTypeName() */ + virtual QString getTypeName() const override; + /*! \brief returns the child node */ + inline MTnode* getChild() const { return this->child; } /*! \brief returns the property openbrace ( \copybrief openbrace ). @@ -958,7 +1050,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; MTnode* child; QString openbrace; QString closebrace; @@ -972,15 +1064,16 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTsqrtNode: public MTnode { public: MTsqrtNode(JKQTMathText* parent, MTnode* child, int degree=2); - virtual ~MTsqrtNode(); - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); + virtual ~MTsqrtNode() override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; virtual QString getTypeName() const ; - /*! \brief returns the property child ( \copybrief child ). - \details Description of the parameter child is:
\copydoc child
. - \see child for more information */ - inline MTnode* getChild() const { + /*! \brief returns the child node */ + inline MTnode* getChild() const { return this->child; } /*! \brief returns the property degree ( \copybrief degree ). @@ -991,7 +1084,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; MTnode* child; int degree; }; @@ -1013,21 +1106,20 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTfracNode: public MTnode { public: MTfracNode(JKQTMathText* parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode); - virtual ~MTfracNode(); + virtual ~MTfracNode() override; virtual QString getTypeName() const ; - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); - /*! \brief returns the property child1 ( \copybrief child1 ). - \details Description of the parameter child1 is:
\copydoc child1
. - \see child1 for more information */ - inline MTnode* getChild1() const { + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /*! \brief returns the 1st child node */ + inline MTnode* getChild1() const { return this->child1; } - /*! \brief returns the property child2 ( \copybrief child2 ). - \details Description of the parameter child2 is:
\copydoc child2
. - \see child2 for more information */ - inline MTnode* getChild2() const { + /*! \brief returns the 2nd child node */ + inline MTnode* getChild2() const { return this->child2; } /*! \brief returns the property mode ( \copybrief mode ). @@ -1038,7 +1130,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; MTnode* child1; MTnode* child2; MTfracMode mode; @@ -1049,13 +1141,12 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { public: MTmatrixNode(JKQTMathText* parent, QVector > children); virtual ~MTmatrixNode() override; + /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override; - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv) override; + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /*! \brief returns the property children ( \copybrief children ). - \details Description of the parameter children is:
\copydoc children
. - \see children for more information */ - inline QVector > getChildren() const { + /*! \brief returns the child nodes */ + inline QVector > getChildren() const { return this->children; } /*! \brief returns the property columns ( \copybrief columns ). @@ -1072,8 +1163,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; - virtual void setDrawBoxes(bool draw); + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; QVector > children; int columns; int lines; @@ -1099,15 +1191,16 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { class MTdecoratedNode: public MTnode { public: MTdecoratedNode(JKQTMathText* parent, MTdecoration decoration, MTnode* child); - virtual ~MTdecoratedNode(); - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - virtual void setDrawBoxes(bool draw); + virtual ~MTdecoratedNode() override; + /** \copydoc MTnode::draw() */ + virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \copydoc MTnode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; + /** \copydoc MTnode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; virtual QString getTypeName() const ; - /*! \brief returns the property child ( \copybrief child ). - \details Description of the parameter child is:
\copydoc child
. - \see child for more information */ - inline MTnode* getChild() const { + /*! \brief returns the child node */ + inline MTnode* getChild() const { return this->child; } /*! \brief returns the property decoration ( \copybrief decoration ). @@ -1118,7 +1211,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { } protected: /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; + virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; MTnode* child; MTdecoration decoration; }; @@ -1386,7 +1479,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject { }; static QList tbrs; static QHash tbrh; - static QRectF getTBR(const QFont &fm, const QString& text, QPaintDevice *pd); + static QRectF getTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd); };