diff --git a/doc/dox/todo.dox b/doc/dox/todo.dox index aac2ab7f7d..cad6088d0d 100644 --- a/doc/dox/todo.dox +++ b/doc/dox/todo.dox @@ -41,7 +41,7 @@ This page lists several todos and wishes for future version of JKQTPlotter
  • add instruction for unicode-characters \char"XXXX, \unicode{XXXX}, \utf8{XXXX}, \utf16{XXXX}, \utf32{XXXX} ...
  • check sub/superscript with italic text in math mode, possibly a correction is necessary
  • explore where QFontMetricsF::horizontalAdvance() can be used (for Qt >=5.15)
  • -
  • correction of frac-height (2*maxHeight or height1+height2) should be done by brace-node, not frac-node
  • +
  • diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index ba9bbd9f48..b67d46f141 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -15,10 +15,10 @@ This page lists release notes for the different version of JKQTPlotter Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include: diff --git a/doc/images/jkqtmathtext_bracenode_geo.cdr b/doc/images/jkqtmathtext_bracenode_geo.cdr new file mode 100644 index 0000000000..a73f5cf4d7 Binary files /dev/null and b/doc/images/jkqtmathtext_bracenode_geo.cdr differ diff --git a/doc/images/jkqtmathtext_bracenode_geo.png b/doc/images/jkqtmathtext_bracenode_geo.png new file mode 100644 index 0000000000..3606282ad8 Binary files /dev/null and b/doc/images/jkqtmathtext_bracenode_geo.png differ diff --git a/doc/images/mathparser/JKQTMathTextMakeArrow.png b/doc/images/mathparser/JKQTMathTextMakeArrow.png new file mode 100644 index 0000000000..2865effd11 Binary files /dev/null and b/doc/images/mathparser/JKQTMathTextMakeArrow.png differ diff --git a/doc/images/mathparser/JKQTMathTextMakeDArrow.png b/doc/images/mathparser/JKQTMathTextMakeDArrow.png new file mode 100644 index 0000000000..be7fa76215 Binary files /dev/null and b/doc/images/mathparser/JKQTMathTextMakeDArrow.png differ diff --git a/doc/images/mathparser/JKQTMathTextMakeHBracePath.png b/doc/images/mathparser/JKQTMathTextMakeHBracePath.png new file mode 100644 index 0000000000..336a551aec Binary files /dev/null and b/doc/images/mathparser/JKQTMathTextMakeHBracePath.png differ diff --git a/examples/jkqtmathtext_test/mathtest.pdf b/examples/jkqtmathtext_test/mathtest.pdf index d0e3b3f2f3..4af49cdf73 100644 Binary files a/examples/jkqtmathtext_test/mathtest.pdf and b/examples/jkqtmathtext_test/mathtest.pdf differ diff --git a/examples/jkqtmathtext_test/mathtest.tex b/examples/jkqtmathtext_test/mathtest.tex index 02ba2336cb..dd344d7bed 100644 --- a/examples/jkqtmathtext_test/mathtest.tex +++ b/examples/jkqtmathtext_test/mathtest.tex @@ -35,6 +35,9 @@ \newcommand{\uul}[1]{\uuline{#1}} \newcommand{\ool}[1]{\overline{\overline{#1}}} \newcommand{\arrow}[1]{\overrightarrow{#1}} + +\newcommand{\stkout}[1]{\ifmmode\text{\sout{\ensuremath{#1}}}\else\sout{#1}\fi} + \begin{document} \begin{itemize} @@ -130,6 +133,7 @@ \item\textbf{math: integrals:} no-limits: \[Hxq \int_{0}^1 f(x)\;\mathrm{d}x\ \iint_{0}^1 f(x)\;\mathrm{d}x\ \iiint_{0}^1 f(x)\;\mathrm{d}x\ \oint_{0}^1 f(x)\;\mathrm{d}x\ \int_{x} f(x)\;\mathrm{d}x\]\ \ \ --\ \ \ limits: \[\int\limits_{0}^1 f(x)\;\mathrm{d}x\ \iint\limits_{0}^1 f(x)\;\mathrm{d}x\ \iiint\limits_{0}^1 f(x)\;\mathrm{d}x\ \oint\limits_{0}^1 f(x)\;\mathrm{d}x\ \int\limits_{x} f(x)\;\mathrm{d}x\] \item\textbf{math: frac test:} \[\frac{a}{b}+\frac{g}{a}-\frac{a^2}{b^2}\cdot\frac{a^2}{b^{\frac{1}{2}}}\] \item\textbf{sfrac:} Hxq \sfrac{1}{2} \ \ -- \ \ $Hxq \frac{1}{2}\ \ \sfrac{1}{2}\ \ \frac{1}{2+\frac{1}{2}}\ \ \sfrac{1}{2+\sfrac{1}{2}}\ \ \sfrac{1}{2+\frac{1}{2}}\ \ \sfrac{\frac{1}{2+\frac{1}{2}}}{2}\ \ e^{\sfrac{1}{2}}$ + \item\textbf{brace+sub/superscript:} $\stkout{\left\langle \stkout{r_{123}}\right\rangle\left\langle r^{123}\right\rangle\left\langle r_{123}^{123}\right\rangle}$ \end{itemize} diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp index d93c50aebe..be4ab15994 100644 --- a/examples/jkqtmathtext_test/testform.cpp +++ b/examples/jkqtmathtext_test/testform.cpp @@ -110,11 +110,17 @@ TestForm::TestForm(QWidget *parent) : ui->cmbTestset->addItem("text/math: brace2 test", "text: \\langle\\langle r^{123}\\rangle\\rangle -- math: $\\langle\\langle r^{123}\\rangle\\rangle$"); ui->cmbTestset->addItem("text/math: brace3 test", "text: \\left\\langle r^{123}\\right\\rangle -- math: $\\left\\langle r^{123}\\right\\rangle$"); ui->cmbTestset->addItem("text/math: brace4 test", "text: \\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle -- math: $\\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle$"); - ui->cmbTestset->addItem("text/math: brace5 test: ( )", "text: \\left(\\left(\\left( r^{123}\\right)\\right)\\right) -- math: $\\left(\\left(\\left( r^{123}\\right)\\right)\\right)$"); - ui->cmbTestset->addItem("text/math: brace6 test: [ ]", "text: \\left[\\left[\\left[ r^{123}\\right]\\right]\\right] -- math: $\\left[\\left[\\left[ r^{123}\\right]\\right]\\right]$"); - ui->cmbTestset->addItem("text/math: brace7 test: { }", "text: \\left\\{\\left\\{\\left\\{ r^{123}\\right\\}\\right\\}\\right\\} -- math: $\\left\\{\\left\\{\\left\\{ r^{123}\\right\\}\\right\\}\\right\\}$"); - ui->cmbTestset->addItem("text/math: brace8 test: || ||", "text: \\left\\|\\left\\|\\left\\| r^{123}\\right\\|\\right\\|\\right\\| -- math: $\\left\\|\\left\\|\\left\\| r^{123}\\right\\|\\right\\|\\right\\|$"); - ui->cmbTestset->addItem("text/math: brace9 test: | |", "text: \\left|\\left|\\left| r^{123}\\right|\\right|\\right| -- math: $\\left|\\left|\\left| r^{123}\\right|\\right|\\right|$"); + auto fAddBraceTest=[](const QString& open, const QString& close) { + QString res= "\\left"+open+"\\left"+open+"\\left"+open+" r^{123}\\right"+close+"\\right"+close+"\\right"+close; + res += "\\left"+open+"\\left"+open+"\\left"+open+" r_{123}\\right"+close+"\\right"+close+"\\right"+close; + res += "\\left"+open+"\\left"+open+"\\left"+open+" r_{123}^{123}\\right"+close+"\\right"+close+"\\right"+close; + return res; + }; + ui->cmbTestset->addItem("text/math: brace5 test: ( )", "text: "+fAddBraceTest("(",")")+" -- math: $"+fAddBraceTest("(",")")+"$"); + ui->cmbTestset->addItem("text/math: brace6 test: [ ]", "text: "+fAddBraceTest("[","]")+" -- math: $"+fAddBraceTest("[","]")+"$"); + ui->cmbTestset->addItem("text/math: brace7 test: { }", "text: "+fAddBraceTest("\\{","\\}")+" -- math: $"+fAddBraceTest("\\{","\\}")+"$"); + ui->cmbTestset->addItem("text/math: brace8 test: || ||", "text: "+fAddBraceTest("\\|","\\|")+" -- math: $"+fAddBraceTest("\\|","\\|")+"$"); + ui->cmbTestset->addItem("text/math: brace9 test: | |", "text: "+fAddBraceTest("|","|")+" -- math: $"+fAddBraceTest("|","|")+"$"); ui->cmbTestset->addItem("text/math: brace10 test", "text: \\left\\{\\left[\\left( r^{123}\\right)\\right]\\right\\} -- math: $\\left\\{\\left[\\left( r^{123}\\right)\\right]\\right\\}$"); ui->cmbTestset->addItem("text/math: brace11 test: floor", "text: \\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor -- math: $\\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor$"); ui->cmbTestset->addItem("text/math: brace12 test: ceil", "text: \\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil -- math: $\\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil$"); @@ -349,7 +355,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p name=QString("MTsqrtNode: deg=%1").arg(sqrtN->getDegree()); if (sqrtN->getChild()) ti->addChild(createTree(sqrtN->getChild(), ti)); } else if (braceN) { - name=QString("MTbraceNode: l='%1', r='%2', showR=%3").arg(braceN->getOpenbrace()).arg(braceN->getClosebrace()).arg(braceN->getShowRightBrace()); + name=QString("MTbraceNode: l[showL=%3]='%1', r[showR=%4]='%2'").arg(braceN->getOpenbrace()).arg(braceN->getClosebrace()).arg(braceN->getShowOpeningBrace()).arg(braceN->getShowClosingBrace()); if (braceN->getChild()) ti->addChild(createTree(braceN->getChild(), ti)); } else if (superN) { name=QString("MTsuperscriptNode"); diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp index bf9373afd4..d284ecaeb6 100644 --- a/lib/jkqtmathtext/jkqtmathtext.cpp +++ b/lib/jkqtmathtext/jkqtmathtext.cpp @@ -81,6 +81,9 @@ JKQTMathText::JKQTMathText(QObject* parent): expensiveRendering=true; blackboardSimulated=true; + showLeftBrace=true; + showRightBrace=true; + static QString serifFont="serif"; static QString sansFont="sans"; @@ -1157,6 +1160,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn if (currentTokenName.size()>0) { if (QString(currentTokenName[0])==quitOnClosingBrace || quitOnClosingBrace=="any" || QString(currentTokenName[0])==".") { //std::cout<<"found \\right '"<" && (currentTokenName=="rangle" || QString(currentTokenName[0])==".")) { + showLeftBrace=true; showRightBrace=(QString(currentTokenName[0])!="."); currentTokenName=currentTokenName.right(currentTokenName.size()-1); break; } else if (quitOnClosingBrace=="any") { + showLeftBrace=true; showRightBrace=(QString(currentTokenName[0])!="."); //currentTokenName=currentTokenName.right(currentTokenName.size()-1); break; @@ -1199,51 +1209,52 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn if (currentTokenName.size()>0) { if (currentTokenName[0]=='(') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); // we already used the first character from the text token! - nl->addNode(new JKQTMathTextBraceNode(this, "(", ")", parseLatexString(currentTokenName.size()<=0, ")"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "(", ")", parseLatexString(currentTokenName.size()<=0, ")"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='[') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "[", "]", parseLatexString(currentTokenName.size()<=0, "]"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "[", "]", parseLatexString(currentTokenName.size()<=0, "]"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='{') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='<') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "<", ">", parseLatexString(currentTokenName.size()<=0, ">"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "<", ">", parseLatexString(currentTokenName.size()<=0, ">"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='|') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "|", "|", parseLatexString(currentTokenName.size()<=0, "|"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "|", "|", parseLatexString(currentTokenName.size()<=0, "|"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='~') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "~", "~", parseLatexString(currentTokenName.size()<=0, "~"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "~", "~", parseLatexString(currentTokenName.size()<=0, "~"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='_') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "_", "_", parseLatexString(currentTokenName.size()<=0, "_"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "_", "_", parseLatexString(currentTokenName.size()<=0, "_"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='#') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showLeftBrace, showRightBrace)); } else if (currentTokenName[0]=='.') { + showLeftBrace=false; currentTokenName=currentTokenName.right(currentTokenName.size()-1); JKQTMathTextNode* cn=parseLatexString(currentTokenName.size()<=0, "any"); - nl->addNode(new JKQTMathTextBraceNode(this, ".", currentTokenName, cn, showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, ".", currentTokenName, cn, showLeftBrace, showRightBrace)); } else { getNew=false; } } } else if (currentToken==MTTinstruction && currentTokenName=="langle") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "<", ">", parseLatexString(true, ">"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "<", ">", parseLatexString(true, ">"), showLeftBrace, showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="{") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showLeftBrace, showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="lfloor") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "_", "_", parseLatexString(true, "_"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "_", "_", parseLatexString(true, "_"), showLeftBrace, showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="lceil") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "~", "~", parseLatexString(true, "~"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "~", "~", parseLatexString(true, "~"), showLeftBrace, showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="|") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new JKQTMathTextBraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showLeftBrace, showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName==quitOnClosingBrace) { break; } diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h index dc4975aa14..3aa934cc35 100644 --- a/lib/jkqtmathtext/jkqtmathtext.h +++ b/lib/jkqtmathtext/jkqtmathtext.h @@ -575,6 +575,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { QStringList error_list; /** \brief used by the parser. This is used to implement brace pairs with \\right. */ bool showRightBrace; + /** \brief used by the parser. This is used to implement brace pairs with \\left. */ + bool showLeftBrace; /** \brief the result of parsing the last string supplied to the object via parse() */ JKQTMathTextNode* parsedNode; diff --git a/lib/jkqtmathtext/jkqtmathtexttools.h b/lib/jkqtmathtext/jkqtmathtexttools.h index 875915dda4..5c66771e2b 100644 --- a/lib/jkqtmathtext/jkqtmathtexttools.h +++ b/lib/jkqtmathtext/jkqtmathtexttools.h @@ -290,18 +290,24 @@ JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextDecorationToString(JKQTMathTextDecor /** \brief create a QPainterPath for drawing horizontal braces * \ingroup jkqtmathtext + * + * \image html mathparser/JKQTMathTextMakeHBracePath.png */ JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double cubicshrink=0.5, double cubiccontrolfac=0.3); /** \brief create a QPainterPath for drawing horizontal arrows * \ingroup jkqtmathtext + * + * \image html mathparser/JKQTMathTextMakeArrow.png */ JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true); /** \brief create a QPainterPath for drawing horizontal double arrows * \ingroup jkqtmathtext + * + * \image html mathparser/JKQTMathTextMakeDArrow.png */ JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeDArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true); @@ -317,6 +323,7 @@ struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRData { bool operator==(const JKQTMathTextTBRData& other) const; }; + struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRDataH { explicit JKQTMathTextTBRDataH(const QFont& f, const QString& text, QPaintDevice *pd); QString text; diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp index de155962dd..73b4f3e56c 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp @@ -36,34 +36,53 @@ -JKQTMathTextBraceNode::JKQTMathTextBraceNode(JKQTMathText* _parent, const QString& openbrace, const QString& closebrace, JKQTMathTextNode* child, bool showRightBrace): +JKQTMathTextBraceNode::JKQTMathTextBraceNode(JKQTMathText* _parent, const QString& openbrace, const QString& closebrace, JKQTMathTextNode* child, bool showOpeningBrace, bool showClosingBrace): JKQTMathTextSingleChildNode(child, _parent) { this->openbrace=openbrace; this->closebrace=closebrace; - this->showRightBrace=showRightBrace; + this->showClosingBrace=showClosingBrace; + this->showOpeningBrace=showOpeningBrace; } JKQTMathTextBraceNode::~JKQTMathTextBraceNode() { } -void JKQTMathTextBraceNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { +void JKQTMathTextBraceNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) { + double braceWidth=0, braceHeight=0; + getSizeInternalAndBrace(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos, braceWidth, braceHeight, prevNodeSize); +} + +void JKQTMathTextBraceNode::getSizeInternalAndBrace(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, double &bracewidth, double &braceheight, const JKQTMathTextNodeSize */*prevNodeSize*/) +{ const JKQTMathTextEnvironment ev=currentEv; child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - double bracewidth=0, braceheight=0; - getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight); + const double cAscentAboveStrike=baselineHeight-strikeoutPos; + const double cDescentBelowStrike=overallHeight-baselineHeight+strikeoutPos; + + //qDebug()<<"getSizeInternalAndBrace(): showOpeningBrace="<0) painter.drawLine(l); - } else if (openbrace=="#" || openbrace=="||") { - const double y1=y+(cOverallHeight-cBaselineHeight); - const 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; - const double y1=y+(cOverallHeight-cBaselineHeight); - const 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); - painter.drawPath(path); + } else if (openbrace=="_") { + QPainterPath path; + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace2s, y1); + path.lineTo(xbrace1, y1); + path.lineTo(xbrace1, y2); + painter.drawPath(path); + } else if (openbrace=="~") { + QPainterPath path; + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace1, y1); + path.lineTo(xbrace1, y2); + path.lineTo(xbrace2s, y2); + painter.drawPath(path); + } else if (openbrace=="|") { + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + const QLineF l(xbrace1, y1, xbrace1, y2); + if (l.length()>0) painter.drawLine(l); + } else if (openbrace=="#" || openbrace=="||") { + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + const QLineF l(xbrace1, y1, xbrace1, y2); + if (l.length()>0) painter.drawLine(l); + const QLineF l2(xbrace1+1.5*lw, y1, xbrace1+1.5*lw, y2); + if (l2.length()>0) painter.drawLine(l2); + } else if (openbrace=="<") { + QPainterPath path; + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace2, y1); + path.lineTo(xbrace1, (y2+y1)/2.0); + path.lineTo(xbrace2, y2); + painter.drawPath(path); + } + xnew=xnew+bracewidth; } painter.setPen(pold); - xnew= child->draw(painter, xnew+bracewidth/parentMathText->getBraceShrinkFactor()-lw, y, currentEv)+lw; + xnew= child->draw(painter, xnew, y, currentEv); - if (showRightBrace) { + if (showClosingBrace) { + const double xbrace1=qMax(xnew+bracewidth-paren_fraction*bracewidth, xnew+lw/2.0); + const double xbrace1s=qMax(xnew+bracewidth-brace_fraction*bracewidth, xnew+lw/2.0); + const double xbrace2=xnew+bracewidth-lw; painter.setPen(p); if (closebrace==")") { QPainterPath path; - const double y1=y+(cOverallHeight-cBaselineHeight); - const 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); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace1, y1); + path.cubicTo(xbrace2, (y1+y2)/2.0+fabs(y1-y2)/6.0, xbrace2, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xbrace1, y2); painter.drawPath(path); } else if (closebrace=="]") { QPainterPath path; - const double y1=y+(cOverallHeight-cBaselineHeight); - const 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); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace1s, y1); + path.lineTo(xbrace2, y1); + path.lineTo(xbrace2, y2); + path.lineTo(xbrace1s, y2); painter.drawPath(path); } else if (closebrace=="}") { - QPainterPath path=JKQTMathTextMakeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction); + QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(xnew+bracewidth*brace_fraction, y-cBaselineHeight+cOverallHeight/2.0); + painter.translate((xbrace1+xbrace2)/2.0, y-nodeBaselineHeight+nodeOverallHeight/2.0); painter.rotate(270); painter.drawPath(path); } else if (closebrace=="_") { QPainterPath path; - const double y1=y+(cOverallHeight-cBaselineHeight); - const double y2=y-cBaselineHeight; - path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); - path.lineTo(xnew+bracewidth, y1); - path.lineTo(xnew+bracewidth, y2); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace1s, y1); + path.lineTo(xbrace2, y1); + path.lineTo(xbrace2, y2); painter.drawPath(path); } else if (closebrace=="~") { QPainterPath path; - const double y1=y+(cOverallHeight-cBaselineHeight); - const double y2=y-cBaselineHeight; - path.moveTo(xnew+bracewidth, y1); - path.lineTo(xnew+bracewidth, y2); - path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace2, y1); + path.lineTo(xbrace2, y2); + path.lineTo(xbrace1s, y2); painter.drawPath(path); } else if (closebrace=="|") { - const double y1=y+(cOverallHeight-cBaselineHeight); - const double y2=y-cBaselineHeight; - QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + const QLineF l(xbrace2, y1, xbrace2, y2); if (l.length()>0) painter.drawLine(l); } else if (closebrace=="#" || closebrace=="||") { - const double y1=y+(cOverallHeight-cBaselineHeight); - const 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); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + const QLineF l(xbrace2, y1, xbrace2, y2); if (l.length()>0) painter.drawLine(l); + const QLineF l2(xbrace2-1.5*lw, y1, xbrace2-1.5*lw, y2); + if (l2.length()>0) painter.drawLine(l2); } else if (closebrace==">") { QPainterPath path; - const double y1=y+(cOverallHeight-cBaselineHeight); - const 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); + const double y1=y+(nodeOverallHeight-nodeBaselineHeight); + const double y2=y-nodeBaselineHeight; + path.moveTo(xbrace1, y1); + path.lineTo(xbrace2, (y2+y1)/2.0); + path.lineTo(xbrace1, y2); painter.drawPath(path); } painter.setPen(pold); + xnew=xnew+bracewidth; } //qDebug()<<" ==> "<getBraceShrinkFactor()-lw; + return xnew; } bool JKQTMathTextBraceNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { @@ -265,28 +287,18 @@ QString JKQTMathTextBraceNode::getClosebrace() const { return this->closebrace; } -bool JKQTMathTextBraceNode::getShowRightBrace() const { - return this->showRightBrace; +bool JKQTMathTextBraceNode::getShowClosingBrace() const { + return this->showClosingBrace; } -void JKQTMathTextBraceNode::getBraceWidth(QPainter &/*painter*/, JKQTMathTextEnvironment ev, double /*baselineHeight*/, double overallHeight, double &bracewidth, double &braceheight) const +bool JKQTMathTextBraceNode::getShowOpeningBrace() const { - /*QFont evf=ev.getFont(parent); - if (ev.insideMath) evf.setItalic(false); - ev.italic=false; - while (ev.fontSize<10*parent->getFontSize()) { - const QFontMetricsF fme(evf, painter.device()); - if (fme.ascent()>overallHeight) break; - ev.fontSize+=0.5; - evf.setPointSizeF(ev.fontSize); - } - ev.fontSize=ev.fontSize*parent->getBraceFactor(); - evf.setPointSizeF(ev.fontSize); - QFontMetricsF fm(evf, painter.device()); - QString bc="_X"; - bracewidth=fm.width("I")*parent->getBraceShrinkFactor(); - braceheight=parent->getTBR(evf, bc, painter.device()).height();*/ - double lw=qMax(0.25,ceil(ev.fontSize/12.0)); + return showOpeningBrace; +} + +void JKQTMathTextBraceNode::getBraceSize(QPainter &/*painter*/, JKQTMathTextEnvironment ev, double /*baselineHeight*/, double overallHeight, double &bracewidth, double &braceheight) const +{ + const double lw=qMax(0.25,ceil(ev.fontSize/12.0)); braceheight=overallHeight*parentMathText->getBraceFactor(); bracewidth=0.6*pow(braceheight, 0.6); if (openbrace=="{" || closebrace=="}") bracewidth=qMax(bracewidth, lw*3.5); diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h index a311a422ea..5b98b542b2 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h +++ b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h @@ -34,10 +34,12 @@ class JKQTMathText; // forward /** \brief subclass representing a brace node * \ingroup jkqtmathtext_items + * + * \image html jkqtmathtext_bracenode_geo.png */ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextSingleChildNode { public: - JKQTMathTextBraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, JKQTMathTextNode* child, bool showRightBrace=true); + JKQTMathTextBraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, JKQTMathTextNode* child, bool showOpeningBrace=true, bool showClosingBrace=true); virtual ~JKQTMathTextBraceNode() override; /** \copydoc JKQTMathTextNode::draw() */ virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; @@ -49,19 +51,28 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextSingleCh QString getOpenbrace() const; /** \copydoc closebrace */ QString getClosebrace() const; - /** \copydoc showRightBrace */ - bool getShowRightBrace() const; + /** \copydoc showRightBrace */ + bool getShowClosingBrace() const; + /** \copydoc showOpeningBrace */ + bool getShowOpeningBrace() const; protected: - /** \copydoc JKQTMathTextNode::getSizeInternal() */ + /** \copydoc JKQTMathTextNode::getSizeInternal() + * + * \note This function internally calls getSizeInternalAndBrace() and returns part of its results. + */ virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** calculates the size of this node (also returned by getSizeInternal() ) and of the brace */ + void getSizeInternalAndBrace(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, double& bracewidth, double&braceheight, const JKQTMathTextNodeSize* prevNodeSize=nullptr); /**\brief opening brace */ QString openbrace; /**\brief closing brace */ QString closebrace; - /**\brief if \c true, the right-hand-side brace is drawn */ - bool showRightBrace; + /**\brief if \c true, the closing (right hand side) brace is drawn */ + bool showClosingBrace; + /**\brief if \c true, the opening (left hand side) brace is drawn */ + bool showOpeningBrace; /** \brief calculate the width of the brace */ - void getBraceWidth(QPainter& painter, JKQTMathTextEnvironment currentEv, double baselineHeight, double overallHeight, double& bracewidth, double& braceheight) const; + void getBraceSize(QPainter& painter, JKQTMathTextEnvironment currentEv, double baselineHeight, double overallHeight, double& bracewidth, double& braceheight) const; }; #endif // JKQTMATHTEXTBRACENODE_H diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp index db2a3702f8..9533568fc4 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp @@ -84,20 +84,14 @@ void JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos2); - const double maxHeight=qMax(overallHeight1,overallHeight2); - const bool _isBraceParentNearerThanFrac=isBraceParentNearerThanFrac(); - const double height1OrMaxHeight=(_isBraceParentNearerThanFrac)?maxHeight:overallHeight1; - const double height2OrMaxHeight=(_isBraceParentNearerThanFrac)?maxHeight:overallHeight2; overallHeight=0; baselineHeight=0; width=0; if (mode==MTFMfrac || mode==MTFMdfrac || mode==MTFMtfrac || mode==MTFMstackrel) { const double top_ascent=line_ascent+xheight*parentMathText->getFracShiftFactor(); const double bot_ascent=line_ascent-xheight*parentMathText->getFracShiftFactor(); - // here we use maxHeight (as LaTeX does) so braces are centered around the xHieght!!! - // if there are no braces, we can use the actual height - const double newascent=height1OrMaxHeight+top_ascent; - const double newdescent=height2OrMaxHeight-bot_ascent; + const double newascent=overallHeight1+top_ascent; + const double newdescent=overallHeight2-bot_ascent; width=qMax(width1, width2); if (mode!=MTFMstackrel) width+=xwidth/2.0; strikeoutPos=line_ascent; @@ -107,10 +101,8 @@ void JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro } else if (mode==MTFMstfrac || mode==MTFMsfrac) { const double top_ascent=line_ascent; - // here we use maxHeight (as LaTeX does) so braces are centered around the xHieght!!! - // if there are no braces, we can use the actual height - const double newascent=height1OrMaxHeight+top_ascent; - const double newdescent=qMax(height2OrMaxHeight-baselineHeight2, qheight-xheight); + const double newascent=overallHeight1+top_ascent; + const double newdescent=qMax(overallHeight2-baselineHeight2, qheight-xheight); width=width1+width2+xwidth/2.0; strikeoutPos=line_ascent; @@ -158,19 +150,6 @@ double JKQTMathTextFracNode::getFracScalingFactor() const return parentMathText->getFracFactor(); } -bool JKQTMathTextFracNode::isBraceParentNearerThanFrac() const -{ - auto parents=getParents(); - for (const auto& p: parents) { - if (p!=nullptr) { - if (dynamic_cast(p)!=nullptr) return true; - if (dynamic_cast(p)!=nullptr) return false; - } - } - return false; - -} - double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { doDrawBoxes(painter, x, y, currentEv); const QFont f=currentEv.getFont(parentMathText); diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h index d54c09c7c3..ffefd1716c 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h +++ b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h @@ -62,8 +62,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFracNode: public JKQTMathTextDualChild int getNestingLevel(bool sameType=false) const; /** \brief determines the scaling factor of the fraction (takes into account the nesting level) */ double getFracScalingFactor() const; - /** \brief determines whether in the list of parents a brace-node or another frac-node appears first */ - bool isBraceParentNearerThanFrac() const; }; diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp index 026baec732..be3e702e6c 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp @@ -98,7 +98,12 @@ void JKQTMathTextNode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMa p.setColor("lightblue"); painter.setPen(p); if (w>0) painter.drawLine(QLineF(x, y, x+w, y)); + p.setColor("pink"); + p.setStyle(Qt::DashLine); + painter.setPen(p); + if (w>0) painter.drawLine(QLineF(x, y-sp, x+w, y-sp)); p.setColor("green"); + p.setStyle(Qt::SolidLine); painter.setPen(p); painter.drawEllipse(QRectF(x-3.0,y-3.0,6.0,6.0)); p.setColor("lightgreen"); diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp index 2a134d2b6b..b01505ea40 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp @@ -48,18 +48,19 @@ JKQTMathTextSuperscriptNode::~JKQTMathTextSuperscriptNode() { void JKQTMathTextSuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) { JKQTMathTextEnvironment ev=currentEv; ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor(); - QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); - QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); + const QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); + double cstrikeoutPos=0; + child->getSize(painter, ev, width, baselineHeight, overallHeight, cstrikeoutPos); double shift=parentMathText->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 (prevNodeSize!=nullptr) strikeoutPos=prevNodeSize->strikeoutPos; + else strikeoutPos=fm.strikeOutPos(); if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor(); } @@ -130,9 +131,9 @@ void JKQTMathTextSubscriptNode::getSizeInternal(QPainter& painter, JKQTMathTextE shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); } - double yshift=baselineHeight-shift; baselineHeight=shift; - strikeoutPos=fm.strikeOutPos()+yshift; + if (prevNodeSize!=nullptr) strikeoutPos=prevNodeSize->strikeoutPos; + else strikeoutPos=fm.strikeOutPos(); if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor(); } diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp index d2e4fd3aac..bc4c1d22a5 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp @@ -1007,43 +1007,41 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM } else if (symbolName==",") { // 25% space } else if (symbolName=="!") { // -25% space } else if (symbolName=="longleftarrow") { - double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); - painter.drawPath(path); + const double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + const double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + const double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + const QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); } else if (symbolName=="longrightarrow"){ - double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); + const double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + const double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + const double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + const QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); painter.drawPath(path); } else if (symbolName=="Longleftarrow") { - double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); - painter.drawPath(path); + const double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + const double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + const double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + const QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); } else if (symbolName=="Longrightarrow") { - double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); + const double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + const double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + const double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + const QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); painter.drawPath(path); } else if (symbolName=="longleftrightarrow") { - double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); + const double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + const double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + const double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + const QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); painter.drawPath(path); } else if (symbolName=="Longleftrightarrow") { - double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); + const double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + const double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + const double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + const QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); painter.drawPath(path); } else { // draw a box to indicate an unavailable symbol - QRectF tbr=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()); + const QRectF tbr=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()); painter.drawRect(QRectF(x+shift,y-tbr.height(), xwi, tbr.height()*0.8)); } painter.setPen(pold);