JKQTMathText: REWORKED rendering of text in text- and math-mode. Now it is more consistent with the output of LaTeX itself

This commit is contained in:
jkriege2 2022-08-02 12:16:10 +02:00
parent 79c5b26642
commit 0b1af2e8f9
9 changed files with 175 additions and 231 deletions

View File

@ -40,7 +40,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
</ul></li>
<li>JKQTMathText:<ul>
<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>add support for \\bigl,\\bigr,\\Bigr,... commands for fixed-size but large paramtheses</li>
<li>explore options to make font-environment-modifying commands avails, like "{blacktext\\color{red}redtext}", today only commands like "\\textcolor{red}{redtext}" work</li>
<li>maybe: add support for text with linebreaks by adding a JKQTMathTextVerticalListNode in addition to JKQTMathTextListNode</li>

View File

@ -52,6 +52,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>IMPROVED/NEW/breaking: refactored whitespace-processing node JKQTMathTextWhitespaceNode, now all major LaTeX whitespace commands are supported properly</li>
<li>IMPROVED/NEW/breaking: refactored LaTeX parser in JKQTMathText</li>
<li>REMOVED/breaking: \c \\v[a-zA-Z] and shorthand for \c \\vec{a-zA-Z} was removed, implementation of \c \\bbR,\c \\bbC,... changed</li>
<li>IMPROVED/REWORKED rendering of text in text- and math-mode. Now it is more consistent with the output of LaTeX itself</li>
<li>NEW: now supports new decoration instructions: \c \\cancel, \c \\xcancel, \c \\bcancel, \c \\sout, \c \\ocirc, \c \\widetilde, \c \\widehat, \c \\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>

View File

@ -67,6 +67,20 @@
scr: $\mathscr{\ddot{A}q\ddot{u}\ddot{a}t{\oe}r abcABC00, 123-45+6.0\%\S}$, \\
bb: $\mathbb{\ddot{A}q\ddot{u}\ddot{a}t{\oe}r abcABC00, 123-45+6.0\%\S}$, \\
frak: $\mathfrak{\ddot{A}q\ddot{u}\ddot{a}t{\oe}r abcABC00, 123-45+6.0\%\S}$
\item \begin{tabular}{rl}
text: & abc123+d/e\\
textit: & \textit{abc123+d/e}\\
textbf: & \textbf{abc123+d/e}\\
math: & $abc123+d/e$\\
mathrm: & $\mathrm{abc123+d/e}$\\
mathit: & $\mathit{abc123+d/e}$\\
mathbf: & $\mathbf{abc123+d/e}$\\
mathfrak: & $\mathfrak{abc123+d/e}$\\
\end{tabular}
\item $xHq\ \vert\ \big\vert\ \Big\vert\ \bigg\vert\ \Bigg\vert$\\
$xHq\ (\ \big(\ \Big(\ \bigg(\ \Bigg($
\item\textbf{std dev:} \[\sigma_x=\sqrt{\langle (x-\langle x\rangle)^2\rangle}=\sqrt{\frac{1}{N-1}\cdot\left( \sum_{i=1}^N{x_i}^2-\frac{1}{N}\cdot\left(\sum_{i=1}^Nx_i\right)^2\right)} \]
\item\textbf{std dev 2:} \[\sigma_x=\sqrt{\langle (x-\langle x\rangle)^2\rangle}=\sqrt{\frac{1}{N-1}\cdot\left( \sum_{i=1}^Nx_i^2-\frac{1}{N}\cdot\left(\sum_{i=1}^Nx_i\right)^2\right)} \]
@ -167,6 +181,7 @@
\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}$
\item\textbf{math: quadratic formula} \[x_{1/2}=\frac{-b\pm \sqrt{b^2-4ac}}{2a}\]
\end{itemize}

View File

@ -26,6 +26,17 @@ TestForm::TestForm(QWidget *parent) :
const QString umla_math="\\ddot{A}\\ddot{a}\\grave{A}\\grave{a}\\acute{A}\\acute{a}\\hat{A}\\hat{a}\\tilde{A}\\tilde{a}\\r{A}\\r{a}\\u{A}\\u{a}\\bar{A}\\bar{a}\\AA\\aa{\\AE}{\\ae}\\check{C}\\check{c}\\ddot{E}\\ddot{e}\\dot{e}\\L\\l\\ddot{O}\\ddot{o}\\grave{O}\\grave{o}\\acute{O}\\acute{o}\\hat{O}\\hat{o}\\tilde{O}\\tilde{o}\\O\\o{\\OE}{\\ae}\\check{S}\\check{s}\\ss\\ddot{U}\\ddot{u}\\grave{U}\\grave{u}\\acute{U}\\acute{u}\\hat{U}\\hat{u}\\tilde{U}\\tilde{u}";
const QString testTextUmla_math="\\ddot{A}q{\\ddot{u}}\\ddot{{}a}t{\\oe}r00, 123-45+6.0\\%\\S";
ui->cmbTestset->addItem("text: fonts", "rm: \\textrm{"+testText+"}, sf: \\textsf{"+testText+"}, tt: \\texttt{"+testText+"}, cal: \\textcal{"+testText+"}, scr: \\textscr{"+testText+"}, bb: \\textbb{"+testText+"}, frak: \\textfrak{"+testText+"}, ");
ui->cmbTestset->addItem("text/math: font comparison",
"\\begin{matrix}\n"
" text: & abc123+d/e\\\\\n"
" textit: & \\textit{abc123+d/e}\\\\\n"
" textbf: & \\textbf{abc123+d/e}\\\\\n"
" math: & $abc123+d/e$\\\\\n"
" mathrm: & $\\mathrm{abc123+d/e}$\\\\\n"
" mathit: & $\\mathit{abc123+d/e}$\\\\\n"
" mathbf: & $\\mathbf{abc123+d/e}$\\\\\n"
" mathfrak: & $\\mathfrak{abc123+d/e}$\n"
"\\end{matrix}");
ui->cmbTestset->addItem("text: umlaute", umla);
ui->cmbTestset->addItem("text: umlaute and fonts", "rm: \\textrm{"+testTextUmla+"}, sf: \\textsf{"+testTextUmla+"}, tt: \\texttt{"+testTextUmla+"}, cal: \\textcal{"+testTextUmla+"}, scr: \\textscr{"+testTextUmla+"}, bb: \\textbb{"+testTextUmla+"}, frak: \\textfrak{"+testTextUmla+"}, ");
ui->cmbTestset->addItem("text: dashes", "hyphen: - endash: -- emdash: --- \\ \\ \\ endash--within text\\ \\ \\ emdash---within text\\ \\ \\ enemdash-----within text\\ \\ \\ ememdash------within text");
@ -211,7 +222,6 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("mathboxed test", "$\\fbox{2^{2^{\\colorbox{red}{2^{x}}}}}$");
ui->cmbTestset->addItem("axiom of power test", "$\\forall A \\, \\exists P \\, \\forall B \\, [B \\in P \\iff \\forall C \\, (C \\in B \\Rightarrow C \\in A)]$");
ui->cmbTestset->addItem("math: De Morgan's law", "$\\neg(P\\land Q)\\iff(\\neg P)\\lor(\\neg Q)$ or $\\overline{\\bigcap_{i \\in I} A_{i}}\\equiv\\bigcup_{i \\in I} \\overline{A_{i}}$ or $\\overline{A \\cup B}\\equiv\\overline{A} \\cap \\overline{B}$");
ui->cmbTestset->addItem("math: quadratic formula", "$x=\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}$");
ui->cmbTestset->addItem("math: combination", "$\\binom{n}{k} = \\frac{n(n-1)...(n-k+1)}{k(k-1)\\dots1}=\\frac{n!}{k!(n-k)!}$");
ui->cmbTestset->addItem("math: Sophomore's dream 1", "$\\int_0^1 x^{-x}\\,dx = \\sum_{n=1}^\\infty n^{-n}(\\scriptstyle{= 1.29128599706266354040728259059560054149861936827\\dots)}$");
ui->cmbTestset->addItem("math: Sophomore's dream 2", "$\\int_0^1 x^x \\,dx = \\sum_{n=1}^\\infty (-1)^{n+1}n^{-n} = - \\sum_{n=1}^\\infty (-n)^{-n} (\\scriptstyle{= 0.78343051071213440705926438652697546940768199014\\dots})$");
@ -232,6 +242,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("math: Fokker-Planck Equation", "$\\frac{\\partial}{\\partial t}P(y,t)=-\\frac{\\partial}{\\partial y}\\left[ A(y,t)P(y,t)\\right] +\\frac{\\Gamma}{2}\\frac{\\partial^2}{\\partial y^2}\\left[ P(y,t)\\right]$");
ui->cmbTestset->addItem("math: Hamilton Equations of motion", "$\\mathcal{H}(\\mathbf{q},\\mathbf{p})=\\frac{\\mathbf{p}^2}{2\\,m}+V(\\mathbf{q})\\ \\ \\ \\text{and}\\ \\ \\ \\dot{q}_k =\\frac{p_k}{m}\\ ,\\ \\dot{p}_k = - \\frac{\\partial V}{\\partial q_k}$");
ui->cmbTestset->addItem("math: Gaussian Distrubution", "$f(x | \\mu,\\sigma^2)=\\frac{1}{\\sqrt{2\\pi\\sigma^2}}\\operatorname{exp}\\left(-\\frac{(x-\\mu)^2}{2\\sigma^2}\\right)=\\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}\\quad -\\infty<x<\\infty$");
ui->cmbTestset->addItem("math: quadratic equation", "$x_{1/2} = \\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}$");
ui->cmbTestset->addItem("math 1", "$f(x)=\\int_{-\\infty}^xe^{-t^2}\\;\\mathrm{d}t$");
ui->cmbTestset->addItem("math 2", "$\\sum_{i=1}^\\infty\\frac{-e^{i\\pi}}{2^n}$");
ui->cmbTestset->addItem("math 3", "$\\mbox{det} \\begin{pmatrix} 1 & x_1 & \\ldots & x_1^{n-1} \\\\ 1 & x_2 & \\ldots & x_2^{n-1} \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ 1 & x_n & \\ldots & x_n^{n-1} \\end{pmatrix} = \\prod_{1 \\leq i < j \\leq n} (x_j - x_i) $");
@ -457,12 +468,12 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
else ti=new QTreeWidgetItem(ui->tree);
if (decoN) {
name=QString("MTdecoratedNode: mode='%1'").arg(JKQTMathTextDecoratedNode::DecorationType2String(decoN->getDecoration()));
name=QString("DecoratedNode: mode='%1'").arg(JKQTMathTextDecoratedNode::DecorationType2String(decoN->getDecoration()));
if (decoN->getChild()) ti->addChild(createTree(decoN->getChild(), ti));
} else if (matrixN) {
int l=matrixN->getLines();
int c=matrixN->getColumns();
name=QString("MTmatrixNode: l*c=%1*%2").arg(l).arg(c);
name=QString("MatrixNode: l*c=%1*%2").arg(l).arg(c);
QVector<QVector<JKQTMathTextNode*> > children=matrixN->getChildren();
for (int y=0; y<l; y++) {
for (int x=0; x<c; x++) {
@ -474,48 +485,48 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
}
}
} else if (fracN) {
name=QString("MTfracNode: mode='%1'").arg(JKQTMathTextFracNode::FracType2String(fracN->getMode()));
name=QString("FracNode: mode='%1'").arg(JKQTMathTextFracNode::FracType2String(fracN->getMode()));
if (fracN->getChild1()) ti->addChild(createTree(fracN->getChild1(), ti));
if (fracN->getChild2()) ti->addChild(createTree(fracN->getChild2(), ti));
} else if (sqrtN) {
name=QString("MTsqrtNode");
name=QString("SqrtNode");
if (sqrtN->getChildDegree()) ti->addChild(createTree(sqrtN->getChildDegree(), ti));
if (sqrtN->getChild()) ti->addChild(createTree(sqrtN->getChild(), ti));
} else if (braceN) {
name=QString("MTbraceNode: l='%1', r='%2'").arg(JKQTMathTextBraceType2String(braceN->getOpenbrace())).arg(JKQTMathTextBraceType2String(braceN->getClosebrace()));
name=QString("BraceNode: l='%1', r='%2'").arg(JKQTMathTextBraceType2String(braceN->getOpenbrace())).arg(JKQTMathTextBraceType2String(braceN->getClosebrace()));
if (braceN->getChild()) ti->addChild(createTree(braceN->getChild(), ti));
} else if (superN) {
name=QString("MTsuperscriptNode");
name=QString("SuperscriptNode");
if (superN->getChild()) ti->addChild(createTree(superN->getChild(), ti));
} else if (subN) {
name=QString("MTsubscriptNode");
name=QString("SubscriptNode");
if (subN->getChild()) ti->addChild(createTree(subN->getChild(), ti));
} else if (instS) {
name=QString("SimpleInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(instS->getInstructionName()).arg(instS->isSubSuperscriptAboveBelowNode()).arg(instS->getParameters().join("/"));
} else if (inst1N) {
name=QString("ModTxtPropsInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(inst1N->getInstructionName()).arg(inst1N->isSubSuperscriptAboveBelowNode()).arg(inst1N->getParameters().join("/"));
name=QString("ModifiedTextPropsInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(inst1N->getInstructionName()).arg(inst1N->isSubSuperscriptAboveBelowNode()).arg(inst1N->getParameters().join("/"));
if (inst1N->getChild()) ti->addChild(createTree(inst1N->getChild(), ti));
} else if (inst1B) {
name=QString("BoxInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(inst1B->getInstructionName()).arg(inst1B->isSubSuperscriptAboveBelowNode()).arg(inst1B->getParameters().join("/"));
if (inst1B->getChild()) ti->addChild(createTree(inst1B->getChild(), ti));
} else if (lstN) {
name=QString("HListNode");
name=QString("HorizontalListNode");
QList<JKQTMathTextNode*> list=lstN->getChildren();
for (int i=0; i<list.size(); i++) {
ti->addChild(createTree(list[i], ti));
}
} else if (lstNV) {
name=QString("VListNode (align=%1, spacingFactor=%2x, spacingMode=%3, verticalOrientation=%4)").arg(JKQTMathTextHorizontalAlignment2String(lstNV->getAlignment())).arg(lstNV->getLineSpacingFactor()).arg(lstNV->SpacingMode2String(lstNV->getSpacingMode())).arg(JKQTMathTextVerticalOrientation2String(lstNV->getVerticalOrientation()));
name=QString("VerticalListNode (align=%1, spacingFactor=%2x, spacingMode=%3, verticalOrientation=%4)").arg(JKQTMathTextHorizontalAlignment2String(lstNV->getAlignment())).arg(lstNV->getLineSpacingFactor()).arg(lstNV->SpacingMode2String(lstNV->getSpacingMode())).arg(JKQTMathTextVerticalOrientation2String(lstNV->getVerticalOrientation()));
QList<JKQTMathTextNode*> list=lstNV->getChildren();
for (int i=0; i<list.size(); i++) {
ti->addChild(createTree(list[i], ti));
}
} else if (symN) {
name=QString("MTSymbolNode: \'%1\' (subsuper=%3)").arg(symN->getSymbolName()).arg(symN->isSubSuperscriptAboveBelowNode());
name=QString("SymbolNode: \'%1\' (subsuper=%3)").arg(symN->getSymbolName()).arg(symN->isSubSuperscriptAboveBelowNode());
} else if (spN) {
name=QString("MTWhitespaceNode :type=%1, count=%2").arg(spN->Type2String(spN->getWhitespaceType())).arg(spN->getWhitespaceCount());
name=QString("WhitespaceNode :type=%1, count=%2").arg(spN->Type2String(spN->getWhitespaceType())).arg(spN->getWhitespaceCount());
} else if (txtN) {
name=QString("MTTextNode: \'%1\'").arg(txtN->getText());
name=QString("TextNode: \'%1\'").arg(txtN->getText());
} else {
name=QString("unknown");
}

View File

@ -50,6 +50,9 @@ class JKQTMathTextNode; // forward
The class does not depend on any library, except Qt.
In particular it actually parses a LaTeX string and draws it in pure C++. It does NOT rely
on an installed LaTeX for the rendering!
\see See \ref jkqtmathtext_supportedlatex for a description of the supported LaTeX subset
and \ref jkqtmathtext_renderingmodel for a description of the rendering model.
\section JKQTMathTextUsage Usage
\subsection JKQTMathTextUsageDirect Direct Usage
@ -98,127 +101,11 @@ class JKQTMathTextNode; // forward
\section JKQTMathTextExamples Examples
Examples for the usage of this class can be found here:
- \ref JKQTMathTextSimpleExample
- \ref JKQTMathTextSimpleExample
- \ref JKQTMathTextTestApp
.
\section JKQTMathTextSuppoertedLaTeX Supported LaTeX Subset
\subsection JKQTMathTextSuppoertedLaTeXSimple Simple Instructions
The supported LaTeX subset is listes below. Please note that some commands are used differently than in actual LaTeX.
For example \c \\bf is just a renamed form of \c \\textbf and used as \c \\bf{...} and NOT as \c {\\bf...} .
- \c $ : enter/leave math mode
- \c \\bf{...} \c \\textbf{...} \c \\mathbf{...}: draw the contained text in bold face \image html jkqtmathtext/jkqtmathtext_bold.png
- \c \\it{...} \c \\textit{...} \c \\mathit{...} : draw the contained text in italic face \image html jkqtmathtext/jkqtmathtext_italic.png
- \c \\rm{...} \c \\textrm{...} \c \\mathrm{...} \c \\mbox{...} : draw the contained text in normal upright roman font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\sf{...} \c \\textsf{...} \c \\mathsf{...} : draw the contained text in normal upright sans-serif font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\script{...} \c \\textscript{...} \c \\mathscript{...} : draw the contained text in a script font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\sc{...} : draw the text in small caps \image html jkqtmathtext/jkqtmathtext_sc.png
- \c \\ul{...} \c \\underline{...} \c \\underlined{...} : draw the text with underlining \image html jkqtmathtext/jkqtmathtext_ul.png
- \c \\sout{...} : strike out the text \image html jkqtmathtext/MTDstrike.png
- \c \\cancel{...} : slanted strike out the text \image html jkqtmathtext/MTDcancel.png
- \c \\bcancel{...} : back-strike out the text \image html jkqtmathtext/MTDbcancel.png
- \c \\xcancel{...} : x-strike out the text \image html jkqtmathtext/MTDxcancel.png
- \c \\ol{...} \c \\overline{...} \c \\overlined{...} : draw the text with overlining \image html jkqtmathtext/jkqtmathtext_ol.png
- \c \\tt{...} \c \\texttt{...} \c \\mathtt{...} : draw text in typewriter font \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\textcolor{color}{...} \c \\color{color} \c \\mathcolor{color}{...} : draw colored text \image html jkqtmathtext/jkqtmathtext_colored.png
- \c \\userfont{font}{...} : draw text in a user-specific font, available on the system \image html jkqtmathtext/jkqtmathtext_userfont.png (generated by <code>default, \\userfont{Arial}{Arial}, \\userfont{Comic Sans MS}{Comic Sans MS}</code> )
- \c \\boxed{...} : draw text with a box around it \image html jkqtmathtext/jkqtmathtext_boxed.png
- \c \\doublebox{...} : draw text with a rounded box around it \image html jkqtmathtext/jkqtmathtext_doublebox.png
- \c \\ovalbox{...} : draw text with a rounded box around it \image html jkqtmathtext/jkqtmathtext_ovalboxed.png
- \c \\Ovalbox{...} : draw a thick oval box \image html jkqtmathtext/jkqtmathtext_oovalbox.png
- \c \\dashbox{...} , \c \\dbox{...} : draw a dashed box \image html jkqtmathtext/jkqtmathtext_dashbox.png
- \c \\dottedbox{...} : draw a dottted box \image html jkqtmathtext/jkqtmathtext_dottedbox.png
- \c \\ovaldoublebox{...} : draw a double oval box \image html jkqtmathtext/jkqtmathtext_doubleovalbox.png
- \c \\colorbox{bordercolor}{...} : draw a colored box \image html jkqtmathtext/jkqtmathtext_colorbox.png
- \c \\shaded{backgroundcolor}{...} : draw a filled box \image html jkqtmathtext/jkqtmathtext_shaded.png
- \c \\fcolorbox{bordercolor}{backgroundcolor}{...} : draw a colored, filled box \image html jkqtmathtext/jkqtmathtext_fcolorbox.png
- \c \\colorbox{color}{...} : draw a colored box around text \image html jkqtmathtext/jkqtmathtext_colorbox.png
- \c \\alpha ... : display the according greek letter \image html jkqtmathtext/jkqtmathtext_greek.png
- \c \\charDECIMAL and \c \\char\"HEX and \c \\char\'OCTAL : draws a unicode character from its 32-bit codepoint \image html jkqtmathtext/jkqtmathtext_char.png (generated by <code>A: \\char65, circonflex: \\char\"109 accent: \\char\'351</code>)
- \c \\unicode{HEX} and \c \\usym{HEX} : draws a unicode character from its 32-bit codepoint \image html jkqtmathtext/jkqtmathtext_unicode.png (generated by <code>star: \\unicode{2605}, circonflex: \\unicode{109} emoticons: \\usym{1F440} \\usym{1F929}</code>)
- \c \\utfeight{HEX} : draws a unicode character from its UTF-8 encoding \image html jkqtmathtext/jkqtmathtext_utf8.png (generated by <code>star: \\utfeight{e29885} emoticons \\utfeight{F09F9881} \\utfeight{f09f98bb}</code>)
- \c ^{...} \c _{...} : display the contents of braces in superscript/subscript \image html jkqtmathtext/jkqtmathtext_supersub.png
<br>Special subscript/superscript typesetting applies, when the sub/super follows \c \\sum \c \\Prod ...: \image html jkqtmathtext/jkqtmathtext_specialsubsuper.png
- \c \\{ / \\} : display opening/closing brace
- \c \\_ : display underscore
- \c \\sum \c \\prod \c \\int ... : plot special symbol. Note that depending on the fontEncoding the available
symbols may differ (there are not all symbols defined in the MS Windows Symbol
font!). Best coverage should be given by Unicode font encoding with a good
unicode font installed!<br>\image html jkqtmathtext/jkqtmathtext_symbols.png
- \c - : draw a hyphen \image html jkqtmathtext/jkqtmathtext_hyphen.png
- \c -- : draw an en-dash \image html jkqtmathtext/jkqtmathtext_endash.png
- \c --- : draw an em-dash \image html jkqtmathtext/jkqtmathtext_emdash.png
- <code>\\vec{x} \\dot{x} \\ddot{x} \\overline{x} \\underline{x} \\hat{x} \\tilde{x} \\uul{x} \\ool{x} \\bar{x} \\arrow{x} \\widehat{x} \\widetilde{x} ...</code>: Decorations over/under symbols \image html jkqtmathtext/jkqtmathtext_mathdeco.png
- <code>\\verb{don't parse this _aaa\\LaTeX} </code>: interpret enclosed text as verbose \image html jkqtmathtext/jkqtmathtext_verb.png
.
\subsection JKQTMathTextSuppoertedLaTeXBraces Braces ...
Braces in math mode are adjusted in size, so they are a small bit (factor \c brace_factor ) larger than the contents.
To enable this you have to write braces with \c \\left and \c \\right. These types of braces are defined (slight
differences to LaTeX standard):
- \c \\left( \c \\right) : default meaning (), \image html jkqtmathtext/jkqtmathtext_brace_round.png
- \c \\left[ \c \\right] : default meaning [], \image html jkqtmathtext/jkqtmathtext_brace_rect.png
- \c \\left\\{ \c \\right\\} : default meaning {}, \image html jkqtmathtext/jkqtmathtext_brace_curly.png
- \c \\left< \c \\right> : "averaging" braces , \image html jkqtmathtext/jkqtmathtext_brace_tri.png
- \c \c \\left\\lfloor \c \\right\\rfloor : floor braces , \image html jkqtmathtext/jkqtmathtext_brace_floor.png
- \c \\left~ \c \\right~ \c \\left\\lceil \c \\right\\rceil : ceil braces , \image html jkqtmathtext/jkqtmathtext_brace_ceil.png
- \c \\left| \c \\right| : absolute value braces | |, \image html jkqtmathtext/jkqtmathtext_brace_oneline.png
- \c \\left\\| \c \\right\\| \endcode : norm braces || ||, \image html jkqtmathtext/jkqtmathtext_brace_dblline.png
- You can use \c \\left. or \c \\right. to have only right or only left brace
.
\subsection JKQTMathTextSuppoertedLaTeXRoots Roots
There are also instructions that allow to write roots:
- <code>$\\sqrt{1+\\sqrt{1+x}}$</code> \image html jkqtmathtext/jkqtmathtext_sqrt.png
- <code>$\\sqrt[3]{1+\\sqrt[3]{1+x}}$</code> \image html jkqtmathtext/jkqtmathtext_cbrt.png
.
\subsection JKQTMathTextSuppoertedLaTeXUnderOver Undersetting, Oversetting, Underbraces, Overbraces ...
There are also instructions that allow to under/overset braces, arrows, ...:
- <code>$\\underbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/jkqtmathtext_brace_underbrace.png
- <code>$\\overbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/jkqtmathtext_brace_overbrace.png
- <code>$\\underbracket{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/MTFMunderbracket.png
- <code>$\\overbracket{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/MTFMoverbracket.png
- <code>$\\overset{main}{over}$</code> \image html jkqtmathtext/jkqtmathtext_brace_overset.png
- <code>$\\underset{main}{under}$</code> \image html jkqtmathtext/jkqtmathtext_brace_underset.png
.
\subsection JKQTMathTextSuppoertedLaTeXFrac Fraction Type Instructions
Several Matrix/Array-typed LaTeX instructions are supported:
- <code>$\\frac{...}{...}$</code> \image html jkqtmathtext/MTFMfrac.png
- <code>$\\tfrac{...}{...}$</code> (70% smaller font) \image html jkqtmathtext/MTFMtfrac.png
- <code>$\\dfrac{...}{...}$</code> \image html jkqtmathtext/MTFMdfrac.png
- <code>$\\sfrac{...}{...}$</code> \image html jkqtmathtext/MTFMsfrac.png
- <code>$\\stfrac{...}{...}$</code> (70% smaller font) \image html jkqtmathtext/MTFMstfrac.png
.
\subsection JKQTMathTextSuppoertedLaTeXMatrix Matrix/Array Type Instructions
Several Matrix/Array-typed LaTeX instructions are supported:
- <code>$\\stackrel{...}{...}$ $\\binom{...}{...}$</code> \image html jkqtmathtext/jkqtmathtext_brace_stackrel.png
- <code>$\\begin{cases} ... & ... \\\\ ... & ... \\end{cases}$</code> \image html jkqtmathtext/jkqtmathtext_brace_begincases.png
- <code>$\\begin{array} a & b & ...\\\\ c & d & ...\\end{array}$</code> <code>$\\begin{matrix} a & b & ...\\\\ c & d & ...\\end{matrix}$</code> \image html jkqtmathtext/jkqtmathtext_array.png
- <code>$\\begin{pmatrix} a & b & ...\\\\ c & d & ...\\end{pmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_pmatrix.png
- <code>$\\begin{bmatrix} a & b & ...\\\\ c & d & ...\\end{bmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_bmatrix.png
- <code>$\\begin{Bmatrix} a & b & ...\\\\ c & d & ...\\end{Bmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_bbmatrix.png
- <code>$\\begin{vmatrix} a & b & ...\\\\ c & d & ...\\end{vmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_vmatrix.png
- <code>$\\begin{Vmatrix} a & b & ...\\\\ c & d & ...\\end{Vmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_vvmatrix.png
- <code>$\\substack[lrc]{...\\\\...}$</code> \image html jkqtmathtext/jkqtmathtext_substack.png
- <code>$\\lsubstack{...\\\\...}$</code> \image html jkqtmathtext/jkqtmathtext_lsubstack.png
- <code>$\\rsubstack{...\\\\...}$</code> \image html jkqtmathtext/jkqtmathtext_rsubstack.png
.
\subsection JKQTMathTextSuppoertedLaTeXTextAlignment Environments for Multi-line text
Several environments are supported that allow to layout text with linebreaks and different alignemnts:
- <code>$\\begin{document} ... \\\\ ... \\end{document}$</code> \image html jkqtmathtext/jkqtmathtext_beginflushleft.png
- <code>$\\begin{flushleft} ... \\\\ ... \\end{flushleft}$</code> \image html jkqtmathtext/jkqtmathtext_beginflushleft.png
- <code>$\\begin{flushright} ... \\\\ ... \\end{flushright}$</code> \image html jkqtmathtext/jkqtmathtext_beginflushright.png
- <code>$\\begin{center} ... \\\\ ... \\end{center}$</code> \image html jkqtmathtext/jkqtmathtext_begincenter.png
- <code>$\\begin{framed} ... \\\\ ... \\end{framed}$</code> \image html jkqtmathtext/jkqtmathtext_beginframed.png
- <code>$\\begin{shaded} ... \\\\ ... \\end{shaded}$</code> \image html jkqtmathtext/jkqtmathtext_beginshaded.png
- <code>$\\begin{snugshade} ... \\\\ ... \\end{snugshade}$</code> \image html jkqtmathtext/jkqtmathtext_beginsnugshade.png
.
\section JKQTMathTextSuppoertedFonts Font Handling
Several fonts are defined as properties to the class:

View File

@ -277,9 +277,17 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bf"] = i;
instructions["textbf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbf"]= i;
}
{
@ -291,6 +299,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["it"] = i;
instructions["textit"] = i;
@ -313,7 +322,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=true; ev.insideMath=true;
ev.beginMathMode();
}, 0);
instructions["ensuremath"] = i;
instructions["equation"]= i;
@ -321,6 +330,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.smallCaps=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["sc"] = i;
instructions["textsc"] = i;
@ -360,6 +370,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathrm"] = i;
instructions["unit"] = i;
@ -369,6 +380,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfit"] = i;
instructions["bfit"] = i;
@ -376,9 +388,8 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.insideMath=false;
ev.endMathMode();
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
}, 0);
instructions["text"] = i;
instructions["mbox"] = i;
@ -396,6 +407,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathcal"]= i;
}
@ -411,6 +423,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.italic=false;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfcal"]= i;
}
@ -418,6 +431,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bbfcal"] = i;
instructions["textfcal"] = i;
@ -433,6 +447,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathfrak"]= i;
}
@ -441,6 +456,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbffrak"]= i;
}
@ -456,6 +472,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEblackboard;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bb"] = i;
instructions["textbb"] = i;
@ -472,6 +489,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathtt"]= i;
}
@ -488,6 +506,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.italic=false;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbftt"]= i;
}
@ -502,6 +521,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathsf"] = i;
}
@ -509,6 +529,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["itsf"] = i;
instructions["textitsf"] = i;
@ -527,6 +548,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathscript"] = i;
instructions["mathscr"]= i;
@ -546,6 +568,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfscript"] = i;
instructions["mathbfscr"]= i;

View File

@ -1,7 +1,7 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
@ -58,32 +58,88 @@ JKQTMathTextTextNode::JKQTMathTextTextNode(JKQTMathText* _parent, const QString&
JKQTMathTextTextNode::~JKQTMathTextTextNode() = default;
void JKQTMathTextTextNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
QFont f=currentEv.getFont(parentMathText);
if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" ||
text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) ||
text==QString(QChar(0x2309)) || text==QString(QChar(0x230A)) || text==QString(QChar(0x230B)))) {
f.setItalic(false);
QStringList textpart;
QList<bool> fontForcedUpright;
QList<double> textpartXPos;
getSizeInternalAndData(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos,textpart, fontForcedUpright, textpartXPos);
}
void JKQTMathTextTextNode::getSizeInternalAndData(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, QStringList &textpart, QList<bool> &fontForcedUpright, QList<double> &textpartXPos)
{
textpart.clear();
fontForcedUpright.clear();
const QString txt=textTransform(text, currentEv, true);
if (currentEv.insideMath && currentEv.insideMathForceDigitsUpright) {
splitTextForMathMode(txt, textpart, fontForcedUpright);
} else {
textpart.append(text);
fontForcedUpright.append(false);
}
const QFont f=currentEv.getFont(parentMathText);
const QFont fnonItalic=JKQTMathTextGetNonItalic(f);
const QFontMetricsF fmNonItalic(fnonItalic, painter.device());
const QFontMetricsF fm(f, painter.device());
width=0;
double ascent=0;
double descent=0;
for (int i=0; i<textpart.size(); i++) {
const QRectF br=(fontForcedUpright[i]) ? fmNonItalic.boundingRect(textpart[i]) : fm.boundingRect(textpart[i]);
const QRectF tbr=(fontForcedUpright[i]) ? JKQTMathTextGetTightBoundingRect(fnonItalic, textpart[i], painter.device()) : JKQTMathTextGetTightBoundingRect(f, textpart[i], painter.device());
textpartXPos.append(width);
width+=br.width();
const double thisAscent=-tbr.top();
const double thisDescent=tbr.bottom();
ascent=qMax(ascent, thisAscent);
descent=qMax(descent, thisDescent);
}
overallHeight=(ascent+descent); //fm.height();
baselineHeight=ascent;
strikeoutPos=fm.strikeOutPos();
}
void JKQTMathTextTextNode::splitTextForMathMode(const QString &txt, QStringList &textpart, QList<bool> &fontForcedUpright)
{
auto isForcedUprightChar=[](const QChar& c) {
return c.isDigit()
|| c=='(' || c=='[' || c=='|' || c==']' || c==')' || c=='<' || c=='>'|| c=='{' || c=='}' || c=='|'
|| c==QChar(0x2329) || c==QChar(0x232A) || c==QChar(0x2308) || c==QChar(0x2309) || c==QChar(0x230A) || c==QChar(0x230B);
};
textpart.clear();
fontForcedUpright.clear();
QString currentSection="";
bool currentSectionForcedUpright=false;
int i=0;
while (i<txt.size()) {
const QChar c=txt[i];
const bool CisForcedUprightChar=isForcedUprightChar(c);
const bool CisForcedUprightCharExt=CisForcedUprightChar||(c=='.')||(c==',');
if (currentSection.size()==0) {
// start new section
currentSectionForcedUpright=CisForcedUprightChar;
currentSection+=c;
} else {
// existing section
if (CisForcedUprightCharExt==currentSectionForcedUpright) {
// continue current section
currentSection+=c;
} else {
// start new section
textpart.append(currentSection);
fontForcedUpright.append(currentSectionForcedUpright);
currentSection=c;
currentSectionForcedUpright=CisForcedUprightChar;
}
}
QString txt=textTransform(text, currentEv, true);
QFontMetricsF fm(f, painter.device());
QRectF br=fm.boundingRect(txt);
QRectF tbr=JKQTMathTextGetTightBoundingRect(f, txt, painter.device()); //fm.tightBoundingRect(txt);
if (txt=="|") {
br=fm.boundingRect("X");
tbr=QRectF(0,0,fm.boundingRect("X").width(), fm.ascent());//fm.boundingRect("X");
br.setWidth(0.7*br.width());
i++;
}
width=br.width();//width(text);
if (txt.size()>0) {
if (txt[0].isSpace() /*&& br.width()<=0*/) width=width+fm.boundingRect("I").width();
if (txt.size()>1 && txt[txt.size()-1].isSpace() /*&& (fm.boundingRect("a ").width()==fm.boundingRect("a").width())*/) width=width+fm.boundingRect("I").width();
if (currentSection.size()>0) {
textpart.append(currentSection);
fontForcedUpright.append(currentSectionForcedUpright);
}
//qDebug()<<"text: "<<text<<" "<<tbr.height()<<tbr.top()<<tbr.bottom();
overallHeight=tbr.height()*1.1; //fm.height();
baselineHeight=1.1*(tbr.height()-(tbr.height()+tbr.top()));//fm.ascent();
strikeoutPos=fm.strikeOutPos()*1.1;
}
double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
@ -92,91 +148,40 @@ double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMat
double baselineHeight=0;
double overallHeight=0;
double sp=0;
getSize(painter, currentEv, width, baselineHeight, overallHeight, sp);
QString txt=textTransform(text, currentEv);
bool hasDigits=false;
bool onlyDigits=true;
for (int i=0; i<txt.size(); i++) {
if (txt[i].isDigit()) {
hasDigits=true;
}
if (!txt[i].isDigit() && !txt[i].isSpace()) {
onlyDigits=false;
}
}
QStringList textpart;
QList<bool> fontForcedUpright;
QList<double> textpartXPos;
getSizeInternalAndData(painter, currentEv, width, baselineHeight, overallHeight, sp, textpart, fontForcedUpright, textpartXPos);
QPen pold=painter.pen();
QFont fold=painter.font();
QFont f=currentEv.getFont(parentMathText);
if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" ||
text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) ||
text==QString(QChar(0x2309)) || text==QString(QChar(0x230A)) || text==QString(QChar(0x230B)))) {
f.setItalic(false);
}
if (onlyDigits && currentEv.insideMath) {
f.setItalic(false);
}
const QFont f=currentEv.getFont(parentMathText);
const QFont fnonItalic=JKQTMathTextGetNonItalic(f);
const QFontMetricsF fm(f, painter.device());
const QFontMetricsF fmNonItalic(fnonItalic, painter.device());
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setFont(f);
//qDebug()<<"JKQTMathTextTextNode: text="<<text<<" font="<<f;
QPen p=painter.pen();
p.setColor(currentEv.color);
const QPen p(currentEv.color, fm.lineWidth(), Qt::SolidLine);
painter.setPen(p);
double dx=0;
QFontMetricsF fm(f, painter.device());
/*if (txt.size()>1 && txt[txt.size()-1].isSpace()) {
QFontMetricsF fm(f, painter.device());
//if ((fm.QFMF_WIDTH("a ")==fm.QFMF_WIDTH("a"))) dx=fm.boundingRect("I").QFMF_WIDTH();
}*/
if (!hasDigits || !f.italic()) {
auto drawString=[&](QPainter& painter, const QFont& f, double x, double y, const QString& txt) {
if (currentEv.font==MTEblackboard && parentMathText->isFontBlackboardSimulated()) {
QPainterPath path;
path.addText(QPointF(x+dx, y), f, txt);
path.addText(QPointF(x, y), f, txt);
painter.drawPath(path);
} else {
painter.drawText(QPointF(x+dx, y), txt);//.simplified());
}
} else {
int i=0;
double xx=x+dx;
QFont ff=f;
QFontMetricsF fmff(ff, painter.device());
ff.setItalic(false);
while (i<txt.size()) {
if (txt[i].isDigit()) {
if (currentEv.font==MTEblackboard && parentMathText->isFontBlackboardSimulated()) {
QPainterPath path;
path.addText(QPointF(xx, y), ff, QString(txt[i]));
painter.drawPath(path);
} else {
painter.setFont(ff);
painter.drawText(QPointF(xx, y), QString(txt[i]));
}
xx=xx+fmff.boundingRect(txt[i]).width();
} else {
if (currentEv.font==MTEblackboard && parentMathText->isFontBlackboardSimulated()) {
QPainterPath path;
path.addText(QPointF(xx, y), f, QString(txt[i]));
painter.drawPath(path);
} else {
painter.setFont(f);
painter.drawText(QPointF(xx, y), QString(txt[i]));
}
xx=xx+fm.boundingRect(txt[i]).width();
}
i++;
painter.setFont(f);
painter.drawText(QPointF(x, y), txt);
}
};
for (int i=0; i<textpart.size(); i++) {
if (fontForcedUpright[i]) drawString(painter, fnonItalic, x+textpartXPos[i], y, textpart[i]);
else drawString(painter, f, x+textpartXPos[i], y, textpart[i]);
}
painter.setPen(pold);
painter.setFont(fold);
return x+width;
}
@ -207,7 +212,6 @@ QString JKQTMathTextTextNode::textTransform(const QString &text, JKQTMathTextEnv
switch(c.unicode()) {
case '-': txt+=QString(QString(" ")+QChar(0x2212)); break;
case '+': txt+=QString(QString(" +")); break;
case '/': txt+=QString(QString(" /")); break;
case '<': txt+=QString(QString(" <")); break;
case '>': txt+=QString(QString(" >")); break;
case '=': txt+=QString(QString(" =")); break;

View File

@ -50,8 +50,12 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextNode {
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \brief calculates the size of the node, much like JKQTMathTextNode::getSizeInternal(), but returns additional properties that can be reused for drawing */
void getSizeInternalAndData(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, QStringList& textpart, QList<bool>& fontForcedUpright, QList<double>& textpartXPos) ;
/** \brief text-contents of the node */
QString text;
/** \brief split text for Math-Mode into section with "normal" text and "forced upright" text */
static void splitTextForMathMode(const QString& txt, QStringList& textpart, QList<bool>& fontForcedUpright);
/** \brief transforms the text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */
virtual QString textTransform(const QString& text, JKQTMathTextEnvironment currentEv, bool forSize=false);
};