bugfix: JKQTMathText: \sum and \prod used the wrong symbol in XITS-mode

NEW: JKQTMathText: \limits and \nolimits work as in LaTeX now (before it was simply removed and the functionality implemented for a fixed list of symbols)
remove/breaking: JKQTMathText: \v[a-zA-Z] and shorthand for \vec{a-zA-Z} was removed
improvement: improved typesetting of sub-/supercripts, especially for large math operators and braces
This commit is contained in:
jkriege2 2022-06-26 00:28:49 +02:00
parent f49714ecb6
commit 45d6ef373b
21 changed files with 834 additions and 524 deletions

View File

@ -32,8 +32,11 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>FIXED: strikeoutPos was not correctly calculated in sub-/superscript node</li> <li>FIXED: strikeoutPos was not correctly calculated in sub-/superscript node</li>
<li>FIXED: symbol spacing in math mode (and text mode)</li> <li>FIXED: symbol spacing in math mode (and text mode)</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>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>FIXED: \sum and \prod used the wrong symbol in XITS-mode</li>
<li>IMPROVED: high-dpr-support in JKQTMathText</li> <li>IMPROVED: high-dpr-support in JKQTMathText</li>
<li>IMPROVED: typesetting of sub-/supercripts, especially for large math operators and braces</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>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>remove/breaking: \v[a-zA-Z] and shorthand for \vec{a-zA-Z} was removed, implementation of \bbR,\bbC,... changed</li>
<li>NEW: now supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve</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 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 code structure: broke up large, single CPP-files into several smaller files!</li>
@ -42,6 +45,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>NEW: shows strikeoutPos when drawing Debug-Boxes</li> <li>NEW: shows strikeoutPos when drawing Debug-Boxes</li>
<li>NEW: LaTeX-Parser understands optional instruction parameters in [...] now</li> <li>NEW: LaTeX-Parser understands optional instruction parameters in [...] now</li>
<li>NEW: LaTeX-Parser simplifies parrse-tree to increase speed of execution</li> <li>NEW: LaTeX-Parser simplifies parrse-tree to increase speed of execution</li>
<li>NEW: \limits and \nolimits works as in LaTeX now (before it was simply removed and the functionality implemented for a fixed list of symbols)</li>
</ul> </ul>
</ul> </ul>

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -130,6 +130,7 @@
\item\textbf{math: long non-2 radicals:} \[Hxq \sqrt[3.14156]{a}\sqrt[3.14156]{5}\] \item\textbf{math: long non-2 radicals:} \[Hxq \sqrt[3.14156]{a}\sqrt[3.14156]{5}\]
\item\textbf{math: sum, prod, ...:} no-limits: \[Hxq \prod_{i=1}^n \sum_{j=1}^c (i + j)\cdot\frac{1}{2}\]\ \ \ --\ \ \ limits: \[Hxq \prod\limits_{i=1}^n \sum\limits_{j=1}^c (i + j)\cdot\frac{1}{2}\]\ \ \ --\ \ \ long-below: \[\sum_{n=\{a,b,c,d,e,f,g\}} f(x)\]\ \ \ --\ \ \ long-above: \[\sum^{n=\{a,b,c,d,e,f,g\}} f(x)\] \item\textbf{math: sum, prod, ...:} no-limits: \[Hxq \prod_{i=1}^n \sum_{j=1}^c (i + j)\cdot\frac{1}{2}\]\ \ \ --\ \ \ limits: \[Hxq \prod\limits_{i=1}^n \sum\limits_{j=1}^c (i + j)\cdot\frac{1}{2}\]\ \ \ --\ \ \ long-below: \[\sum_{n=\{a,b,c,d,e,f,g\}} f(x)\]\ \ \ --\ \ \ long-above: \[\sum^{n=\{a,b,c,d,e,f,g\}} f(x)\]
\item\textbf{math: more sum-symbols :} \[Hxq \sum_{i=0}^N\prod_{i=0}^N\coprod_{i=0}^N\bigcup_{i=0}^N\bigcap_{i=0}^N\bigsqcup_{i=0}^N\bigvee_{i=0}^N\bigwedge_{i=0}^N\bigoplus_{i=0}^N\bigotimes_{i=0}^N\bigodot_{i=0}^N\biguplus_{i=0}^N\] \item\textbf{math: more sum-symbols :} \[Hxq \sum_{i=0}^N\prod_{i=0}^N\coprod_{i=0}^N\bigcup_{i=0}^N\bigcap_{i=0}^N\bigsqcup_{i=0}^N\bigvee_{i=0}^N\bigwedge_{i=0}^N\bigoplus_{i=0}^N\bigotimes_{i=0}^N\bigodot_{i=0}^N\biguplus_{i=0}^N\]
\item\textbf{math: more sum-symbols, no-limits :} $Hxq \sum_{i=0}^N\prod_{i=0}^N\coprod_{i=0}^N\bigcup_{i=0}^N\bigcap_{i=0}^N\bigsqcup_{i=0}^N\bigvee_{i=0}^N\bigwedge_{i=0}^N\bigoplus_{i=0}^N\bigotimes_{i=0}^N\bigodot_{i=0}^N\biguplus_{i=0}^N$
\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: 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{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{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}}$

View File

@ -34,15 +34,15 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("math: 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)}$"); ui->cmbTestset->addItem("math: 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)}$");
ui->cmbTestset->addItem("math: 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)}$"); ui->cmbTestset->addItem("math: 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)}$");
ui->cmbTestset->addItem("math: rotation matrix", "$\\mathrm{\\mathbf{M}}(\\alpha) = \\left(\\begin{matrix}\\cos(\\alpha)+n_x^2\\cdot (1-\\cos(\\alpha)) & n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))-n_z\\cdot \\sin(\\alpha) & n_x\\cdot n_z\\cdot (1-\\cos(\\alpha))+n_y\\cdot \\sin(\\alpha)\\\\n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_z\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_y^2\\cdot (1-\\cos(\\alpha)) & n_y\\cdot n_z\\cdot (1-\\cos(\\alpha))-n_x\\cdot \\sin(\\alpha)\\\\n_z\\cdot n_x\\cdot (1-\\cos(\\alpha))-n_y\\cdot \\sin(\\alpha) & n_z\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_x\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_z^2\\cdot (1-\\cos(\\alpha))\\end{matrix}\\right)$"); ui->cmbTestset->addItem("math: rotation matrix", "$\\mathrm{\\mathbf{M}}(\\alpha) = \\left(\\begin{matrix}\\cos(\\alpha)+n_x^2\\cdot (1-\\cos(\\alpha)) & n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))-n_z\\cdot \\sin(\\alpha) & n_x\\cdot n_z\\cdot (1-\\cos(\\alpha))+n_y\\cdot \\sin(\\alpha)\\\\n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_z\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_y^2\\cdot (1-\\cos(\\alpha)) & n_y\\cdot n_z\\cdot (1-\\cos(\\alpha))-n_x\\cdot \\sin(\\alpha)\\\\n_z\\cdot n_x\\cdot (1-\\cos(\\alpha))-n_y\\cdot \\sin(\\alpha) & n_z\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_x\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_z^2\\cdot (1-\\cos(\\alpha))\\end{matrix}\\right)$");
ui->cmbTestset->addItem("text: like in label at bottom)", "\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)");
ui->cmbTestset->addItem("math: like in label at bottom", "$\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)$"); ui->cmbTestset->addItem("math: like in label at bottom", "$\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)$");
ui->cmbTestset->addItem("text: like in label at bottom)", "\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)");
ui->cmbTestset->addItem("text 0", "text"); ui->cmbTestset->addItem("text 0", "text");
ui->cmbTestset->addItem("text 1", "text \\mathbf{bold}"); ui->cmbTestset->addItem("text 1", "text \\mathbf{bold}");
ui->cmbTestset->addItem("text 2", "text \\mathbf{bold}\\textcolor{red}{RED}"); ui->cmbTestset->addItem("text 2", "text \\mathbf{bold}\\textcolor{red}{RED}");
const auto mathDecoExample=[](const QString& deco)->QString { return "\\"+deco+"{x}\\"+deco+"{i}\\"+deco+"{X}\\"+deco+"{\\psi}\\"+deco+"{abc}"; }; const auto mathDecoExample=[](const QString& deco)->QString { return "\\"+deco+"{x}\\"+deco+"{i}\\"+deco+"{X}\\"+deco+"{\\psi}\\"+deco+"{abc}"; };
ui->cmbTestset->addItem("decoration: math", "$"+mathDecoExample("vec")+" -- "+mathDecoExample("dot")+" -- "+mathDecoExample("ddot")+" -- "+mathDecoExample("ocirc")+" -- "+mathDecoExample("overline")+" -- "+mathDecoExample("underline")+" -- "+mathDecoExample("hat")+" -- "+mathDecoExample("widehat")+" -- "+mathDecoExample("check")+" -- "+mathDecoExample("widecheck")+" -- "+mathDecoExample("breve")+" -- "+mathDecoExample("tilde")+" -- "+mathDecoExample("widetilde")+" -- "+mathDecoExample("uul")+" -- "+mathDecoExample("ool")+" -- "+mathDecoExample("bar")+" -- "+mathDecoExample("arrow")+" -- "+mathDecoExample("cancel")+" -- "+mathDecoExample("bcancel")+" -- "+mathDecoExample("xcancel")+" -- "+mathDecoExample("sout")+"$"); ui->cmbTestset->addItem("decoration: math", "$"+mathDecoExample("vec")+" -- "+mathDecoExample("dot")+" -- "+mathDecoExample("ddot")+" -- "+mathDecoExample("ocirc")+" -- "+mathDecoExample("overline")+" -- "+mathDecoExample("underline")+" -- "+mathDecoExample("hat")+" -- "+mathDecoExample("widehat")+" -- "+mathDecoExample("check")+" -- "+mathDecoExample("widecheck")+" -- "+mathDecoExample("breve")+" -- "+mathDecoExample("tilde")+" -- "+mathDecoExample("widetilde")+" -- "+mathDecoExample("uul")+" -- "+mathDecoExample("ool")+" -- "+mathDecoExample("bar")+" -- "+mathDecoExample("arrow")+" -- "+mathDecoExample("cancel")+" -- "+mathDecoExample("bcancel")+" -- "+mathDecoExample("xcancel")+" -- "+mathDecoExample("sout")+"$");
ui->cmbTestset->addItem("decoration: text", "Text \\ul{underlined Text Equator} -- \\ol{overlined Text Equator} -- \\sout{striked out Text Equator} -- \\cancel{canceled out Text Equator} -- \\bcancel{b-canceled out Text Equator} -- \\xcancel{x-canceled out Text Equator}"); ui->cmbTestset->addItem("decoration: text", "Text \\ul{underlined Text Equator} -- \\ol{overlined Text Equator} -- \\sout{striked out Text Equator} -- \\cancel{canceled out Text Equator} -- \\bcancel{b-canceled out Text Equator} -- \\xcancel{x-canceled out Text Equator}");
ui->cmbTestset->addItem("mathtest", "This is normal text: $this is math:\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle\\ \\ \\ g(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1} \\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\left\\{\\va\\left|\\|\\va\\|_2\\geq2\\right.\\right\\} \\vr\\vR\\frac{\\sqrt{\\sqrt{\\sqrt{\\sum_{i=0}^\\infty \\hat{i}^2}+y^\\alpha}+1}}{\\dot{v}\\equiv\\ddot{r}}\\argmin_{\\vec{k}}\\sum_{\\sqrt{i}=0}^{N}\\int_{x_0}^{x_1}\\left(\\left(\\left(x\\right)\\right)\\right)\\underbrace{\\left[\\left\\{\\frac{\\partial f}{\\partial x}\\right\\}\\cdot\\frac{1}{2}\\right]}{\\text{underbraced text \\hbar}}\\cdots\\frac{\\sqrt{\\sum_{i=0}^2 \\hat{i}^2}+y^\\alpha}{\\dot{v}\\equiv\\ddot{r}}, \\hat{t}\\hat{T} \\overbrace{\\left|\\sqrt{x\\cdot Y}\\right|}{\\propto\\bbN\\circ\\bbZ} \\left<\\arrow{x(\\tau)}\\cdot\\vec{R}(t+\\bar{\\tau})\\right> \\alpha\\beta\\gamma\\delta\\epsilon\\Gamma\\Delta\\Theta\\Omega \\left\\_\\left~\\cbrt{\\hbar\\omega}\\right~\\right\\_$"); ui->cmbTestset->addItem("mathtest", "This is normal text: $this is math:\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle\\ \\ \\ g(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1} \\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\left\\{\\vec{a}\\left|\\|\\vec{a}\\|_2\\geq2\\right.\\right\\} \\vec{r}\\vec{R}\\frac{\\sqrt{\\sqrt{\\sqrt{\\sum_{i=0}^\\infty \\hat{i}^2}+y^\\alpha}+1}}{\\dot{v}\\equiv\\ddot{r}}\\argmin_{\\vec{k}}\\sum_{\\sqrt{i}=0}^{N}\\int_{x_0}^{x_1}\\left(\\left(\\left(x\\right)\\right)\\right)\\underbrace{\\left[\\left\\{\\frac{\\partial f}{\\partial x}\\right\\}\\cdot\\frac{1}{2}\\right]}{\\text{underbraced text \\hbar}}\\cdots\\frac{\\sqrt{\\sum_{i=0}^2 \\hat{i}^2}+y^\\alpha}{\\dot{v}\\equiv\\ddot{r}}, \\hat{t}\\hat{T} \\overbrace{\\left|\\sqrt{x\\cdot Y}\\right|}{\\propto\\bbN\\circ\\bbZ} \\left<\\arrow{x(\\tau)}\\cdot\\vec{R}(t+\\bar{\\tau})\\right> \\alpha\\beta\\gamma\\delta\\epsilon\\Gamma\\Delta\\Theta\\Omega \\left\\_\\left~\\cbrt{\\hbar\\omega}\\right~\\right\\_$");
ui->cmbTestset->addItem("math: upper/lower parantheses test:", "$\\text{bblabla} \\frac{1}{2}\\cdot\\left(\\frac{1}{\\mathrm{e}^x+\\mathrm{e}^{-x}}\\right)\\cdot\\left(\\frac{1}{\\frac{1+2}{5+x}}\\right)\\cdot\\left(\\frac{1}{\\exp\\left[-\\frac{y^2}{\\sqrt{x}}\\right]\\cdot\\exp\\left[-\\frac{1}{\\frac{1}{2}}\\right]}\\right) $"); ui->cmbTestset->addItem("math: upper/lower parantheses test:", "$\\text{bblabla} \\frac{1}{2}\\cdot\\left(\\frac{1}{\\mathrm{e}^x+\\mathrm{e}^{-x}}\\right)\\cdot\\left(\\frac{1}{\\frac{1+2}{5+x}}\\right)\\cdot\\left(\\frac{1}{\\exp\\left[-\\frac{y^2}{\\sqrt{x}}\\right]\\cdot\\exp\\left[-\\frac{1}{\\frac{1}{2}}\\right]}\\right) $");
ui->cmbTestset->addItem("math: ACF test", "$g_{rg}^{ab}(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-\\frac{1}{2}}$"); ui->cmbTestset->addItem("math: ACF test", "$g_{rg}^{ab}(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-\\frac{1}{2}}$");
ui->cmbTestset->addItem("math: MSD test", "$\\mathrm{MSD}(\\tau)\\equiv\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle=2n\\cdot\\frac{K_\\alpha}{\\Gamma(1+\\alpha)}\\cdot\\tau^\\alpha$"); ui->cmbTestset->addItem("math: MSD test", "$\\mathrm{MSD}(\\tau)\\equiv\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle=2n\\cdot\\frac{K_\\alpha}{\\Gamma(1+\\alpha)}\\cdot\\tau^\\alpha$");
@ -92,11 +92,11 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("text: non-2 radicals", "\\sqrt[3]{a}\\sqrt[3]{5}\\sqrt[3]{-1}\\sqrt[3]{h}\\sqrt[3]{\\vec{A}}\\sqrt[3]{\\frac{1}{a}}\\frac{\\sqrt[3]{a}}{\\sqrt[3]{a}}\\sqrt[3]{\\frac{1}{1+\\frac{1}{a}}}\\frac{1}{\\sqrt[3]{1+\\frac{1}{a}}}\\sqrt[3]{a+\\sqrt[3]{a+b}}"); ui->cmbTestset->addItem("text: non-2 radicals", "\\sqrt[3]{a}\\sqrt[3]{5}\\sqrt[3]{-1}\\sqrt[3]{h}\\sqrt[3]{\\vec{A}}\\sqrt[3]{\\frac{1}{a}}\\frac{\\sqrt[3]{a}}{\\sqrt[3]{a}}\\sqrt[3]{\\frac{1}{1+\\frac{1}{a}}}\\frac{1}{\\sqrt[3]{1+\\frac{1}{a}}}\\sqrt[3]{a+\\sqrt[3]{a+b}}");
ui->cmbTestset->addItem("math: long non-2 radicals", "$\\sqrt[3.14156]{a}\\sqrt[3.14156]{5}$"); ui->cmbTestset->addItem("math: long non-2 radicals", "$\\sqrt[3.14156]{a}\\sqrt[3.14156]{5}$");
ui->cmbTestset->addItem("text: long non-2 radicals", "\\sqrt[3.14156]{a}\\sqrt[3.14156]{5}"); ui->cmbTestset->addItem("text: long non-2 radicals", "\\sqrt[3.14156]{a}\\sqrt[3.14156]{5}");
ui->cmbTestset->addItem("math: sum, prod, ...", "no-limits: $\\prod_{i=1}^n \\sum_{j=1}^c (i + j)\\cdot\\frac{1}{2}$\\ \\ \\ --\\ \\ \\ limits: $\\prod\\limits_{i=1}^n \\sum\\limits_{j=1}^c (i + j)\\cdot\\frac{1}{2}$\\ \\ \\ --\\ \\ \\ long-below: $\\sum_{n=\\{a,b,c,d,e,f,g\\}} f(x)$\\ \\ \\ --\\ \\ \\ long-above: $\\sum^{n=\\{a,b,c,d,e,f,g\\}} f(x)$"); ui->cmbTestset->addItem("math: sum, prod, ... bare/+\\nolimits", "no-limits: $\\prod\\nolimits_{i=1}^n \\sum\\nolimits_{j=1}^c (i + j)\\cdot\\frac{1}{2}$\\ \\ \\ --\\ \\ \\ bare: $\\prod_{i=1}^n \\sum_{j=1}^c (i + j)\\cdot\\frac{1}{2}$\\ \\ \\ --\\ \\ \\ long-below, bare: $\\sum_{n=\\{a,b,c,d,e,f,g\\}} f(x)$\\ \\ \\ --\\ \\ \\ long-above, bare: $\\sum^{n=\\{a,b,c,d,e,f,g\\}} f(x)$");
ui->cmbTestset->addItem("text: sum, prod, ...", "no-limits: \\prod_{i=1}^n \\sum_{j=1}^c (i + j)\\cdot\\frac{1}{2}\\ \\ \\ --\\ \\ \\ limits: \\prod\\limits_{i=1}^n \\sum\\limits_{j=1}^c (i + j)\\cdot\\frac{1}{2}\\ \\ \\ --\\ \\ \\ long-below: \\sum_{n=\\{a,b,c,d,e,f,g\\}} f(x)\\ \\ \\ --\\ \\ \\ long-above: \\sum^{n=\\{a,b,c,d,e,f,g\\}} f(x)"); ui->cmbTestset->addItem("text: sum, prod, ... bare/+\\limits", "bare: \\prod_{i=1}^n \\sum_{j=1}^c (i + j)\\cdot\\frac{1}{2}\\ \\ \\ --\\ \\ \\ limits: \\prod\\limits_{i=1}^n \\sum\\limits_{j=1}^c (i + j)\\cdot\\frac{1}{2}\\ \\ \\ --\\ \\ \\ long-below, bare: \\sum_{n=\\{a,b,c,d,e,f,g\\}} f(x)\\ \\ \\ --\\ \\ \\ long-above, bare: \\sum^{n=\\{a,b,c,d,e,f,g\\}} f(x)");
ui->cmbTestset->addItem("math: more sum-symbols ", "$\\sum_{i=0}^N\\prod_{i=0}^N\\coprod_{i=0}^N\\bigcup_{i=0}^N\\bigcap_{i=0}^N\\bigsqcup_{i=0}^N\\bigvee_{i=0}^N\\bigwedge_{i=0}^N\\bigoplus_{i=0}^N\\bigotimes_{i=0}^N\\bigodot_{i=0}^N\\biguplus_{i=0}^N$"); ui->cmbTestset->addItem("math: more sum-symbols ", "$\\sum\\limits_{i=0}^N\\prod\\limits_{i=0}^N\\coprod\\limits_{i=0}^N\\bigcup\\limits_{i=0}^N\\bigcap\\limits_{i=0}^N\\bigsqcup\\limits_{i=0}^N\\bigvee\\limits_{i=0}^N\\bigwedge\\limits_{i=0}^N\\bigoplus\\limits_{i=0}^N\\bigotimes\\limits_{i=0}^N\\bigodot\\limits_{i=0}^N\\biguplus\\limits_{i=0}^N$");
ui->cmbTestset->addItem("math: integrals", "no-limits: $\\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$"); ui->cmbTestset->addItem("math: integrals+sums, bare/+\\nolimits", "bare: $\\int_{0}^1 f(x)\\;\\mathrm{d}x\\ \\sum_{x=0}^1f(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$\\ \\ \\ --\\ \\ \\ nolimits: $\\int\\nolimits_{0}^1 f(x)\\;\\mathrm{d}x\\ \\sum\\nolimits_{x=0}^1f(x)\\ \\iint\\nolimits_{0}^1 f(x)\\;\\mathrm{d}x\\ \\iiint\\nolimits_{0}^1 f(x)\\;\\mathrm{d}x\\ \\oint\\nolimits_{0}^1 f(x)\\;\\mathrm{d}x\\ \\int\\nolimits_{x} f(x)\\;\\mathrm{d}x$");
ui->cmbTestset->addItem("text: integrals", "no-limits: \\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"); ui->cmbTestset->addItem("text: integrals+sums, bare/+\\limits", "bare: \\int_{0}^1 f(x)\\;\\mathrm{d}x\\ \\sum_{x=0}^1f(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\\ \\sum\\limits_{x=0}^1f(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");
ui->cmbTestset->addItem("math: frac test", "$\\frac{a}{b}+\\frac{g}{a}-\\frac{a^2}{b^2}\\cdot\\frac{a^2}{b^{\\frac{1}{2}}}$"); ui->cmbTestset->addItem("math: frac test", "$\\frac{a}{b}+\\frac{g}{a}-\\frac{a^2}{b^2}\\cdot\\frac{a^2}{b^{\\frac{1}{2}}}$");
ui->cmbTestset->addItem("math/text: stacked frac", "math: $\\frac{1+\\frac{a}{b}}{1+\\frac{1}{1+\\frac{1}{a}}}$\\ \\ text: \\frac{1+\\frac{a}{b}}{1+\\frac{1}{1+\\frac{1}{a}}}\\ \\ \\ \\ \\ --\\ \\ \\ \\ \\ math: $a_0+\\cfrac{1}{a_1+\\cfrac{1}{a_2+\\cfrac{1}{a_3+\\cdots}}}$\\ \\ text: a_0+\\cfrac{1}{a_1+\\cfrac{1}{a_2+\\cfrac{1}{a_3+\\cdots}}}"); ui->cmbTestset->addItem("math/text: stacked frac", "math: $\\frac{1+\\frac{a}{b}}{1+\\frac{1}{1+\\frac{1}{a}}}$\\ \\ text: \\frac{1+\\frac{a}{b}}{1+\\frac{1}{1+\\frac{1}{a}}}\\ \\ \\ \\ \\ --\\ \\ \\ \\ \\ math: $a_0+\\cfrac{1}{a_1+\\cfrac{1}{a_2+\\cfrac{1}{a_3+\\cdots}}}$\\ \\ text: a_0+\\cfrac{1}{a_1+\\cfrac{1}{a_2+\\cfrac{1}{a_3+\\cdots}}}");
ui->cmbTestset->addItem("math: tfrac test", "$\\tfrac{a}{b}+\\tfrac{g}{a}-\\tfrac{a^2}{b^2}\\cdot\\tfrac{a^2}{b^{\\tfrac{1}{2}}}$"); ui->cmbTestset->addItem("math: tfrac test", "$\\tfrac{a}{b}+\\tfrac{g}{a}-\\tfrac{a^2}{b^2}\\cdot\\tfrac{a^2}{b^{\\tfrac{1}{2}}}$");
@ -217,7 +217,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->setCurrentIndex(0); ui->cmbTestset->setCurrentIndex(0);
ui->labMath->setMath("\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)"); ui->labMath->setMath("$\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)$");
ui->cmbFont->setCurrentIndex(1); ui->cmbFont->setCurrentIndex(1);
connect(ui->chkBoxes, SIGNAL(toggled(bool)), this, SLOT(updateMath())); connect(ui->chkBoxes, SIGNAL(toggled(bool)), this, SLOT(updateMath()));
@ -268,7 +268,7 @@ TestForm::~TestForm()
double TestForm::draw(QPainter& painter, double X, double YY, JKQTMathText& mt, QString name, double& durationSizingMS, double&durationTimingMS) { double TestForm::draw(QPainter& painter, double X, double YY, JKQTMathText& mt, QString name, double& durationSizingMS, double&durationTimingMS, QStringList* lstErrors) {
double Y=YY; double Y=YY;
@ -298,6 +298,7 @@ double TestForm::draw(QPainter& painter, double X, double YY, JKQTMathText& mt,
qDebug()<<" drawing in "<<durationTimingMS<<" ms"; qDebug()<<" drawing in "<<durationTimingMS<<" ms";
p.setColor("blue"); p.setColor("blue");
painter.setPen(p); painter.setPen(p);
if (lstErrors) *lstErrors=mt.getErrorList();
QFont f; QFont f;
f.setFamily("sans serif"); f.setFamily("sans serif");
@ -364,7 +365,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
name=QString("MTsubscriptNode"); name=QString("MTsubscriptNode");
if (subN->getChild()) ti->addChild(createTree(subN->getChild(), ti)); if (subN->getChild()) ti->addChild(createTree(subN->getChild(), ti));
} else if (inst1N) { } else if (inst1N) {
name=QString("MTinstruction1Node: \'%1\'").arg(inst1N->getName()); name=QString("MTinstruction1Node: \'%1\' (subsuper=%2").arg(inst1N->getName()).arg(inst1N->isSubSuperscriptAboveBelowNode());
if (inst1N->getChild()) ti->addChild(createTree(inst1N->getChild(), ti)); if (inst1N->getChild()) ti->addChild(createTree(inst1N->getChild(), ti));
} else if (lstN) { } else if (lstN) {
name=QString("MTlistNode"); name=QString("MTlistNode");
@ -373,7 +374,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
ti->addChild(createTree(list[i], ti)); ti->addChild(createTree(list[i], ti));
} }
} else if (symN) { } else if (symN) {
name=QString("MTSymbolNode: \'%1\' (addWhite: %2)").arg(symN->getSymbolName()).arg(symN->getAddWhitespace()); name=QString("MTSymbolNode: \'%1\' (addWhite: %2, subsuper=%3)").arg(symN->getSymbolName()).arg(symN->getAddWhitespace()).arg(symN->isSubSuperscriptAboveBelowNode());
} else if (spN) { } else if (spN) {
name=QString("MTWhitespaceNode :\'%1\'").arg(txtN->getText()); name=QString("MTWhitespaceNode :\'%1\'").arg(txtN->getText());
} else if (txtN) { } else if (txtN) {
@ -445,24 +446,36 @@ void TestForm::updateMath()
ht.start(); ht.start();
if (ui->cmbFont->currentIndex()<=3) {
mt.setFontRoman(ui->cmbUnicodeSerif->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSerif->currentIndex()));
mt.setFontSans(ui->cmbUnicodeSans->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSans->currentIndex()));
mt.setFontMathRoman(ui->cmbUnicodeSerifMath->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSerifMath->currentIndex()));
mt.setFontMathSans(ui->cmbUnicodeSansMath->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSansMath->currentIndex()));
mt.setFontTypewriter(ui->cmbUnicodeFixed->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingTypewriter->currentIndex()));
mt.setFontCaligraphic(ui->cmbCaligraphic->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingCaligraphic->currentIndex()));
mt.setFontScript(ui->cmbScript->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingScript->currentIndex()));
mt.setFontFraktur(ui->cmbUnicodeFraktur->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingFraktur->currentIndex()));
mt.setFontBlackboard(ui->cmbUnicodeBlackboard->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingBlackboard->currentIndex()));
mt.setSymbolfontSymbol(ui->cmbUnicodeSymbol->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSymbol->currentIndex()));
mt.setSymbolfontGreek(ui->cmbUnicodeGreek->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingGreek->currentIndex()));
} else if (ui->cmbFont->currentIndex()==5 || ui->cmbFont->currentIndex()==6) {
mt.setFontRoman(QGuiApplication::font().family());
} else if (ui->cmbFont->currentIndex()==7) {
mt.useAnyUnicode("Times New Roman", "Times New Roman");
} else if (ui->cmbFont->currentIndex()==8) {
mt.useAnyUnicode("Arial", "Arial");
} else if (ui->cmbFont->currentIndex()==9) {
mt.useAnyUnicode("Courier New", "Courier New");
} else if (ui->cmbFont->currentIndex()==10) {
mt.useAnyUnicode("Comic Sans MS", "Comic Sans MS");
}
mt.setFontRoman(ui->cmbUnicodeSerif->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSerif->currentIndex()));
mt.setFontSans(ui->cmbUnicodeSans->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSans->currentIndex()));
mt.setFontMathRoman(ui->cmbUnicodeSerifMath->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSerifMath->currentIndex()));
mt.setFontMathSans(ui->cmbUnicodeSansMath->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSansMath->currentIndex()));
mt.setFontTypewriter(ui->cmbUnicodeFixed->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingTypewriter->currentIndex()));
mt.setFontCaligraphic(ui->cmbCaligraphic->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingCaligraphic->currentIndex()));
mt.setFontScript(ui->cmbScript->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingScript->currentIndex()));
mt.setFontFraktur(ui->cmbUnicodeFraktur->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingFraktur->currentIndex()));
mt.setFontBlackboard(ui->cmbUnicodeBlackboard->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingBlackboard->currentIndex()));
mt.setSymbolfontSymbol(ui->cmbUnicodeSymbol->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingSymbol->currentIndex()));
mt.setSymbolfontGreek(ui->cmbUnicodeGreek->currentFont().family(), static_cast<JKQTMathTextFontEncoding>(ui->cmbEncodingGreek->currentIndex()));
mt.setFontBlackboardSimulated(ui->chkSimulateBlackboard->isChecked()); mt.setFontBlackboardSimulated(ui->chkSimulateBlackboard->isChecked());
if (ui->cmbFont->currentIndex()==1) qDebug()<<"useXITS: "<<mt.useXITS(); if (ui->cmbFont->currentIndex()==1) qDebug()<<"useXITS: "<<mt.useXITS();
else if (ui->cmbFont->currentIndex()==2) qDebug()<<"useSTIX: "<<mt.useSTIX(); else if (ui->cmbFont->currentIndex()==2) qDebug()<<"useSTIX: "<<mt.useSTIX();
else if (ui->cmbFont->currentIndex()==3) qDebug()<<"useASANA: "<<mt.useASANA(); else if (ui->cmbFont->currentIndex()==3) qDebug()<<"useASANA: "<<mt.useASANA();
else if (ui->cmbFont->currentIndex()==6) qDebug()<<"useXITS: "<<mt.useXITS();
ui->tree->clear(); ui->tree->clear();
ht.start(); ht.start();
double durationParse=0; double durationParse=0;
@ -490,18 +503,21 @@ void TestForm::updateMath()
Y+=draw(painter, X1, Y, mt, QString("%1, %2, %3pt").arg(ui->cmbTestset->currentText()).arg(ui->cmbFont->currentText()).arg(size), durationSizingMS, durationTimingMS); Y+=draw(painter, X1, Y, mt, QString("%1, %2, %3pt").arg(ui->cmbTestset->currentText()).arg(ui->cmbFont->currentText()).arg(size), durationSizingMS, durationTimingMS);
if (i==0) { if (i==0) {
ui->labError->clear();
if (mt.getErrorList().size()>0) { if (mt.getErrorList().size()>0) {
ui->labError->setText("<span color=\"red\">"+mt.getErrorList().join("<br>")+"</span>"); ui->labError->setHtml("<span color=\"red\">"+mt.getErrorList().join("<br>")+"</span>");
} else { } else {
ui->labError->setText("<span color=\"green\">OK</span>"); ui->labError->setHtml("<span color=\"green\">OK</span>");
} }
} }
ui->labRenderTimes->setText(ui->labRenderTimes->text()+QString(" %1pt: %2ms/%3ms").arg(size).arg(durationSizingMS, 0, 'F', 1).arg(durationTimingMS, 0, 'F', 1)); ui->labRenderTimes->setText(ui->labRenderTimes->text()+QString(" %1pt: %2ms/%3ms").arg(size).arg(durationSizingMS, 0, 'F', 1).arg(durationTimingMS, 0, 'F', 1));
ui->textBrowser->textCursor().insertHtml("<hr>"+mt.toHtml(&okh)+"<hr><br><br>"); if (i==0) {
qDebug()<<"HTML: ---------------------------------------------\n"<<mt.toHtml(&okh)<<"\nHTML: --------------------------------------------- ok="<<okh; ui->textBrowser->textCursor().insertHtml("<hr>"+mt.toHtml(&okh)+"<hr><br><br>");
if (mt.getErrorList().size()>0) { qDebug()<<"HTML: ---------------------------------------------\n"<<mt.toHtml(&okh)<<"\nHTML: --------------------------------------------- ok="<<okh;
qDebug()<<mt.getErrorList().join("\n")<<"\n"; if (mt.getErrorList().size()>0) {
qDebug()<<mt.getErrorList().join("\n")<<"\n";
}
} }
} }

View File

@ -27,7 +27,7 @@ class TestForm : public QWidget
private: private:
Ui::TestForm *ui; Ui::TestForm *ui;
JKQTPHighResTimer ht; JKQTPHighResTimer ht;
double draw(QPainter& painter, double X, double YY, JKQTMathText& mt, QString name, double &durationSizingMS, double &durationTimingMS); double draw(QPainter& painter, double X, double YY, JKQTMathText& mt, QString name, double &durationSizingMS, double &durationTimingMS, QStringList *lstErrors=nullptr);
QTreeWidgetItem* createTree(JKQTMathTextNode* node, QTreeWidgetItem *parent=NULL); QTreeWidgetItem* createTree(JKQTMathTextNode* node, QTreeWidgetItem *parent=NULL);
}; };

View File

@ -14,174 +14,18 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="4" column="0" rowspan="11"> <item row="7" column="1">
<widget class="QScrollArea" name="scrollArea"> <widget class="QLabel" name="label_9">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>748</width>
<height>538</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="label_12">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>render times (getSize()+getAscent()/draw()):</string> <string>HTML output:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,2,0,2,0,0,1,0,0,0,0,0">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>testset:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbTestset">
<property name="currentIndex">
<number>-1</number>
</property>
<property name="maxVisibleItems">
<number>30</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>fonts:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbFont">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Below</string>
</property>
</item>
<item>
<property name="text">
<string>Below+Math: XITS</string>
</property>
</item>
<item>
<property name="text">
<string>Below+Math: STIX</string>
</property>
</item>
<item>
<property name="text">
<string>Below+Math: ASANA</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>size:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edtSizes">
<property name="text">
<string>90,30,20,10</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkBoxes">
<property name="text">
<string>boxes</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAntiAlias">
<property name="text">
<string>anti-aliase</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAntiAliasHQ">
<property name="text">
<string>HQ anti-aliase</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAntiAliasText">
<property name="text">
<string>Text anti-aliase</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkSmoothTransform">
<property name="text">
<string>smooth transform</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="15" column="0" colspan="2"> <item row="15" column="0" colspan="2">
<widget class="JKQTMathTextLabel" name="labMath"> <widget class="JKQTMathTextLabel" name="labMath">
<property name="text"> <property name="text">
@ -195,7 +39,6 @@
<widget class="QLabel" name="label_8"> <widget class="QLabel" name="label_8">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
@ -229,18 +72,10 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="4" column="1" rowspan="2">
<widget class="QPlainTextEdit" name="textBrowserSource">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_11"> <widget class="QLabel" name="label_11">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
@ -249,16 +84,61 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="13" column="1">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_10">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>HTML output:</string> <string>node tree:</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QTextBrowser" name="textBrowser"/>
</item>
<item row="4" column="0" rowspan="11">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>752</width>
<height>552</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="labRenderTimes">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="labParsingTimes">
<property name="text">
<string/>
</property> </property>
</widget> </widget>
</item> </item>
@ -301,18 +181,14 @@
<item row="0" column="2"> <item row="0" column="2">
<widget class="QFontComboBox" name="cmbUnicodeSerif"> <widget class="QFontComboBox" name="cmbUnicodeSerif">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Times New Roman</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="2" column="2">
<widget class="QFontComboBox" name="cmbUnicodeBlackboard"> <widget class="QFontComboBox" name="cmbUnicodeBlackboard">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Times New Roman</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -326,9 +202,7 @@
<item row="2" column="8"> <item row="2" column="8">
<widget class="QFontComboBox" name="cmbUnicodeSymbol"> <widget class="QFontComboBox" name="cmbUnicodeSymbol">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Symbol</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -447,18 +321,14 @@
<item row="0" column="8"> <item row="0" column="8">
<widget class="QFontComboBox" name="cmbUnicodeGreek"> <widget class="QFontComboBox" name="cmbUnicodeGreek">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Symbol</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="5"> <item row="0" column="5">
<widget class="QFontComboBox" name="cmbUnicodeSans"> <widget class="QFontComboBox" name="cmbUnicodeSans">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Arial</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -510,9 +380,7 @@
<item row="2" column="5"> <item row="2" column="5">
<widget class="QFontComboBox" name="cmbUnicodeFraktur"> <widget class="QFontComboBox" name="cmbUnicodeFraktur">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Times New Roman</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -553,9 +421,7 @@
<item row="3" column="5"> <item row="3" column="5">
<widget class="QFontComboBox" name="cmbCaligraphic"> <widget class="QFontComboBox" name="cmbCaligraphic">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Script</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -596,9 +462,7 @@
<item row="3" column="8"> <item row="3" column="8">
<widget class="QFontComboBox" name="cmbScript"> <widget class="QFontComboBox" name="cmbScript">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Script</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -639,9 +503,7 @@
<item row="1" column="8"> <item row="1" column="8">
<widget class="QFontComboBox" name="cmbUnicodeFixed"> <widget class="QFontComboBox" name="cmbUnicodeFixed">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Courier New</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -682,9 +544,7 @@
<item row="1" column="2"> <item row="1" column="2">
<widget class="QFontComboBox" name="cmbUnicodeSerifMath"> <widget class="QFontComboBox" name="cmbUnicodeSerifMath">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Times New Roman</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -725,9 +585,7 @@
<item row="1" column="5"> <item row="1" column="5">
<widget class="QFontComboBox" name="cmbUnicodeSansMath"> <widget class="QFontComboBox" name="cmbUnicodeSansMath">
<property name="currentFont"> <property name="currentFont">
<font> <font/>
<family>Arial</family>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -760,16 +618,18 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="12" column="1"> <item row="11" column="1">
<widget class="QLabel" name="labRenderTimes"> <widget class="QLabel" name="label_12">
<property name="font">
<font>
<bold>true</bold>
</font>
</property>
<property name="text"> <property name="text">
<string/> <string>render times (getSize()+getAscent()/draw()):</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1">
<widget class="QTextBrowser" name="textBrowser"/>
</item>
<item row="14" column="1"> <item row="14" column="1">
<widget class="QTreeWidget" name="tree"> <widget class="QTreeWidget" name="tree">
<property name="headerHidden"> <property name="headerHidden">
@ -782,24 +642,171 @@
</column> </column>
</widget> </widget>
</item> </item>
<item row="13" column="1"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_10"> <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,2,0,2,0,0,1,0,0,0,0,0">
<property name="font"> <item>
<font> <widget class="QLabel" name="label_3">
<weight>75</weight> <property name="text">
<bold>true</bold> <string>testset:</string>
</font> </property>
</property> </widget>
<property name="text"> </item>
<string>node tree:</string> <item>
</property> <widget class="QComboBox" name="cmbTestset">
</widget> <property name="currentIndex">
<number>-1</number>
</property>
<property name="maxVisibleItems">
<number>30</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>fonts:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbFont">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Below</string>
</property>
</item>
<item>
<property name="text">
<string>Below+Math: XITS</string>
</property>
</item>
<item>
<property name="text">
<string>Below+Math: STIX</string>
</property>
</item>
<item>
<property name="text">
<string>Below+Math: ASANA</string>
</property>
</item>
<item>
<property name="text">
<string>Default-Constructed</string>
</property>
</item>
<item>
<property name="text">
<string>Default-Constructed+SetAppFont</string>
</property>
</item>
<item>
<property name="text">
<string>Default-Constructed+SetAppFont+XITS</string>
</property>
</item>
<item>
<property name="text">
<string>useAnyUnicode(&quot;Times New Roman&quot;, &quot;Times New Roman&quot;)</string>
</property>
</item>
<item>
<property name="text">
<string>useAnyUnicode(&quot;Arial&quot;, &quot;Arial&quot;)</string>
</property>
</item>
<item>
<property name="text">
<string>useAnyUnicode(&quot;Courier New&quot;, &quot;Courier New&quot;)</string>
</property>
</item>
<item>
<property name="text">
<string>useAnyUnicode(&quot;Comic Sans MS&quot;, &quot;Comic Sans MS&quot;)</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>size:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edtSizes">
<property name="text">
<string>90,30,20,10</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkBoxes">
<property name="text">
<string>boxes</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAntiAlias">
<property name="text">
<string>anti-aliase</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAntiAliasHQ">
<property name="text">
<string>HQ anti-aliase</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAntiAliasText">
<property name="text">
<string>Text anti-aliase</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkSmoothTransform">
<property name="text">
<string>smooth transform</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item row="9" column="1"> <item row="9" column="1">
<widget class="QLabel" name="label_13"> <widget class="QLabel" name="label_13">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
@ -808,17 +815,32 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1"> <item row="4" column="1" rowspan="2">
<widget class="QLabel" name="labParsingTimes"> <widget class="QPlainTextEdit" name="textBrowserSource">
<property name="text"> <property name="readOnly">
<string/> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="6" column="1">
<widget class="QLabel" name="labError"> <widget class="QTextBrowser" name="labError">
<property name="text"> <property name="sizePolicy">
<string/> <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>48</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -62,9 +62,12 @@ JKQTMathText::JKQTMathText(QObject* parent):
fontSize=10; fontSize=10;
brace_factor=1.04; brace_factor=1.04;
subsuper_size_factor=0.7; subsuper_size_factor=0.7;
subsuper_mode_selection_by_size_factor=1.01;
italic_correction_factor=0.4; italic_correction_factor=0.4;
sub_shift_factor=0.4; sub_shift_factor=0.4;
super_shift_factor=0.6; super_shift_factor=0.7;
special_sub_shift_factor=0.4;
special_super_shift_factor=0.4;
brace_shrink_factor=0.6; brace_shrink_factor=0.6;
fontColor=QColor("black"); fontColor=QColor("black");
@ -77,7 +80,10 @@ JKQTMathText::JKQTMathText(QObject* parent):
decoration_width_reduction_Xfactor=0.2; decoration_width_reduction_Xfactor=0.2;
brace_y_shift_factor=0.7;//-1; brace_y_shift_factor=0.7;//-1;
operatorsubsuper_size_factor=0.65; operatorsubsuper_size_factor=0.65;
operatorsubsuper_distance_factor=0.25;
operatorsubsuper_extraspace_factor=0.5;
mathoperator_width_factor=1.5; mathoperator_width_factor=1.5;
bigmathoperator_font_factor=1.8;
blackboardSimulated=true; blackboardSimulated=true;
@ -200,9 +206,12 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group)
brace_factor=settings.value(group+"brace_factor", brace_factor).toDouble(); brace_factor=settings.value(group+"brace_factor", brace_factor).toDouble();
brace_shrink_factor=settings.value(group+"brace_shrink_factor", brace_shrink_factor).toDouble(); brace_shrink_factor=settings.value(group+"brace_shrink_factor", brace_shrink_factor).toDouble();
subsuper_size_factor=settings.value(group+"subsuper_size_factor", subsuper_size_factor).toDouble(); subsuper_size_factor=settings.value(group+"subsuper_size_factor", subsuper_size_factor).toDouble();
subsuper_mode_selection_by_size_factor=settings.value(group+"subsuper_mode_selection_by_size_factor", subsuper_mode_selection_by_size_factor).toDouble();
italic_correction_factor=settings.value(group+"italic_correction_factor", italic_correction_factor).toDouble(); italic_correction_factor=settings.value(group+"italic_correction_factor", italic_correction_factor).toDouble();
super_shift_factor=settings.value(group+"super_shift_factor", super_shift_factor).toDouble(); super_shift_factor=settings.value(group+"super_shift_factor", super_shift_factor).toDouble();
sub_shift_factor=settings.value(group+"sub_shift_factor", sub_shift_factor).toDouble(); sub_shift_factor=settings.value(group+"sub_shift_factor", sub_shift_factor).toDouble();
special_super_shift_factor=settings.value(group+"special_super_shift_factor", special_super_shift_factor).toDouble();
special_sub_shift_factor=settings.value(group+"special_sub_shift_factor", special_sub_shift_factor).toDouble();
frac_factor=settings.value(group+"frac_factor", frac_factor).toDouble(); frac_factor=settings.value(group+"frac_factor", frac_factor).toDouble();
frac_shift_factor=settings.value(group+"frac_shift_factor", frac_shift_factor).toDouble(); frac_shift_factor=settings.value(group+"frac_shift_factor", frac_shift_factor).toDouble();
underbrace_factor=settings.value(group+"underbrace_factor", underbrace_factor).toDouble(); underbrace_factor=settings.value(group+"underbrace_factor", underbrace_factor).toDouble();
@ -211,6 +220,8 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group)
decoration_height_factor=settings.value(group+"decoration_height_factor", decoration_height_factor).toDouble(); decoration_height_factor=settings.value(group+"decoration_height_factor", decoration_height_factor).toDouble();
decoration_width_reduction_Xfactor=settings.value(group+"decoration_width_reduction_xfactor", decoration_width_reduction_Xfactor).toDouble(); decoration_width_reduction_Xfactor=settings.value(group+"decoration_width_reduction_xfactor", decoration_width_reduction_Xfactor).toDouble();
operatorsubsuper_size_factor=settings.value(group+"operatorsubsuper_size_factor", operatorsubsuper_size_factor).toDouble(); operatorsubsuper_size_factor=settings.value(group+"operatorsubsuper_size_factor", operatorsubsuper_size_factor).toDouble();
operatorsubsuper_distance_factor=settings.value(group+"operatorsubsuper_distance_factor", operatorsubsuper_distance_factor).toDouble();
operatorsubsuper_extraspace_factor=settings.value(group+"operatorsubsuper_extraspace_factor", operatorsubsuper_extraspace_factor).toDouble();
mathoperator_width_factor=settings.value(group+"mathoperator_width_factor", mathoperator_width_factor).toDouble(); mathoperator_width_factor=settings.value(group+"mathoperator_width_factor", mathoperator_width_factor).toDouble();
@ -226,14 +237,19 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const
settings.setValue(group+ "brace_factor", brace_factor); settings.setValue(group+ "brace_factor", brace_factor);
settings.setValue(group+ "brace_shrink_factor", brace_shrink_factor); settings.setValue(group+ "brace_shrink_factor", brace_shrink_factor);
settings.setValue(group+ "subsuper_size_factor", subsuper_size_factor); settings.setValue(group+ "subsuper_size_factor", subsuper_size_factor);
settings.setValue(group+ "subsuper_mode_selection_by_size_factor", subsuper_mode_selection_by_size_factor);
settings.setValue(group+ "italic_correction_factor", italic_correction_factor); settings.setValue(group+ "italic_correction_factor", italic_correction_factor);
settings.setValue(group+ "sub_shift_factor", sub_shift_factor); settings.setValue(group+ "sub_shift_factor", sub_shift_factor);
settings.setValue(group+ "super_shift_factor", super_shift_factor); settings.setValue(group+ "super_shift_factor", super_shift_factor);
settings.setValue(group+ "special_sub_shift_factor", special_sub_shift_factor);
settings.setValue(group+ "special_super_shift_factor", special_super_shift_factor);
settings.setValue(group+ "frac_factor", frac_factor); settings.setValue(group+ "frac_factor", frac_factor);
settings.setValue(group+ "frac_shift_factor", frac_shift_factor); settings.setValue(group+ "frac_shift_factor", frac_shift_factor);
settings.setValue(group+ "underbrace_factor", underbrace_factor); settings.setValue(group+ "underbrace_factor", underbrace_factor);
settings.setValue(group+ "undersetFactor", underset_factor); settings.setValue(group+ "undersetFactor", underset_factor);
settings.setValue(group+ "operatorsubsuper_size_factor", operatorsubsuper_size_factor); settings.setValue(group+ "operatorsubsuper_size_factor", operatorsubsuper_size_factor);
settings.setValue(group+ "operatorsubsuper_distance_factor", operatorsubsuper_distance_factor);
settings.setValue(group+ "operatorsubsuper_extraspace_factor", operatorsubsuper_extraspace_factor);
settings.setValue(group+ "mathoperator_width_factor", mathoperator_width_factor); settings.setValue(group+ "mathoperator_width_factor", mathoperator_width_factor);
settings.setValue(group+ "brace_y_shift_factor", brace_y_shift_factor); settings.setValue(group+ "brace_y_shift_factor", brace_y_shift_factor);
settings.setValue(group+ "decoration_height_factor", decoration_height_factor); settings.setValue(group+ "decoration_height_factor", decoration_height_factor);
@ -358,10 +374,8 @@ void JKQTMathText::addReplacementFont(const QString &nonUseFont, const QString &
QPair<QString,JKQTMathTextFontEncoding> JKQTMathText::getReplacementFont(const QString &nonUseFont, const QString &defaultFont, JKQTMathTextFontEncoding defaultFontEncoding) const { QPair<QString,JKQTMathTextFontEncoding> JKQTMathText::getReplacementFont(const QString &nonUseFont, const QString &defaultFont, JKQTMathTextFontEncoding defaultFontEncoding) const {
QPair<QString,JKQTMathTextFontEncoding> res(defaultFont, defaultFontEncoding); QPair<QString,JKQTMathTextFontEncoding> res(defaultFont, defaultFontEncoding);
bool foundFont=false;
for (auto it=fontReplacements.begin(); it!=fontReplacements.end(); ++it) { for (auto it=fontReplacements.begin(); it!=fontReplacements.end(); ++it) {
if (it.key().toLower()==nonUseFont.toLower()) { if (it.key().toLower()==nonUseFont.toLower()) {
foundFont=true;
res.first=it.value(); res.first=it.value();
res.second=fontEncodingReplacements.value(res.first, res.second); res.second=fontEncodingReplacements.value(res.first, res.second);
return res; return res;
@ -639,6 +653,16 @@ double JKQTMathText::getSubsuperSizeFactor() const
return this->subsuper_size_factor; return this->subsuper_size_factor;
} }
void JKQTMathText::setSubsuperModeSelectionBySizeFactor(double __value)
{
subsuper_mode_selection_by_size_factor=__value;
}
double JKQTMathText::getSubsuperModeSelectionBySizeFactor() const
{
return subsuper_mode_selection_by_size_factor;
}
void JKQTMathText::setItalicCorrectionFactor(double __value) void JKQTMathText::setItalicCorrectionFactor(double __value)
{ {
this->italic_correction_factor = __value; this->italic_correction_factor = __value;
@ -659,6 +683,26 @@ double JKQTMathText::getOperatorsubsuperSizeFactor() const
return this->operatorsubsuper_size_factor; return this->operatorsubsuper_size_factor;
} }
void JKQTMathText::setOperatorsubsuperDistanceFactor(double __value)
{
this->operatorsubsuper_distance_factor = __value;
}
double JKQTMathText::getOperatorsubsuperDistanceFactor() const
{
return this->operatorsubsuper_distance_factor;
}
void JKQTMathText::setOperatorsubsuperExtraSpaceFactor(double __value)
{
operatorsubsuper_extraspace_factor=__value;
}
double JKQTMathText::getOperatorsubsuperExtraSpaceFactor() const
{
return operatorsubsuper_extraspace_factor;
}
void JKQTMathText::setMathoperatorWidthFactor(double __value) void JKQTMathText::setMathoperatorWidthFactor(double __value)
{ {
this->mathoperator_width_factor = __value; this->mathoperator_width_factor = __value;
@ -669,6 +713,16 @@ double JKQTMathText::getMathoperatorWidthFactor() const
return this->mathoperator_width_factor; return this->mathoperator_width_factor;
} }
void JKQTMathText::setBigMathoperatorFontFactor(double __value)
{
bigmathoperator_font_factor=__value;
}
double JKQTMathText::getBigMathoperatorFontFactor() const
{
return bigmathoperator_font_factor;
}
void JKQTMathText::setSuperShiftFactor(double __value) void JKQTMathText::setSuperShiftFactor(double __value)
{ {
this->super_shift_factor = __value; this->super_shift_factor = __value;
@ -689,6 +743,26 @@ double JKQTMathText::getSubShiftFactor() const
return this->sub_shift_factor; return this->sub_shift_factor;
} }
double JKQTMathText::getSpecialSuperShiftFactor() const
{
return special_super_shift_factor;
}
void JKQTMathText::setSpecialSuperShiftFactor(double __value)
{
special_super_shift_factor=__value;
}
void JKQTMathText::setSpecialSubShiftFactor(double __value)
{
special_sub_shift_factor=__value;
}
double JKQTMathText::getSpecialSubShiftFactor() const
{
return special_sub_shift_factor;
}
void JKQTMathText::setBraceShrinkFactor(double __value) void JKQTMathText::setBraceShrinkFactor(double __value)
{ {
this->brace_shrink_factor = __value; this->brace_shrink_factor = __value;
@ -1174,6 +1248,17 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
nl->addChild(new JKQTMathTextInstruction1Node(this, currentInstructionName, parseLatexString(true))); nl->addChild(new JKQTMathTextInstruction1Node(this, currentInstructionName, parseLatexString(true)));
} }
} }
if (getNew) getToken();
if (currentToken==MTTinstruction && currentTokenName=="limits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
getNew=true;
} else if (currentToken==MTTinstruction && currentTokenName=="nolimits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
getNew=true;
} else {
getNew=false;
}
} else if (currentToken==MTTopenbracket && currentInstructionName!="left") { } else if (currentToken==MTTopenbracket && currentInstructionName!="left") {
//std::cout<<"found '[' after '"<<name.toStdString()<<"'\n"; //std::cout<<"found '[' after '"<<name.toStdString()<<"'\n";
if (currentInstructionName=="sqrt") { if (currentInstructionName=="sqrt") {
@ -1201,6 +1286,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
nl->addChild(new JKQTMathTextTextNode(this, "[", false)); nl->addChild(new JKQTMathTextTextNode(this, "[", false));
} }
} else { } else {
bool subSuperscriptAboveBelowNode=false;
//std::cout<<"did not find '{' after '"<<name.toStdString()<<"'\n"; //std::cout<<"did not find '{' after '"<<name.toStdString()<<"'\n";
if (currentInstructionName=="right") { if (currentInstructionName=="right") {
if (currentToken==MTTtext) { if (currentToken==MTTtext) {
@ -1257,32 +1343,23 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
} }
} else { } else {
//bool addWhite=(currentToken==MTTwhitespace); nl->addChild(new JKQTMathTextSymbolNode(this, currentInstructionName, false));
//getNew=addWhite;
getNew=false; static QSet<QString> subsupOperations= (QSet<QString>()<<"sum"<<"prod"<<"coprod"
bool done=false; <<"bigcap"<<"bigcup"<<"bigvee"<<"bighat"
if (currentInstructionName.size()==2) { <<"int"<<"iint"<<"iiint"<<"oint"<<"oiint"<<"oiiint"
QChar n0=currentInstructionName[0]; <<"mod"<<"median"<<"max"<<"min"<<"argmax"<<"argmin"<<"sup"<<"inf"
QChar n1=currentInstructionName[1]; <<"liminf"<<"limsup"<<"lim"<<"max"<<"min");
if (n0=='v' && n1.isLetter()) { if (subsupOperations.contains(currentInstructionName) && parsingMathEnvironment) {
done=true; nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
//std::cout<<"found \\v... command\n"; }
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDvec, new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); if (currentToken==MTTinstruction && currentTokenName=="limits") {
} else if (n0=='c' && n1.isLetter()) { if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
done=true; } else if (currentToken==MTTinstruction && currentTokenName=="nolimits") {
//std::cout<<"found \\v... command\n"; if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
nl->addChild(new JKQTMathTextInstruction1Node(this, "mathcal", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); } else {
} getNew=false;
} else if (currentInstructionName.size()==3) {
QString n0=currentInstructionName.left(2);
QChar n1=currentInstructionName[currentInstructionName.size()-1];
if (n0=="bb" && n1.isLetter()) {
done=true;
//std::cout<<"found \\v... command\n";
nl->addChild(new JKQTMathTextInstruction1Node(this, "mathbb", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment)));
}
} }
if (!done) nl->addChild(new JKQTMathTextSymbolNode(this, currentInstructionName, false));//, addWhite));
} }
} }
@ -1387,7 +1464,6 @@ bool JKQTMathText::parse(const QString& text, bool addSpaceBeforeAndAfter){
QString ntext; QString ntext;
if (addSpaceBeforeAndAfter) ntext=QString("\\;")+text+QString("\\;"); if (addSpaceBeforeAndAfter) ntext=QString("\\;")+text+QString("\\;");
else ntext=text; else ntext=text;
ntext=ntext.remove("\\limits");
if (parsedNode && parseString==ntext) return true; if (parsedNode && parseString==ntext) return true;

View File

@ -416,10 +416,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
* use generic Unicode fonts, e.g. "Arial" and "Times New Roman" in math-mode. * use generic Unicode fonts, e.g. "Arial" and "Times New Roman" in math-mode.
* You should use fonts that contain as many of the mathematical symbols as possible to ensure good rendering results. * You should use fonts that contain as many of the mathematical symbols as possible to ensure good rendering results.
* *
* <code>setAnyUnicode("Times New Roman", "Times New Roman")</code>:<br>\image html jkqtmathtext/jkqtmathparser_timesnewroman.png <br><br> * <code>useAnyUnicode("Times New Roman", "Times New Roman")</code>:<br>\image html jkqtmathtext/jkqtmathparser_timesnewroman.png <br><br>
* <code>setAnyUnicode("Arial", "Arial")</code>:<br>\image html jkqtmathtext/jkqtmathparser_arial.png <br><br> * <code>useAnyUnicode("Arial", "Arial")</code>:<br>\image html jkqtmathtext/jkqtmathparser_arial.png <br><br>
* <code>setAnyUnicode("Courier New", "Courier New")</code>:<br>\image html jkqtmathtext/jkqtmathparser_couriernew.png <br><br> * <code>useAnyUnicode("Courier New", "Courier New")</code>:<br>\image html jkqtmathtext/jkqtmathparser_couriernew.png <br><br>
* <code>setAnyUnicode("Comic Sans MS", "Comic Sans MS")</code>:<br>\image html jkqtmathtext/jkqtmathparser_comicsans.png <br><br> * <code>useAnyUnicode("Comic Sans MS", "Comic Sans MS")</code>:<br>\image html jkqtmathtext/jkqtmathparser_comicsans.png <br><br>
* *
*/ */
void useAnyUnicode(QString timesFont=QString(""), const QString& sansFont=QString(""), JKQTMathTextFontEncoding encodingTimes=JKQTMathTextFontEncoding::MTFEunicode, JKQTMathTextFontEncoding encodingSans=JKQTMathTextFontEncoding::MTFEunicode); void useAnyUnicode(QString timesFont=QString(""), const QString& sansFont=QString(""), JKQTMathTextFontEncoding encodingTimes=JKQTMathTextFontEncoding::MTFEunicode, JKQTMathTextFontEncoding encodingSans=JKQTMathTextFontEncoding::MTFEunicode);
@ -434,6 +434,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
void setSubsuperSizeFactor(double __value); void setSubsuperSizeFactor(double __value);
/** \copydoc subsuper_size_factor */ /** \copydoc subsuper_size_factor */
double getSubsuperSizeFactor() const; double getSubsuperSizeFactor() const;
/** \copydoc subsuper_mode_selection_by_size_factor */
void setSubsuperModeSelectionBySizeFactor(double __value);
/** \copydoc subsuper_mode_selection_by_size_factor */
double getSubsuperModeSelectionBySizeFactor() const;
/** \copydoc italic_correction_factor */ /** \copydoc italic_correction_factor */
void setItalicCorrectionFactor(double __value); void setItalicCorrectionFactor(double __value);
/** \copydoc italic_correction_factor */ /** \copydoc italic_correction_factor */
@ -442,10 +446,22 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
void setOperatorsubsuperSizeFactor(double __value); void setOperatorsubsuperSizeFactor(double __value);
/** \copydoc operatorsubsuper_size_factor */ /** \copydoc operatorsubsuper_size_factor */
double getOperatorsubsuperSizeFactor() const; double getOperatorsubsuperSizeFactor() const;
/** \copydoc operatorsubsuper_distance_factor */
void setOperatorsubsuperDistanceFactor(double __value);
/** \copydoc operatorsubsuper_distance_factor */
double getOperatorsubsuperDistanceFactor() const;
/** \copydoc operatorsubsuper_extraspace_factor */
void setOperatorsubsuperExtraSpaceFactor(double __value);
/** \copydoc operatorsubsuper_extraspace_factor */
double getOperatorsubsuperExtraSpaceFactor() const;
/** \copydoc mathoperator_width_factor */ /** \copydoc mathoperator_width_factor */
void setMathoperatorWidthFactor(double __value); void setMathoperatorWidthFactor(double __value);
/** \copydoc mathoperator_width_factor */ /** \copydoc mathoperator_width_factor */
double getMathoperatorWidthFactor() const; double getMathoperatorWidthFactor() const;
/** \copydoc bigmathoperator_font_factor */
void setBigMathoperatorFontFactor(double __value);
/** \copydoc bigmathoperator_font_factor */
double getBigMathoperatorFontFactor() const;
/** \copydoc super_shift_factor */ /** \copydoc super_shift_factor */
void setSuperShiftFactor(double __value); void setSuperShiftFactor(double __value);
/** \copydoc super_shift_factor */ /** \copydoc super_shift_factor */
@ -454,6 +470,14 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
void setSubShiftFactor(double __value); void setSubShiftFactor(double __value);
/** \copydoc sub_shift_factor */ /** \copydoc sub_shift_factor */
double getSubShiftFactor() const; double getSubShiftFactor() const;
/** \copydoc special_super_shift_factor */
void setSpecialSuperShiftFactor(double __value);
/** \copydoc special_super_shift_factor */
double getSpecialSuperShiftFactor() const;
/** \copydoc special_sub_shift_factor */
void setSpecialSubShiftFactor(double __value);
/** \copydoc special_sub_shift_factor */
double getSpecialSubShiftFactor() const;
/** \copydoc brace_shrink_factor */ /** \copydoc brace_shrink_factor */
void setBraceShrinkFactor(double __value); void setBraceShrinkFactor(double __value);
/** \copydoc brace_shrink_factor */ /** \copydoc brace_shrink_factor */
@ -529,10 +553,37 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
double brace_shrink_factor; double brace_shrink_factor;
/** \brief resizing factor for font size in sub-/superscript */ /** \brief resizing factor for font size in sub-/superscript */
double subsuper_size_factor; double subsuper_size_factor;
/** \brief this factor is used to determine how to typeset sub-/superscript.
*
* If the ascent for superscript of descent for subscript of the previous character is \c >=subsuper_mode_selection_by_size_factor*ascent(currentFont)
* or \c <=subsuper_mode_selection_by_size_factor*descent(currentFont) respectively, the sub/superscript is typeset, aligned with the ascent or descent
* of the previous character. Otherwise it is aligned with the default method:
*
* <b>Default mode:</b>
* \image html jkqtmathtext_superscriptnode_getSizeInternal.png
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png
*
* <b>Special mode:</b>
*
*
* This method fixes problems with characters that are significantyl larger that normal text character of the fonst, such as generated
* by \c \\sum,\\int,... .
*/
double subsuper_mode_selection_by_size_factor;
/** \brief fraction of a whitespace by which to shift a sub-/superscript left/right when the previous text is italic */ /** \brief fraction of a whitespace by which to shift a sub-/superscript left/right when the previous text is italic */
double italic_correction_factor; double italic_correction_factor;
/** \brief like subsuper_size_factor, but for operators (\C \\sum , \c \\int , ...) where the text is placed above/below the symbol */ /** \brief like subsuper_size_factor, but for operators (\c \\sum , \c \\int , ...) where the text is placed above/below the symbol */
double operatorsubsuper_size_factor; double operatorsubsuper_size_factor;
/** \brief for operators (\c \\sum , \c \\int , ...) where the text is placed above/below the symbol, this is the distance between the operator symbol and the sub-/super-text if multiplied by xHeight
*
* \image html jkqtmathtext_subsuper_with_limits.png
*/
double operatorsubsuper_distance_factor;
/** \brief for operators (\c \\sum , \c \\int , ...) where the text is placed above/below the symbol, this is the additional width added to the width of maximum width of the operator, above and below
*
* \image html jkqtmathtext_subsuper_with_limits.png
*/
double operatorsubsuper_extraspace_factor;
/** \brief factor, used to extend the size of an operator in math mode /** \brief factor, used to extend the size of an operator in math mode
* *
* The next image demonstrates the effect of this property, which adds extra space * The next image demonstrates the effect of this property, which adds extra space
@ -541,6 +592,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
* \image html jkqtmathparser_mathoperator_width_factor.png * \image html jkqtmathparser_mathoperator_width_factor.png
*/ */
double mathoperator_width_factor; double mathoperator_width_factor;
/** \brief factor, used to increase the font size for big math operators, such as \c \\sum , \c \\prod , ...
*
*/
double bigmathoperator_font_factor;
/** \brief relative shift of text in superscript to normal text: /** \brief relative shift of text in superscript to normal text:
* 0= baseline kept, 1: baseline shifted to top of normal text * 0= baseline kept, 1: baseline shifted to top of normal text
* *
@ -553,6 +608,18 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png * \image html jkqtmathtext_subscriptnode_getSizeInternal.png
*/ */
double sub_shift_factor; double sub_shift_factor;
/** \brief relative shift of text in superscript to normal text in special superscript mode (after large previous nodes):
* 0= superscript descent coincides with the previous node's baselineHeight, 1: top of previous node and top of the superscript nodes coincide
*
* \image html jkqtmathtext_specialsuperscriptnode_getSizeInternal.png
*/
double special_super_shift_factor;
/** \brief relative shift of text in subscript to normal text in special superscript mode (after large previous nodes):
* 0=child's baseline at the descent of the previous node, 1: subscript-node starts at the descent of the previous node
*
* \image html jkqtmathtext_specialsubscriptnode_getSizeInternal.png
*/
double special_sub_shift_factor;
/** \brief scaling factor for font size of nominator and denominator of a fraction /** \brief scaling factor for font size of nominator and denominator of a fraction

View File

@ -36,12 +36,6 @@
#include <QFont> #include <QFont>
QSet<QString> JKQTMathTextListNode::subsupOperations= (QSet<QString>()<<"sum"<<"prod"<<"coprod"
<<"bigcap"<<"bigcup"<<"bigvee"<<"bighat"
<<"int"<<"iint"<<"iiint"<<"oint"<<"oiint"<<"oiiint"
<<"mod"<<"median"<<"max"<<"min"<<"argmax"<<"argmin"<<"sup"<<"inf"
<<"liminf"<<"limsup"<<"lim"<<"max"<<"min");
JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent): JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent):
JKQTMathTextMultiChildNode(_parent) JKQTMathTextMultiChildNode(_parent)
{ {
@ -50,7 +44,7 @@ JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent):
} }
JKQTMathTextListNode::~JKQTMathTextListNode() { JKQTMathTextListNode::~JKQTMathTextListNode() {
clearChildren(true); clearChildrenImpl(true);
} }
QString JKQTMathTextListNode::getTypeName() const QString JKQTMathTextListNode::getTypeName() const
@ -63,7 +57,12 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
overallHeight=0; overallHeight=0;
baselineHeight=0; baselineHeight=0;
strikeoutPos=0; strikeoutPos=0;
QFontMetricsF fm(currentEv.getFont(parentMathText)); const QFontMetricsF fm(currentEv.getFont(parentMathText));
const double subsupershift=fm.xHeight()*parentMathText->getOperatorsubsuperDistanceFactor();
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double spaceWidth=fm.boundingRect(' ').width();
//QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); //QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
@ -71,23 +70,30 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
bool wasBrace=false; bool wasBrace=false;
for (int i=0; i<nodes.size(); i++) { for (int i=0; i<nodes.size(); i++) {
JKQTMathTextNodeSize prevNodeSize; JKQTMathTextNodeSize prevNodeSize;
JKQTMathTextNodeSize* prevNodeSizePtr=nullptr; JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr;
if (i>0 && wasBrace) { if (i>0) {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos);
prevNodeSizePtr=&prevNodeSize; const double prevAscent=prevNodeSize.baselineHeight;
const double prevDescent=prevNodeSize.overallHeight-prevNodeSize.baselineHeight;
const bool shouldUseSpecialSubscriptMode=prevAscent>=subsuperSpecialModeAscent;
const bool shouldUseSpecialSuperscriptMode=prevDescent>=subsuperSpecialModeDecent;
if (shouldUseSpecialSubscriptMode) prevNodeSizePtrForSubscript=&prevNodeSize;
if (shouldUseSpecialSuperscriptMode) prevNodeSizePtrForSuperscript=&prevNodeSize;
} }
JKQTMathTextSuperscriptNode* nodeI_SuperScript=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i]);
JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i]);
bool doDraw=true; bool doDraw=true;
JKQTMathTextSymbolNode* smb=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
// if we find a subscript/superscript node we check whether the next node is super/subscript // if we find a subscript/superscript node we check whether the next node is super/subscript
// if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly // if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly
if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i])) { if (nodeI_SuperScript) {
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1])) { // is this subscript?
double w1, w2, oh, bh, sp; double w1, w2, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr); nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtrForSuperscript);
if (bh>baselineHeight) { if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight; overallHeight=overallHeight+bh-baselineHeight;
@ -100,7 +106,7 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
} }
i++; i++;
nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtr); nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtrForSubscript);
//qDebug()<<"super_sub: sub: "<<nodes[i]->getTypeName()<<" w2="<<w2<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp; //qDebug()<<"super_sub: sub: "<<nodes[i]->getTypeName()<<" w2="<<w2<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp;
if (bh>baselineHeight) { if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight; overallHeight=overallHeight+bh-baselineHeight;
@ -111,18 +117,18 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
overallHeight=baselineHeight+oh-bh; overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp; strikeoutPos=sp;
} }
xnew+=qMax(w1+fm.boundingRect(' ').width(), w2); xnew+=qMax(w1+spaceWidth, w2);
doDraw=false; doDraw=false;
//qDebug()<<"### super+sub"; //qDebug()<<"### super+sub";
//qDebug()<<"### subsupop: super+sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: super+sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
} }
} else if (dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i])) { } else if (nodeI_SubScript) {
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1])) { // is this subscript?
double w1, w2, oh, bh, sp; double w1, w2, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr); nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtrForSubscript);
if (bh>baselineHeight) { if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight; overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=bh; baselineHeight=bh;
@ -134,7 +140,7 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
} }
i++; i++;
nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtr); nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtrForSuperscript);
if (bh>baselineHeight) { if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight; overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=bh; baselineHeight=bh;
@ -144,7 +150,7 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
overallHeight=baselineHeight+oh-bh; overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp; strikeoutPos=sp;
} }
xnew+=qMax(w1, w2+fm.boundingRect(' ').width()); xnew+=qMax(w1, w2+spaceWidth);
doDraw=false; doDraw=false;
@ -152,95 +158,103 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
//qDebug()<<"### subsupop: sub+super1 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: sub+super1 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
} }
} else if (smb) { } else {
QString s=smb->getSymbolName(); if (nodes[i]->isSubSuperscriptAboveBelowNode()) {
if (subsupOperations.contains(s)) {
JKQTMathTextSubscriptNode* subn=nullptr; JKQTMathTextSubscriptNode* subn=nullptr;
if (i+1<nodes.size()) subn=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1]);
JKQTMathTextSuperscriptNode* supn=nullptr; JKQTMathTextSuperscriptNode* supn=nullptr;
if (i+2<nodes.size()) supn=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+2]); JKQTMathTextSubscriptNode* subn2=nullptr;
JKQTMathTextSuperscriptNode* supn2=nullptr;
if (i+1<nodes.size()) {
subn=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1]);
supn=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1]);
}
if (i+2<nodes.size()) {
subn2=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+2]);
supn2=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+2]);
}
//std::cout<<"symbol ='"<<s.toStdString()<<"' subn="<<subn<<" supn="<<supn<<"\n"; //std::cout<<"symbol ='"<<s.toStdString()<<"' subn="<<subn<<" supn="<<supn<<"\n";
if (subn && supn) { // is this subscript and superscript? if ((subn && supn2) || (subn2 && supn)) { // is this subscript and superscript or superscript and subscript?
JKQTMathTextEnvironment ev=currentEv; if (!subn) subn=subn2;
if (!supn) supn=supn2; JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double w1=0, w2=0, w3=0; double w1=0, wsub=0, wsup=0;
double oh1=0, oh2=0, oh3=0; double oh1=0, ohsub=0, ohsup=0;
double bh1=0, bh2=0, bh3=0; double bh1=0, bhsub=0, bhsup=0;
double sp1=0, sp2=0, sp3=0; double sp1=0, spsub=0, spsup=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1);
//qDebug()<<"sub_super: node: "<<nodes[i]->getTypeName()<<" w1="<<w1<<" bh"<<bh1<<" oh="<<oh1<<" sp="<<sp1; //qDebug()<<"sub_super: node: "<<nodes[i]->getTypeName()<<" w1="<<w1<<" bh"<<bh1<<" oh="<<oh1<<" sp="<<sp1;
subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp2); subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
//qDebug()<<"sub_super: node: "<<subn->getTypeName()<<" w2="<<w2<<" bh2"<<bh2<<" oh2="<<oh2<<" sp2="<<sp2; //qDebug()<<"sub_super: node: "<<subn->getTypeName()<<" w2="<<w2<<" bh2"<<bh2<<" oh2="<<oh2<<" sp2="<<sp2;
supn->getChild()->getSize(painter, ev, w3, bh3, oh3, sp3); supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
//qDebug()<<"sub_super: node: "<<supn->getTypeName()<<" w3="<<w3<<" bh3"<<bh3<<" oh3="<<oh3<<" sp3="<<sp3; //qDebug()<<"sub_super: node: "<<supn->getTypeName()<<" w3="<<w3<<" bh3"<<bh3<<" oh3="<<oh3<<" sp3="<<sp3;
//double d1=oh1-bh1; //double d1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
//double d3=oh3-bh3; //double d3=oh3-bh3;
double w=qMax(qMax(w1, w2), w3)+fm.boundingRect(' ').width(); const double neww=qMax(qMax(w1, wsub), wsup)+subsuperextrawidth;
double oh=oh1+oh2+oh3; const double newBaselineHeight=bh1+ohsup+subsupershift;
double bh=bh1+oh3; if (newBaselineHeight>baselineHeight) {
if (oh>overallHeight) overallHeight=oh; const double extraBaselineHeight=newBaselineHeight-baselineHeight;
if (bh>baselineHeight) { baselineHeight=bh; strikeoutPos=sp1; } baselineHeight=newBaselineHeight;
if (oh-bh>overallHeight-baselineHeight) { overallHeight=overallHeight+extraBaselineHeight;
overallHeight=baselineHeight+oh-bh; }
const double newDescent=oh1-bh1+ohsub+subsupershift;
if (newDescent>overallHeight-baselineHeight) {
const double extraDescent=newDescent-(overallHeight-baselineHeight);
overallHeight=overallHeight+extraDescent;
} }
i++; i++;
i++; i++;
doDraw=false; doDraw=false;
xnew+=w; xnew+=neww;
//qDebug()<<"### subsupop: sub+super2 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: sub+super2 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
/*} else if (subn && supn) { // is this subscript and superscript?
MTenvironment ev=currentEv;
ev.fontSize=ev.fontSize*parent->getOperatorsubsuperSizeFactor();
double w1=0, w2=0, w3=0;
double oh1=0, oh2=0, oh3=0;
double bh1=0, bh2=0, bh3=0;
double sp1=0, sp2=0, sp3=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1);
supn->getChild()->getSize(painter, ev, w3, bh3, oh3, sp3);
//double d1=oh1-bh1;
//double d2=oh2-bh2;
//double d3=oh3-bh3;
double w=qMax(w1, w3)+fm.boundingRect(' ').width();
double oh=oh1+oh3;
double bh=bh1+oh3;
if (oh>overallHeight) overallHeight=oh;
if (bh>baselineHeight) { baselineHeight=bh; strikeoutPos=sp1; }
if (oh-bh>overallHeight-baselineHeight) {
overallHeight=baselineHeight+oh-bh;
}
i++;
i++;
doDraw=false;
xnew+=w;
//qDebug()<<"### subsupop: sub+super";*/
} else if (subn) { // is this subscript? } else if (subn) { // is this subscript?
JKQTMathTextEnvironment ev=currentEv; JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double w1=0, w2=0; double w1=0, wsub=0;
double oh1=0, oh2=0; double oh1=0, ohsub=0;
double bh1=0, bh2=0; double bh1=0, bhsub=0;
double sp1=0, sp2=0;//, sp3=0; double sp1=0, spsub=0;//, sp3=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1);
subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp2); subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
//double d1=oh1-bh1; //double d1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
double oh=oh1+oh2; const double newDescent=oh1-bh1+ohsub+subsupershift;
double sh=oh1-bh1+oh2*1.1; if (newDescent>overallHeight-baselineHeight) {
if (oh>overallHeight) overallHeight=oh; const double extraDescent=newDescent-(overallHeight-baselineHeight);
if (bh1>baselineHeight) baselineHeight=bh1; overallHeight=overallHeight+extraDescent;
if (sh>overallHeight-baselineHeight) {
overallHeight=baselineHeight+sh;
} }
double w=qMax(w1, w2)+fm.boundingRect(' ').width(); const double neww=qMax(w1, wsub)+subsuperextrawidth;
i++; i++;
doDraw=false; doDraw=false;
xnew+=w; xnew+=neww;
//qDebug()<<"### subsupop: sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} else if (supn) { // is this superscript?
JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double w1=0, wsup=0;
double oh1=0, ohsup=0;
double bh1=0, bhsup=0;
double sp1=0, spsup=0;//, sp3=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1);
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
//double d1=oh1-bh1;
//double d2=oh2-bh2;
const double newBaselineHeight=bh1+ohsup+subsupershift;
if (newBaselineHeight>baselineHeight) {
const double extraBaselineHeight=newBaselineHeight-baselineHeight;
baselineHeight=newBaselineHeight;
overallHeight=overallHeight+extraBaselineHeight;
}
const double neww=qMax(w1, wsup)+subsuperextrawidth;
i++;
doDraw=false;
xnew+=neww;
//qDebug()<<"### subsupop: sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
} }
@ -248,17 +262,19 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
if (i<nodes.size() && doDraw) { if (i<nodes.size() && doDraw) {
double w, oh, bh, sp; double w, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w, bh, oh, sp, prevNodeSizePtr); if (nodeI_SubScript) nodes[i]->getSize(painter, currentEv, w, bh, oh, sp, prevNodeSizePtrForSubscript);
else if (nodeI_SuperScript) nodes[i]->getSize(painter, currentEv, w, bh, oh, sp, prevNodeSizePtrForSuperscript);
else nodes[i]->getSize(painter, currentEv, w, bh, oh, sp, nullptr);
const double cDescent=oh-bh;
//qDebug()<<"### else: bh="<<bh<<" baselineHeight="<<baselineHeight<<" oh="<<oh<<" overallHeight="<<overallHeight; //qDebug()<<"### else: bh="<<bh<<" baselineHeight="<<baselineHeight<<" oh="<<oh<<" overallHeight="<<overallHeight;
if (bh>baselineHeight) { if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight; overallHeight=overallHeight-baselineHeight+bh;
baselineHeight=bh; baselineHeight=bh;
strikeoutPos=sp; strikeoutPos=sp;
} }
if (baselineHeight+oh-bh>overallHeight) { if (baselineHeight+cDescent>overallHeight) {
overallHeight=baselineHeight+oh-bh; overallHeight=baselineHeight+cDescent;
strikeoutPos=sp; strikeoutPos=sp;
} }
//qDebug()<<"### subsupop: else overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: else overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
@ -276,137 +292,156 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
double ynew=y; double ynew=y;
double xnew=x; double xnew=x;
//qDebug()<<"listNode: "<<currentEv.fontSize; //qDebug()<<"listNode: "<<currentEv.fontSize;
QFontMetricsF fm(currentEv.getFont(parentMathText)); const QFontMetricsF fm(currentEv.getFont(parentMathText));
bool wasBrace=false; const double subsupershift=fm.xHeight()*parentMathText->getOperatorsubsuperDistanceFactor();
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
for (int i=0; i<nodes.size(); i++) { for (int i=0; i<nodes.size(); i++) {
bool doDraw=true; bool doDraw=true;
JKQTMathTextNodeSize prevNodeSize; JKQTMathTextNodeSize prevNodeSize;
JKQTMathTextNodeSize* prevNodeSizePtr=nullptr; JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr;
if (i>0 && wasBrace) { if (i>0) {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos);
prevNodeSizePtr=&prevNodeSize; const double prevAscent=prevNodeSize.baselineHeight;
const double prevDescent=prevNodeSize.overallHeight-prevNodeSize.baselineHeight;
const bool shouldUseSpecialSubscriptMode=prevAscent>=subsuperSpecialModeAscent;
const bool shouldUseSpecialSuperscriptMode=prevDescent>=subsuperSpecialModeDecent;
if (shouldUseSpecialSubscriptMode) prevNodeSizePtrForSubscript=&prevNodeSize;
if (shouldUseSpecialSuperscriptMode) prevNodeSizePtrForSuperscript=&prevNodeSize;
} }
JKQTMathTextSuperscriptNode* nodeI_SuperScript=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i]);
JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i]);
JKQTMathTextSymbolNode* smb=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
// if we find a subscript/superscript node we check whether the next node is super/subscript // if we find a subscript/superscript node we check whether the next node is super/subscript
// if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly // if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly
if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i])) { if (nodeI_SuperScript) {
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1])) { // is this subscript?
//painter.setPen(QPen("red")); //painter.setPen(QPen("red"));
//painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8); //painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8);
double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSuperscript);
i++; i++;
//painter.setPen(QPen("magenta")); //painter.setPen(QPen("magenta"));
//painter.drawEllipse(xnew-4,ynew-4,8,8); //painter.drawEllipse(xnew-4,ynew-4,8,8);
double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSubscript);
//i++; //i++;
xnew=qMax(xnew1, xnew2); xnew=qMax(xnew1, xnew2);
doDraw=false; doDraw=false;
} }
} }
} else if (dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i])) { } else if (nodeI_SubScript) {
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one more node behind?
if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1])) { // is this subscript?
//painter.setPen(QPen("red")); //painter.setPen(QPen("red"));
//painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8); //painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8);
double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSubscript);
i++; i++;
//painter.setPen(QPen("magenta")); //painter.setPen(QPen("magenta"));
//painter.drawEllipse(xnew-4,ynew-4,8,8); //painter.drawEllipse(xnew-4,ynew-4,8,8);
double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSuperscript);
//i++; //i++;
xnew=qMax(xnew1, xnew2); xnew=qMax(xnew1, xnew2);
doDraw=false; doDraw=false;
} }
} }
} else { } else {
if (smb) {
QString s=smb->getSymbolName();
if (subsupOperations.contains(s)) {
JKQTMathTextSubscriptNode* subn=nullptr;
if (i+1<nodes.size()) subn=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1]);
JKQTMathTextSuperscriptNode* supn=nullptr;
if (i+2<nodes.size()) supn=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+2]);
//std::cout<<"symbol ='"<<s.toStdString()<<"' subn="<<subn<<" supn="<<supn<<"\n";
if (subn && supn) { // is this subscript and superscript?
JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double w1=0, w2=0, w3=0;
double oh1=0, oh2=0, oh3=0;
double bh1=0, bh2=0, bh3=0, sp;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp);
supn->getChild()->getSize(painter, ev, w3, bh3, oh3, sp);
double d1=oh1-bh1;
//double d2=oh2-bh2;
double d3=oh3-bh3;
double w=qMax(qMax(w1, w2), w3); if (nodes[i]->isSubSuperscriptAboveBelowNode()) {
//double xnew1= JKQTMathTextSubscriptNode* subn=nullptr;
double xn1=nodes[i]->draw(painter, xnew+(w-w1)/2.0, ynew, currentEv); JKQTMathTextSuperscriptNode* supn=nullptr;
i++; JKQTMathTextSubscriptNode* subn2=nullptr;
//double xnew2= JKQTMathTextSuperscriptNode* supn2=nullptr;
double xn2=subn->getChild()->draw(painter, xnew+(w-w2)/2.0, ynew+bh2+d1, ev); if (i+1<nodes.size()) {
i++; subn=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+1]);
//double xnew3= supn=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1]);
double xn3=supn->getChild()->draw(painter, xnew+(w-w3)/2.0, ynew-bh1-d3-fm.xHeight()/4.0, ev); }
doDraw=false; if (i+2<nodes.size()) {
xnew=qMax(qMax(xn1, xn2), xn3)+fm.boundingRect(' ').width(); subn2=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i+2]);
} else if (subn) { // is this subscript and not superscript? supn2=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+2]);
JKQTMathTextEnvironment ev=currentEv; }
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); //std::cout<<"symbol ='"<<s.toStdString()<<"' subn="<<subn<<" supn="<<supn<<"\n";
double w1=0, w2=0; if ((subn && supn2) || (subn2 && supn)) { // is this subscript and superscript or superscript and subscript?
double oh1=0, oh2=0; if (!subn) subn=subn2;
double bh1=0, bh2=0, sp=0; if (!supn) supn=supn2;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); JKQTMathTextEnvironment ev=currentEv;
subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp); ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double d1=oh1-bh1; double w1=0, wsub=0, wsup=0;
//double d2=oh2-bh2; double oh1=0, ohsub=0, ohsup=0;
double bh1=0, bhsub=0, bhsup=0, spsub, spsup, sp;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
const double descent1=oh1-bh1;
//double d2=oh2-bh2;
const double descent3=ohsup-bhsup;
double w=qMax(w1, w2); const double neww=qMax(qMax(w1, wsub), wsup)+subsuperextrawidth;
//double xnew1= //double xnew1=
double xn2=nodes[i]->draw(painter, xnew+(w-w1)/2.0, ynew, currentEv); const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv);
i++; i++;
//double xnew2= //double xnew2=
double xn1=subn->getChild()->draw(painter, xnew+(w-w2)/2.0, ynew+bh2+d1, ev)+fm.boundingRect(' ').width(); const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0, ynew+bhsub+descent1+subsupershift, ev);
doDraw=false; i++;
//xnew+=w; //double xnew3=
xnew=qMax(xn1, xn2); const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0, ynew-bh1-descent3-subsupershift, ev);
} else if (supn) { // is this subscript and superscript? doDraw=false;
JKQTMathTextEnvironment ev=currentEv; xnew=qMax(qMax(xn1, xnsub), xnsup)+subsuperextrawidth/2.0;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); } else if (subn) { // is this subscript and no following superscript?
double w1=0, w3=0; JKQTMathTextEnvironment ev=currentEv;
double oh1=0, oh3=0; ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double bh1=0, bh3=0, sp; double w1=0, wsub=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); double oh1=0, ohsub=0;
supn->getChild()->getSize(painter, ev, w3, bh3, oh3, sp); double bh1=0, bhsub=0, sp=0, spsub=0;
//double d1=oh1-bh1; nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
//double d2=oh2-bh2; subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
double d3=oh3-bh3; const double descent1=oh1-bh1;
//double d2=oh2-bh2;
double w=qMax(w1, w3); const double neww=qMax(w1, wsub)+subsuperextrawidth;
//double xnew1= //double xnew1=
double xn1=nodes[i]->draw(painter, xnew+(w-w1)/2.0, ynew, currentEv); const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv);
i++; i++;
//double xnew3= //double xnew2=
double xn3=supn->getChild()->draw(painter, xnew+(w-w3)/2.0, ynew-bh1-d3-fm.xHeight()/4.0, ev); const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0, ynew+bhsub+descent1+subsupershift, ev)+subsupershift;
doDraw=false; doDraw=false;
xnew=qMax(xn1, xn3)+fm.boundingRect(' ').width(); //xnew+=w;
} xnew=qMax(xnsub, xn1)+subsuperextrawidth/2.0;
} else if (supn) { // is this superscript and no following subscript?
JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double w1=0, wsup=0;
double oh1=0, ohsup=0;
double bh1=0, bhsup=0, sp, spsup;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
//double d1=oh1-bh1;
//double d2=oh2-bh2;
const double descent3=ohsup-bhsup;
const double neww=qMax(w1, wsup)+subsuperextrawidth;
//double xnew1=
const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv);
i++;
//double xnew3=
const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0, ynew-bh1-descent3-subsupershift, ev);
doDraw=false;
xnew=qMax(xn1, xnsup)+subsuperextrawidth/2.0;
} }
} }
} }
if (i<nodes.size() && doDraw) { if (i<nodes.size() && doDraw) {
xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); if (nodeI_SuperScript) xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSuperscript);
else if (nodeI_SubScript) xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSubscript);
else xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, nullptr);
} }
wasBrace=dynamic_cast<JKQTMathTextBraceNode*>(nodes[i]);
} }
return xnew; return xnew;
} }
@ -437,7 +472,7 @@ int JKQTMathTextListNode::childCount() const
} }
void JKQTMathTextListNode::clearChildren(bool deleteChildren) void JKQTMathTextListNode::clearChildrenImpl(bool deleteChildren)
{ {
if (deleteChildren) { if (deleteChildren) {
for (int i=0; i<nodes.size(); i++) { for (int i=0; i<nodes.size(); i++) {
@ -447,6 +482,11 @@ void JKQTMathTextListNode::clearChildren(bool deleteChildren)
nodes.clear(); nodes.clear();
} }
void JKQTMathTextListNode::clearChildren(bool deleteChildren)
{
clearChildrenImpl(deleteChildren);
}
JKQTMathTextNode *JKQTMathTextListNode::getChild(int i) JKQTMathTextNode *JKQTMathTextListNode::getChild(int i)
{ {
return nodes[i]; return nodes[i];

View File

@ -34,6 +34,10 @@ class JKQTMathText; // forward
/** \brief subclass representing a list of nodes in the syntax tree /** \brief subclass representing a list of nodes in the syntax tree
* \ingroup jkqtmathtext_items * \ingroup jkqtmathtext_items
*
* \note This type of node also implements typesetting sub-/superscript above/below the previous node (if
* JKQTMathTextNode::is() is \c true for that previus node. The drawing is done as defined in the
* following image \image html jkqtmathtext_subsuper_with_limits.png
*/ */
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextListNode: public JKQTMathTextMultiChildNode { class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextListNode: public JKQTMathTextMultiChildNode {
public: public:
@ -63,8 +67,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextListNode: public JKQTMathTextMultiChil
/** \copydoc JKQTMathTextNode::getSizeInternal() */ /** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
QList<JKQTMathTextNode*> nodes; QList<JKQTMathTextNode*> nodes;
/** \brief the instructions in this can have the sub-script/superscript set below/above, not besides the node */ private:
static QSet<QString> subsupOperations; /** \brief internal implementation of clearChildren() that is non-virtual, so can be used in the destructor */
void clearChildrenImpl(bool deleteChildren);
}; };
#endif // JKQTMATHTEXTLISTNODE_H #endif // JKQTMATHTEXTLISTNODE_H

View File

@ -41,7 +41,8 @@
JKQTMathTextNode::JKQTMathTextNode(JKQTMathText *_parent): JKQTMathTextNode::JKQTMathTextNode(JKQTMathText *_parent):
parentMathText(_parent), parentMathText(_parent),
parentNode(nullptr), parentNode(nullptr),
drawBoxes(false) drawBoxes(false),
subSuperscriptAboveBelowNode(false)
{ {
} }
@ -140,6 +141,16 @@ const JKQTMathTextNode *JKQTMathTextNode::getParentNode() const
return parentNode; return parentNode;
} }
bool JKQTMathTextNode::isSubSuperscriptAboveBelowNode() const
{
return subSuperscriptAboveBelowNode;
}
void JKQTMathTextNode::setSubSuperscriptAboveBelowNode(bool __value)
{
subSuperscriptAboveBelowNode=__value;
}
JKQTMathTextSingleChildNode::JKQTMathTextSingleChildNode(JKQTMathTextNode *_child, JKQTMathText *parentMathText): JKQTMathTextSingleChildNode::JKQTMathTextSingleChildNode(JKQTMathTextNode *_child, JKQTMathText *parentMathText):
JKQTMathTextNode(parentMathText), JKQTMathTextNode(parentMathText),
child(_child) child(_child)
@ -302,6 +313,26 @@ QList<const JKQTMathTextNode *> JKQTMathTextMultiChildNode::getChildren() const
return l; return l;
} }
JKQTMathTextNode *JKQTMathTextMultiChildNode::getFirstChild()
{
return getChild(0);
}
const JKQTMathTextNode *JKQTMathTextMultiChildNode::getFirstChild() const
{
return getChild(0);
}
JKQTMathTextNode *JKQTMathTextMultiChildNode::getLastChild()
{
return getChild(childCount()-1);
}
const JKQTMathTextNode *JKQTMathTextMultiChildNode::getLastChild() const
{
return getChild(childCount()-1);
}
void JKQTMathTextMultiChildNode::replaceAndDeleteChild(int i, JKQTMathTextNode *newChild) void JKQTMathTextMultiChildNode::replaceAndDeleteChild(int i, JKQTMathTextNode *newChild)
{ {
JKQTMathTextNode* oldC=replaceChild(i, newChild); JKQTMathTextNode* oldC=replaceChild(i, newChild);
@ -311,6 +342,16 @@ void JKQTMathTextMultiChildNode::replaceAndDeleteChild(int i, JKQTMathTextNode *
} }
} }
bool JKQTMathTextMultiChildNode::hasChildren() const
{
return childCount()>0;
}
bool JKQTMathTextMultiChildNode::isEmpty() const
{
return childCount()==0;
}
void JKQTMathTextMultiChildNode::setDrawBoxes(bool draw) void JKQTMathTextMultiChildNode::setDrawBoxes(bool draw)
{ {
JKQTMathTextNode::setDrawBoxes(draw); JKQTMathTextNode::setDrawBoxes(draw);

View File

@ -84,6 +84,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode {
JKQTMathTextNode* getParentNode(); JKQTMathTextNode* getParentNode();
/** \copydoc parentNode */ /** \copydoc parentNode */
const JKQTMathTextNode* getParentNode() const; const JKQTMathTextNode* getParentNode() const;
/** \copydoc subSuperscriptAboveBelowNode */
bool isSubSuperscriptAboveBelowNode() const;
/** \copydoc subSuperscriptAboveBelowNode */
void setSubSuperscriptAboveBelowNode(bool __value);
protected: protected:
/** \brief determine the size of the node, overwrite this function in derived classes /** \brief determine the size of the node, overwrite this function in derived classes
* *
@ -104,6 +109,12 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode {
JKQTMathTextNode* parentNode; JKQTMathTextNode* parentNode;
/** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */
bool drawBoxes; bool drawBoxes;
/** \brief if \c true then following sub- and/or superscripts are placed below and above the node, not besides it.
* This is activated when \c \\sum\\limits_{sub}^{sup} is used in LaTeX instead of simply \c \\sum_{sub}^{sup}
*
* The default is c false
*/
bool subSuperscriptAboveBelowNode;
/** \brief draws colored boxes (for DEBUGGING) around the actual output of the node /** \brief draws colored boxes (for DEBUGGING) around the actual output of the node
* *
* \param painter QPainter to use * \param painter QPainter to use
@ -189,6 +200,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMultiChildNode: public JKQTMathTextNod
/** \brief returns the i-th child node */ /** \brief returns the i-th child node */
virtual const JKQTMathTextNode* getChild(int i) const=0; virtual const JKQTMathTextNode* getChild(int i) const=0;
/** \brief returns the first child node */
virtual JKQTMathTextNode* getFirstChild();
/** \brief returns the first child node */
virtual const JKQTMathTextNode* getFirstChild() const;
/** \brief returns the last child node */
virtual JKQTMathTextNode* getLastChild();
/** \brief returns the last child node */
virtual const JKQTMathTextNode* getLastChild() const;
/** \brief replaces the i-th child node with the node \a newChild , returns the replaced old node */ /** \brief replaces the i-th child node with the node \a newChild , returns the replaced old node */
virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) =0; virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) =0;
@ -197,6 +217,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMultiChildNode: public JKQTMathTextNod
/** \brief returns the number of child nodes */ /** \brief returns the number of child nodes */
virtual int childCount() const =0; virtual int childCount() const =0;
/** \brief returns \c true if children exist */
bool hasChildren() const;
/** \brief returns \c true if there are no children */
bool isEmpty() const;
/** \brief clear all children, deleting them if \a deleteChildren==true */ /** \brief clear all children, deleting them if \a deleteChildren==true */
virtual void clearChildren(bool deleteChildren=true) =0; virtual void clearChildren(bool deleteChildren=true) =0;

View File

@ -49,16 +49,19 @@ void JKQTMathTextSuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathTex
JKQTMathTextEnvironment ev=currentEv; JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
const QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
double cstrikeoutPos=0; double cStrikeoutPos=0, cWidth=0, cBaselineHeight=0, cOverallHeight=0;
getChild()->getSize(painter, ev, width, baselineHeight, overallHeight, cstrikeoutPos); getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos);
double shift=parentMathText->getSuperShiftFactor()*tbr.height(); const double childDescent=cOverallHeight-cBaselineHeight;
double shiftToChildBottom=parentMathText->getSuperShiftFactor()*tbr_of_letterM.height();
if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { if (prevNodeSize!=nullptr) {
shift=prevNodeSize->baselineHeight-(overallHeight-baselineHeight)-shift; const double modifiedShift=prevNodeSize->baselineHeight-childDescent-parentMathText->getSpecialSuperShiftFactor()*cBaselineHeight-childDescent;
if (modifiedShift>shiftToChildBottom) shiftToChildBottom=modifiedShift;
} }
baselineHeight=overallHeight=overallHeight+shift; baselineHeight=overallHeight=cOverallHeight+shiftToChildBottom;
width=cWidth;
if (prevNodeSize!=nullptr) strikeoutPos=prevNodeSize->strikeoutPos; if (prevNodeSize!=nullptr) strikeoutPos=prevNodeSize->strikeoutPos;
else strikeoutPos=fm.strikeOutPos(); else strikeoutPos=fm.strikeOutPos();
if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor(); if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor();
@ -72,19 +75,20 @@ double JKQTMathTextSuperscriptNode::draw(QPainter& painter, double x, double y,
double cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos; double cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos;
getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos);
QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
double shift=parentMathText->getSuperShiftFactor()*tbr.height(); const double childDescent=cOverallHeight-cBaselineHeight;
double shiftToChildBottom=parentMathText->getSuperShiftFactor()*tbr_of_letterM.height();
if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { if (prevNodeSize!=nullptr) {
shift=prevNodeSize->baselineHeight-(cOverallHeight-cBaselineHeight)-shift; const double modifiedShift=prevNodeSize->baselineHeight-childDescent-parentMathText->getSpecialSuperShiftFactor()*cBaselineHeight-childDescent;
if (modifiedShift>shiftToChildBottom) shiftToChildBottom=modifiedShift;
} }
double yshift=shift+cOverallHeight-cBaselineHeight;
double xx=x; double xx=x;
if (currentEv.italic && prevNodeSize==nullptr) xx=xx+double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor(); if (currentEv.italic && prevNodeSize==nullptr) xx=xx+double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor();
return getChild()->draw(painter, xx, y-yshift, ev);//+0.5*fm.boundingRect("A").width(); return getChild()->draw(painter, xx, y-(shiftToChildBottom+childDescent), ev);//+0.5*fm.boundingRect("A").width();
} }
@ -120,20 +124,27 @@ JKQTMathTextSubscriptNode::~JKQTMathTextSubscriptNode() {
void JKQTMathTextSubscriptNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) { void JKQTMathTextSubscriptNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) {
JKQTMathTextEnvironment ev=currentEv; JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
const QFontMetricsF fm(ev.getFont(parentMathText), painter.device());
const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
getChild()->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); double cWidth=0, cBaselineHeight=0, cOverallHeight=0, cStrikeoutPos=0;
getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos);
const double childDescent=cOverallHeight-cBaselineHeight;
double shift_to_childBaseline=cBaselineHeight-parentMathText->getSubShiftFactor()*tbr_of_letterM.height();
QFontMetricsF fm(ev.getFont(parentMathText), painter.device()); if (prevNodeSize!=nullptr) {
QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); //qDebug()<<"oldshift="<<shift<<", prevNodeSize->overallHeight="<<prevNodeSize->overallHeight<<", prevNodeSize->baselineHeight="<<prevNodeSize->baselineHeight;
double shift=parentMathText->getSubShiftFactor()*tbr.height(); const double parentDescent=prevNodeSize->overallHeight-prevNodeSize->baselineHeight;
const double newShift=parentDescent+parentMathText->getSpecialSubShiftFactor()*cBaselineHeight;
if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { if (newShift>shift_to_childBaseline) shift_to_childBaseline=newShift;
shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); //qDebug()<<"newshift="<<shift;
} }
baselineHeight=shift; baselineHeight=cBaselineHeight-shift_to_childBaseline;
overallHeight=cOverallHeight;
if (prevNodeSize!=nullptr) strikeoutPos=prevNodeSize->strikeoutPos; if (prevNodeSize!=nullptr) strikeoutPos=prevNodeSize->strikeoutPos;
else strikeoutPos=fm.strikeOutPos(); else strikeoutPos=fm.strikeOutPos();
width=cWidth;
if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor(); if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor();
} }
@ -141,25 +152,26 @@ double JKQTMathTextSubscriptNode::draw(QPainter& painter, double x, double y, JK
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv; JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
QFontMetricsF fm(ev.getFont(parentMathText), painter.device()); const QFontMetricsF fm(ev.getFont(parentMathText), painter.device());
QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; double cWidth=0, cBaselineHeight=0, cOverallHeight=0, cStrikeoutPos=0;
getChild()->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos);
double shift=parentMathText->getSubShiftFactor()*tbr.height(); double shift_to_childBaseline=cBaselineHeight-parentMathText->getSubShiftFactor()*tbr_of_letterM.height();
if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { if (prevNodeSize!=nullptr) {
//qDebug()<<"oldshift="<<shift<<", prevNodeSize->overallHeight="<<prevNodeSize->overallHeight<<", prevNodeSize->baselineHeight="<<prevNodeSize->baselineHeight; //qDebug()<<"oldshift="<<shift<<", prevNodeSize->overallHeight="<<prevNodeSize->overallHeight<<", prevNodeSize->baselineHeight="<<prevNodeSize->baselineHeight;
shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); const double parentDescent=prevNodeSize->overallHeight-prevNodeSize->baselineHeight;
const double newShift=parentDescent+parentMathText->getSpecialSubShiftFactor()*cBaselineHeight;
if (newShift>shift_to_childBaseline) shift_to_childBaseline=newShift;
//qDebug()<<"newshift="<<shift; //qDebug()<<"newshift="<<shift;
} }
double yshift=baselineHeight-shift;
//qDebug()<<"baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight<<", strikeoutPos="<<strikeoutPos; //qDebug()<<"baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight<<", strikeoutPos="<<strikeoutPos;
//qDebug()<<"shift="<<shift<<", yshift="<<yshift; //qDebug()<<"shift="<<shift<<", yshift="<<yshift;
double xx=x; double xx=x;
if (currentEv.italic && prevNodeSize==nullptr) xx=xx-double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor(); if (currentEv.italic && prevNodeSize==nullptr) xx=xx-double(fm.boundingRect(' ').width())*parentMathText->getItalicCorrectionFactor();
return getChild()->draw(painter, xx, y+yshift, ev);//+0.5*fm.boundingRect("A").width(); return getChild()->draw(painter, xx, y+shift_to_childBaseline, ev);//+0.5*fm.boundingRect("A").width();
} }
QString JKQTMathTextSubscriptNode::getTypeName() const QString JKQTMathTextSubscriptNode::getTypeName() const

View File

@ -633,10 +633,10 @@ bool JKQTMathTextSymbolNode::getUnicodeFullSymbolProp(JKQTMathTextSymbolNode::Sy
else if (n == "oiint") { props.symbol = QChar(0x222F); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } else if (n == "oiint") { props.symbol = QChar(0x222F); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "oiiint") { props.symbol = QChar(0x2230); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } else if (n == "oiiint") { props.symbol = QChar(0x2230); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "coprod") { props.symbol = QChar(0x2210); props.heightIsAscent = true; props.exactAscent = true; } else if (n == "coprod") { props.symbol = QChar(0x2210); props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "bigcap") { props.symbol = QChar(0x22C2); props.heightIsAscent = true; props.exactAscent = true; props.heightIsAscent = true; props.exactAscent = true; } else if (n == "bigcap") { props.symbol = QChar(0x22C2); props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "bigcup") { props.symbol = QChar(0x22C3); props.heightIsAscent = true; props.exactAscent = true; props.heightIsAscent = true; props.exactAscent = true; } else if (n == "bigcup") { props.symbol = QChar(0x22C3); props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "bigvee") { props.symbol = QChar(0x22C1); props.heightIsAscent = true; props.exactAscent = true; props.heightIsAscent = true; props.exactAscent = true; } else if (n == "bigvee") { props.symbol = QChar(0x22C1); props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "bighat") { props.symbol = QChar(0x22C0); props.heightIsAscent = true; props.exactAscent = true; props.heightIsAscent = true; props.exactAscent = true; } else if (n == "bighat") { props.symbol = QChar(0x22C0); props.heightIsAscent = true; props.exactAscent = true; }
else if (n == "int") { props.symbol = QChar(0x222B); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } else if (n == "int") { props.symbol = QChar(0x222B); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; }
else {return false;} else {return false;}
return true; return true;
@ -653,7 +653,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps&
props.font = fnt.first; props.font = fnt.first;
if (fnt.second==MTFEunicode) { if (fnt.second==MTFEunicode) {
props.font = fnt.first; props.font = fnt.first;
if (!getUnicodeBaseSymbolProp(props, n) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) { if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) {
return false; return false;
} }
} else if (fnt.second==MTFEunicodeLimited) { } else if (fnt.second==MTFEunicodeLimited) {
@ -661,7 +661,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps&
if (!getUnicodeBaseSymbolProp(props, n) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) { if (!getUnicodeBaseSymbolProp(props, n) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) {
if (fntSym.second==MTFEunicode) { if (fntSym.second==MTFEunicode) {
props.font = fntSym.first; props.font = fntSym.first;
if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) { if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) {
return false; return false;
} }
} else if (fntSym.second==MTFEunicodeLimited) { } else if (fntSym.second==MTFEunicodeLimited) {
@ -684,7 +684,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps&
if (!getWinSymbolProp(props, n, currentEv, mathFontFactor)) { if (!getWinSymbolProp(props, n, currentEv, mathFontFactor)) {
if (fntSym.second==MTFEunicode) { if (fntSym.second==MTFEunicode) {
props.font = fntSym.first; props.font = fntSym.first;
if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) { if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) {
return false; return false;
} }
} else if (fntSym.second==MTFEunicodeLimited) { } else if (fntSym.second==MTFEunicodeLimited) {
@ -707,7 +707,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps&
if (!getStandardTextSymbolProp(props, n)) { if (!getStandardTextSymbolProp(props, n)) {
if (fntSym.second==MTFEunicode) { if (fntSym.second==MTFEunicode) {
props.font = fntSym.first; props.font = fntSym.first;
if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) { if (!getUnicodeBaseSymbolProp(props, n) && !getUnicodeFullSymbolProp(props,n,mathFontFactor) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) {
return false; return false;
} }
} else if (fntSym.second==MTFEunicodeLimited) { } else if (fntSym.second==MTFEunicodeLimited) {
@ -1271,12 +1271,14 @@ bool JKQTMathTextSymbolNode::toHtml(QString &html, JKQTMathTextEnvironment curre
QMap<QString, QString>::iterator itS = entitylut.find(symbolName); QMap<QString, QString>::iterator itS = entitylut.find(symbolName);
if (itS!=entitylut.end()) { s=itS.value(); } if (itS!=entitylut.end()) { s=itS.value(); }
else if (symbolName == "sum") { ev.fontSize*=1.7; s="&sum;"; } else if (symbolName == "sum") {
else if (symbolName == "prod") { ev.fontSize*=1.7; s="&prod;"; } ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="&sum;"; }
else if (symbolName == "bigcap") { ev.fontSize*=1.7; s="&cap;"; } else if (symbolName == "prod") {
else if (symbolName == "bigcup") { ev.fontSize*=1.7; s="&cup;"; } ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="&prod;"; }
else if (symbolName == "bigvee") { ev.fontSize*=1.7; s="&or;"; } else if (symbolName == "bigcap") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="&cap;"; }
else if (symbolName == "bighat") { ev.fontSize*=1.7; s="&and;"; } else if (symbolName == "bigcup") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="&cup;"; }
else if (symbolName == "bigvee") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="&or;"; }
else if (symbolName == "bighat") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="&and;"; }
else ok=false; else ok=false;
if (ok) html=html+ev.toHtmlStart(defaultEv)+s+ev.toHtmlAfter(defaultEv); if (ok) html=html+ev.toHtmlStart(defaultEv)+s+ev.toHtmlAfter(defaultEv);