mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-24 09:31:40 +08:00
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:
parent
79c5b26642
commit
0b1af2e8f9
@ -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>
|
||||
|
@ -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>
|
||||
|
Binary file not shown.
@ -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}
|
||||
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user