mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
MODIFIED: brace node now calculates the extension of the child height above or below the strikeoutPos, in order to center braces around the strikeoutPos
fixed: strikeoutPos was not correctly calculated in sub-/superscript node NEW: JKQTMathText shows strikeoutPos when drawing Debug-Boxes
This commit is contained in:
parent
143ae54ae8
commit
992cad7ff3
@ -41,7 +41,7 @@ This page lists several todos and wishes for future version of JKQTPlotter
|
||||
<li>add instruction for unicode-characters \char"XXXX, \unicode{XXXX}, \utf8{XXXX}, \utf16{XXXX}, \utf32{XXXX} ...</li>
|
||||
<li>check sub/superscript with italic text in math mode, possibly a correction is necessary</li>
|
||||
<li>explore where QFontMetricsF::horizontalAdvance() can be used (for Qt >=5.15)</li>
|
||||
<li>correction of frac-height (2*maxHeight or height1+height2) should be done by brace-node, not frac-node</li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul></li>
|
||||
|
@ -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:
|
||||
<ul>
|
||||
<li>JKQtPlotter:<ul>
|
||||
<li>fixed issue described in <a href="https://github.com/jkriege2/JKQtPlotter/pull/62">#62: Fix custom labels draw, because giving exactly two label-strings did not display all of them</a>, thanks to <a href="https://github.com/FalsinSoft">user:FalsinSoft</a></li>
|
||||
<li>fixed issue <a href="https://github.com/jkriege2/JKQtPlotter/pull/70">#70: Typo in jkqtplotter/CMakeLists.txt</a>, thanks to <a href="https://github.com/tedlinlab">user:tedlinlab</a></li>
|
||||
<li>fixed: styling was not properly applied to coordinate axes of colorbars outside the plot</li>
|
||||
<li>improved: QT6-compatibility by removing deprecated warnings</li>
|
||||
<li>FIXED issue described in <a href="https://github.com/jkriege2/JKQtPlotter/pull/62">#62: Fix custom labels draw, because giving exactly two label-strings did not display all of them</a>, thanks to <a href="https://github.com/FalsinSoft">user:FalsinSoft</a></li>
|
||||
<li>FIXED issue <a href="https://github.com/jkriege2/JKQtPlotter/pull/70">#70: Typo in jkqtplotter/CMakeLists.txt</a>, thanks to <a href="https://github.com/tedlinlab">user:tedlinlab</a></li>
|
||||
<li>FIXED: styling was not properly applied to coordinate axes of colorbars outside the plot</li>
|
||||
<li>IMPROVED: QT6-compatibility by removing deprecated warnings</li>
|
||||
<li>NEW: JKQTPFilledCurveXGraph and JKQTPFilledCurveYGraph can now plot wiggle plots with different fill styles above and below the baseline (feature request <a href="https://github.com/jkriege2/JKQtPlotter/issues/68">#68 Wiggle Plots</a> from <a href="https://github.com/xichaoqiang">user:xichaoqiang</a> </li>
|
||||
<li>NEW/BREAKING CHANGE: data tooltip can now also be shown when "just" moving the mouse (so far this was only possible when dragging the mouse with a button pressed). This also removes JKQtPlotter::getActMouseLeftAsToolTip() and adds JKQtPlotter::getActMouseMoveToolTip() instead! Also the default toolbars and context menus changed!</li>
|
||||
<li>NEW: new "seaborn" style for plots</li>
|
||||
@ -27,15 +27,18 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
</ul>
|
||||
|
||||
<li>JKQTMathText:<ul>
|
||||
<li>fixed: JKQTMathText added a little whitespace before and after the LaTeX-string. This was removed as it disturbed the layout of text in plots</li>
|
||||
<li>fixed: height-calculation of frac-like instructions: before the ascent and descent were equal, even if the numerator and denominator have different hieghts</li>
|
||||
<li>fixes/improvements: JKQTMathText renders several LaTeX strings better (simple braces in math mode, +-*... as symbols with proper sizes in math mode, added some missing instruction aliases, improved size of \vec and \hat, corrrected fonts usage for mathrm</li>
|
||||
<li>improved: high-dpr-support in JKQTMathText</li>
|
||||
<li>FIXED: JKQTMathText added a little whitespace before and after the LaTeX-string. This was removed as it disturbed the layout of text in plots</li>
|
||||
<li>FIXED: height-calculation of frac-like instructions: before the ascent and descent were equal, even if the numerator and denominator have different heights</li>
|
||||
<li>FIXED: strikeoutPos was not correctly calculated in sub-/superscript node</li>
|
||||
<li>FIXED/IMPROVED: JKQTMathText renders several LaTeX strings better (simple braces in math mode, +-*... as symbols with proper sizes in math mode, added some missing instruction aliases, improved size of \vec and \hat, corrrected fonts usage for mathrm</li>
|
||||
<li>IMPROVED: high-dpr-support in JKQTMathText</li>
|
||||
<li>MODIFIED: brace node now calculates the extension of the child height above or below the strikeoutPos, in order to center braces around the strikeoutPos</li>
|
||||
<li>NEW: now supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve</li>
|
||||
<li>NEW: reworked drawing of decorations: improved appearance and positioning!</li>
|
||||
<li>NEW: reworked code structure: broke up large, single CPP-files into several smaller files!</li>
|
||||
<li>NEW: reworked node class tree: inserted base-class nodes for single-child, dual-child!</li>
|
||||
<li>NEW: improved frac-rendering: font-scaling takes nesting-level into account, overall-rendering, sizes, if a brace surrounds a frac, the heights are equal above and below to center the brace , ...</li>
|
||||
<li>NEW: shows strikeoutPos when drawing Debug-Boxes</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
BIN
doc/images/jkqtmathtext_bracenode_geo.cdr
Normal file
BIN
doc/images/jkqtmathtext_bracenode_geo.cdr
Normal file
Binary file not shown.
BIN
doc/images/jkqtmathtext_bracenode_geo.png
Normal file
BIN
doc/images/jkqtmathtext_bracenode_geo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
BIN
doc/images/mathparser/JKQTMathTextMakeArrow.png
Normal file
BIN
doc/images/mathparser/JKQTMathTextMakeArrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
BIN
doc/images/mathparser/JKQTMathTextMakeDArrow.png
Normal file
BIN
doc/images/mathparser/JKQTMathTextMakeDArrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
doc/images/mathparser/JKQTMathTextMakeHBracePath.png
Normal file
BIN
doc/images/mathparser/JKQTMathTextMakeHBracePath.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
@ -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}
|
||||
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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.toStdString()<<"'\n";
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
//if (!showRightBrace) std::cout<<"don't show right brace '"<<quitOnClosingBrace.toStdString()<<"' !!!\n";
|
||||
if (quitOnClosingBrace!="any") currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
@ -1167,26 +1171,32 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
}
|
||||
} else if (currentToken==MTTinstruction) {
|
||||
if (quitOnClosingBrace=="~" && (currentTokenName=="rceil" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="}" && (currentTokenName=="}" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="_" && (currentTokenName=="rfloor" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="#" && (currentTokenName=="|" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace==">" && (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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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="<<showOpeningBrace<<", openbrace="<<openbrace<<", showClosingBrace="<<showClosingBrace<<", closebrace="<<closebrace;
|
||||
//qDebug()<<"getSizeInternalAndBrace(): child: baselineHeight="<<baselineHeight<<", strikeoutPos="<<strikeoutPos<<", overallHeight="<<overallHeight;
|
||||
//qDebug()<<"getSizeInternalAndBrace(): child: cAscentAboveStrike="<<cAscentAboveStrike<<", cDescentBelowStrike="<<cDescentBelowStrike;
|
||||
|
||||
const double heightAboveBelowStrike=qMax(cAscentAboveStrike, cDescentBelowStrike);
|
||||
|
||||
|
||||
baselineHeight=strikeoutPos+heightAboveBelowStrike*parentMathText->getBraceFactor();
|
||||
overallHeight=2.0*heightAboveBelowStrike*parentMathText->getBraceFactor(); //fm.height();
|
||||
|
||||
//qDebug()<<"getSizeInternalAndBrace(): heightAboveBelowStrike="<<heightAboveBelowStrike<<", baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight;
|
||||
|
||||
bracewidth=0;
|
||||
braceheight=0;
|
||||
getBraceSize(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight);
|
||||
|
||||
bracewidth=bracewidth/parentMathText->getBraceShrinkFactor();
|
||||
|
||||
baselineHeight=/*qMin(baselineHeight, braceheight)*/ baselineHeight*parentMathText->getBraceFactor();
|
||||
overallHeight=qMax(overallHeight, braceheight)*parentMathText->getBraceFactor(); //fm.height();
|
||||
|
||||
width=width+bracewidth*2.0;
|
||||
|
||||
|
||||
if (showOpeningBrace) width+=bracewidth;
|
||||
if (showClosingBrace) width+=bracewidth;
|
||||
}
|
||||
|
||||
double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
@ -71,163 +90,166 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
doDrawBoxes(painter, x, y, currentEv);
|
||||
JKQTMathTextEnvironment ev=currentEv;
|
||||
|
||||
double width=0;
|
||||
double baselineHeight=0;
|
||||
double overallHeight=0, strikeoutPos=0;
|
||||
|
||||
child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos);
|
||||
|
||||
double nodeWidth=0;
|
||||
double nodeBaselineHeight=0;
|
||||
double nodeOverallHeight=0, nodeStrikeoutPos=0;
|
||||
double bracewidth=0, braceheight=0;
|
||||
getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight);
|
||||
getSizeInternalAndBrace(painter, currentEv, nodeWidth, nodeBaselineHeight, nodeOverallHeight, nodeStrikeoutPos, bracewidth, braceheight);
|
||||
|
||||
double cWidth=0;
|
||||
double cBaselineHeight=0;
|
||||
double cOverallHeight=0, cstrikeoutPos=0;
|
||||
|
||||
getSize(painter, currentEv, cWidth, cBaselineHeight, cOverallHeight, cstrikeoutPos);
|
||||
|
||||
const double lw=qMax(0.25,ceil(currentEv.fontSize/16.0));//fm.lineWidth();
|
||||
|
||||
double xnew=x+lw;
|
||||
double xnew=x;
|
||||
|
||||
const QPen pold=painter.pen();
|
||||
QPen p=pold;
|
||||
p.setWidthF(lw);
|
||||
p.setColor(currentEv.color);
|
||||
painter.setPen(p);
|
||||
double brace_fraction=0.85;
|
||||
if (openbrace=="(") {
|
||||
QPainterPath path;
|
||||
const double y1=y+(cOverallHeight-cBaselineHeight);
|
||||
const double y2=y-cBaselineHeight;
|
||||
path.moveTo(xnew+brace_fraction*bracewidth, y1);
|
||||
path.cubicTo(xnew, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+brace_fraction*bracewidth, y2);
|
||||
painter.drawPath(path);
|
||||
} 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+lw/2.0, y1);
|
||||
path.lineTo(xnew+lw/2.0, y2);
|
||||
path.lineTo(xnew+brace_fraction*bracewidth, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace=="{") {
|
||||
QPainterPath path=JKQTMathTextMakeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction);
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.translate(xnew+bracewidth*(1.0-brace_fraction), y-cBaselineHeight+cOverallHeight/2.0);
|
||||
painter.rotate(90);
|
||||
painter.drawPath(path);
|
||||
const double paren_fraction=0.85;
|
||||
const double brace_fraction=0.65;
|
||||
if (showOpeningBrace) {
|
||||
const double xbrace1=xnew+lw;
|
||||
const double xbrace2=qMin(xnew+paren_fraction*bracewidth, xnew+bracewidth-lw/2.0);
|
||||
const double xbrace2s=qMin(xnew+brace_fraction*bracewidth, xnew+bracewidth-lw/2.0);
|
||||
if (openbrace=="(") {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
path.moveTo(xbrace2, y1);
|
||||
path.cubicTo(xbrace1, (y1+y2)/2.0+fabs(y1-y2)/6.0, xbrace1, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xbrace2, 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);
|
||||
path.lineTo(xbrace2s, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace=="{") {
|
||||
QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction);
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.translate((xbrace1+xbrace2)/2.0, y-nodeBaselineHeight+nodeOverallHeight/2.0);
|
||||
painter.rotate(90);
|
||||
painter.drawPath(path);
|
||||
|
||||
} 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, y1);
|
||||
path.lineTo(xnew, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace=="~") {
|
||||
QPainterPath path;
|
||||
const double y1=y+(cOverallHeight-cBaselineHeight);
|
||||
const double y2=y-cBaselineHeight;
|
||||
path.moveTo(xnew, y1);
|
||||
path.lineTo(xnew, y2);
|
||||
path.lineTo(xnew+brace_fraction*bracewidth, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (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);
|
||||
} 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()<<" ==> "<<bc<<fm.boundingRect(bc).width();
|
||||
return xnew+bracewidth/parentMathText->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);
|
||||
|
@ -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
|
||||
|
@ -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<JKQTMathTextNode>();
|
||||
for (const auto& p: parents) {
|
||||
if (p!=nullptr) {
|
||||
if (dynamic_cast<const JKQTMathTextBraceNode*>(p)!=nullptr) return true;
|
||||
if (dynamic_cast<const JKQTMathTextFracNode*>(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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user