diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 49fc10db4f..bc4dce3fe4 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -32,8 +32,11 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
  • FIXED: strikeoutPos was not correctly calculated in sub-/superscript node
  • FIXED: symbol spacing in math mode (and text mode)
  • 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
  • +
  • FIXED: \sum and \prod used the wrong symbol in XITS-mode
  • IMPROVED: high-dpr-support in JKQTMathText
  • +
  • IMPROVED: typesetting of sub-/supercripts, especially for large math operators and braces
  • MODIFIED: brace node now calculates the extension of the child height above or below the strikeoutPos, in order to center braces around the strikeoutPos
  • +
  • remove/breaking: \v[a-zA-Z] and shorthand for \vec{a-zA-Z} was removed, implementation of \bbR,\bbC,... changed
  • NEW: now supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve
  • NEW: reworked drawing of decorations: improved appearance and positioning!
  • NEW: reworked code structure: broke up large, single CPP-files into several smaller files!
  • @@ -42,6 +45,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
  • NEW: shows strikeoutPos when drawing Debug-Boxes
  • NEW: LaTeX-Parser understands optional instruction parameters in [...] now
  • NEW: LaTeX-Parser simplifies parrse-tree to increase speed of execution
  • +
  • NEW: \limits and \nolimits works as in LaTeX now (before it was simply removed and the functionality implemented for a fixed list of symbols)
  • diff --git a/doc/images/jkqtmathtext/jkqtmathtext_specialsubscriptnode_getSizeInternal.cdr b/doc/images/jkqtmathtext/jkqtmathtext_specialsubscriptnode_getSizeInternal.cdr new file mode 100644 index 0000000000..c1da766899 Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_specialsubscriptnode_getSizeInternal.cdr differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_specialsubscriptnode_getSizeInternal.png b/doc/images/jkqtmathtext/jkqtmathtext_specialsubscriptnode_getSizeInternal.png new file mode 100644 index 0000000000..7642b92499 Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_specialsubscriptnode_getSizeInternal.png differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_specialsuperscriptnode_getSizeInternal.cdr b/doc/images/jkqtmathtext/jkqtmathtext_specialsuperscriptnode_getSizeInternal.cdr new file mode 100644 index 0000000000..3d56d774fc Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_specialsuperscriptnode_getSizeInternal.cdr differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_specialsuperscriptnode_getSizeInternal.png b/doc/images/jkqtmathtext/jkqtmathtext_specialsuperscriptnode_getSizeInternal.png new file mode 100644 index 0000000000..9ce16ff487 Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_specialsuperscriptnode_getSizeInternal.png differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_subsuper_with_limits.cdr b/doc/images/jkqtmathtext/jkqtmathtext_subsuper_with_limits.cdr new file mode 100644 index 0000000000..a0d0682ba0 Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_subsuper_with_limits.cdr differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_subsuper_with_limits.png b/doc/images/jkqtmathtext/jkqtmathtext_subsuper_with_limits.png new file mode 100644 index 0000000000..745452efa7 Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_subsuper_with_limits.png differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_superscriptnode_getSizeInternal.cdr b/doc/images/jkqtmathtext/jkqtmathtext_superscriptnode_getSizeInternal.cdr index 31b3efe455..7aa9c3d93b 100644 Binary files a/doc/images/jkqtmathtext/jkqtmathtext_superscriptnode_getSizeInternal.cdr and b/doc/images/jkqtmathtext/jkqtmathtext_superscriptnode_getSizeInternal.cdr differ diff --git a/examples/jkqtmathtext_test/mathtest.pdf b/examples/jkqtmathtext_test/mathtest.pdf index 4af49cdf73..97fe5e51f6 100644 Binary files a/examples/jkqtmathtext_test/mathtest.pdf and b/examples/jkqtmathtext_test/mathtest.pdf differ diff --git a/examples/jkqtmathtext_test/mathtest.tex b/examples/jkqtmathtext_test/mathtest.tex index dd344d7bed..8033de02b6 100644 --- a/examples/jkqtmathtext_test/mathtest.tex +++ b/examples/jkqtmathtext_test/mathtest.tex @@ -130,6 +130,7 @@ \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: 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: 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}}$ diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp index 17257b5886..b3af7a8bb8 100644 --- a/examples/jkqtmathtext_test/testform.cpp +++ b/examples/jkqtmathtext_test/testform.cpp @@ -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 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("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("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 1", "text \\mathbf{bold}"); 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}"; }; 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("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: 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$"); @@ -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("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("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("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("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: 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", "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: 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, ... 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\\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+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+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/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}}}$"); @@ -217,7 +217,7 @@ TestForm::TestForm(QWidget *parent) : 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); 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; @@ -298,6 +298,7 @@ double TestForm::draw(QPainter& painter, double X, double YY, JKQTMathText& mt, qDebug()<<" drawing in "<getChild()) ti->addChild(createTree(subN->getChild(), ti)); } 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)); } else if (lstN) { name=QString("MTlistNode"); @@ -373,7 +374,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p ti->addChild(createTree(list[i], ti)); } } 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) { name=QString("MTWhitespaceNode :\'%1\'").arg(txtN->getText()); } else if (txtN) { @@ -445,24 +446,36 @@ void TestForm::updateMath() ht.start(); + if (ui->cmbFont->currentIndex()<=3) { + mt.setFontRoman(ui->cmbUnicodeSerif->currentFont().family(), static_cast(ui->cmbEncodingSerif->currentIndex())); + mt.setFontSans(ui->cmbUnicodeSans->currentFont().family(), static_cast(ui->cmbEncodingSans->currentIndex())); + mt.setFontMathRoman(ui->cmbUnicodeSerifMath->currentFont().family(), static_cast(ui->cmbEncodingSerifMath->currentIndex())); + mt.setFontMathSans(ui->cmbUnicodeSansMath->currentFont().family(), static_cast(ui->cmbEncodingSansMath->currentIndex())); + mt.setFontTypewriter(ui->cmbUnicodeFixed->currentFont().family(), static_cast(ui->cmbEncodingTypewriter->currentIndex())); + mt.setFontCaligraphic(ui->cmbCaligraphic->currentFont().family(), static_cast(ui->cmbEncodingCaligraphic->currentIndex())); + mt.setFontScript(ui->cmbScript->currentFont().family(), static_cast(ui->cmbEncodingScript->currentIndex())); + mt.setFontFraktur(ui->cmbUnicodeFraktur->currentFont().family(), static_cast(ui->cmbEncodingFraktur->currentIndex())); + mt.setFontBlackboard(ui->cmbUnicodeBlackboard->currentFont().family(), static_cast(ui->cmbEncodingBlackboard->currentIndex())); + mt.setSymbolfontSymbol(ui->cmbUnicodeSymbol->currentFont().family(), static_cast(ui->cmbEncodingSymbol->currentIndex())); + mt.setSymbolfontGreek(ui->cmbUnicodeGreek->currentFont().family(), static_cast(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(ui->cmbEncodingSerif->currentIndex())); - mt.setFontSans(ui->cmbUnicodeSans->currentFont().family(), static_cast(ui->cmbEncodingSans->currentIndex())); - mt.setFontMathRoman(ui->cmbUnicodeSerifMath->currentFont().family(), static_cast(ui->cmbEncodingSerifMath->currentIndex())); - mt.setFontMathSans(ui->cmbUnicodeSansMath->currentFont().family(), static_cast(ui->cmbEncodingSansMath->currentIndex())); - mt.setFontTypewriter(ui->cmbUnicodeFixed->currentFont().family(), static_cast(ui->cmbEncodingTypewriter->currentIndex())); - mt.setFontCaligraphic(ui->cmbCaligraphic->currentFont().family(), static_cast(ui->cmbEncodingCaligraphic->currentIndex())); - mt.setFontScript(ui->cmbScript->currentFont().family(), static_cast(ui->cmbEncodingScript->currentIndex())); - mt.setFontFraktur(ui->cmbUnicodeFraktur->currentFont().family(), static_cast(ui->cmbEncodingFraktur->currentIndex())); - mt.setFontBlackboard(ui->cmbUnicodeBlackboard->currentFont().family(), static_cast(ui->cmbEncodingBlackboard->currentIndex())); - mt.setSymbolfontSymbol(ui->cmbUnicodeSymbol->currentFont().family(), static_cast(ui->cmbEncodingSymbol->currentIndex())); - mt.setSymbolfontGreek(ui->cmbUnicodeGreek->currentFont().family(), static_cast(ui->cmbEncodingGreek->currentIndex())); mt.setFontBlackboardSimulated(ui->chkSimulateBlackboard->isChecked()); if (ui->cmbFont->currentIndex()==1) qDebug()<<"useXITS: "<cmbFont->currentIndex()==2) qDebug()<<"useSTIX: "<cmbFont->currentIndex()==3) qDebug()<<"useASANA: "<cmbFont->currentIndex()==6) qDebug()<<"useXITS: "<tree->clear(); ht.start(); 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); if (i==0) { + ui->labError->clear(); if (mt.getErrorList().size()>0) { - ui->labError->setText(""+mt.getErrorList().join("
    ")+"
    "); + ui->labError->setHtml(""+mt.getErrorList().join("
    ")+"
    "); } else { - ui->labError->setText("OK"); + ui->labError->setHtml("OK"); } } 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("
    "+mt.toHtml(&okh)+"


    "); - qDebug()<<"HTML: ---------------------------------------------\n"<textBrowser->textCursor().insertHtml("
    "+mt.toHtml(&okh)+"


    "); + qDebug()<<"HTML: ---------------------------------------------\n"<Form - - - - true - - - - - 0 - 0 - 748 - 538 - - - - - - - TextLabel - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - + + - 75 true - render times (getSize()+getAscent()/draw()): + HTML output: - - - - - - testset: - - - - - - - -1 - - - 30 - - - - - - - fonts: - - - - - - - 0 - - - - Below - - - - - Below+Math: XITS - - - - - Below+Math: STIX - - - - - Below+Math: ASANA - - - - - - - - size: - - - - - - - 90,30,20,10 - - - - - - - boxes - - - true - - - - - - - anti-aliase - - - true - - - - - - - HQ anti-aliase - - - - - - - Text anti-aliase - - - true - - - - - - - smooth transform - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -195,7 +39,6 @@ - 75 true @@ -229,18 +72,10 @@ - - - - true - - - - 75 true @@ -249,16 +84,61 @@ - - + + - 75 true - HTML output: + node tree: + + + + + + + + + + true + + + + + 0 + 0 + 752 + 552 + + + + + + + TextLabel + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + + + + + + + + + @@ -301,18 +181,14 @@ - - Times New Roman - + - - Times New Roman - + @@ -326,9 +202,7 @@ - - Symbol - + @@ -447,18 +321,14 @@ - - Symbol - + - - Arial - + @@ -510,9 +380,7 @@ - - Times New Roman - + @@ -553,9 +421,7 @@ - - Script - + @@ -596,9 +462,7 @@ - - Script - + @@ -639,9 +503,7 @@ - - Courier New - + @@ -682,9 +544,7 @@ - - Times New Roman - + @@ -725,9 +585,7 @@ - - Arial - + @@ -760,16 +618,18 @@ - - + + + + + true + + - + render times (getSize()+getAscent()/draw()): - - - @@ -782,24 +642,171 @@ - - - - - 75 - true - - - - node tree: - - + + + + + + testset: + + + + + + + -1 + + + 30 + + + + + + + fonts: + + + + + + + 0 + + + + Below + + + + + Below+Math: XITS + + + + + Below+Math: STIX + + + + + Below+Math: ASANA + + + + + Default-Constructed + + + + + Default-Constructed+SetAppFont + + + + + Default-Constructed+SetAppFont+XITS + + + + + useAnyUnicode("Times New Roman", "Times New Roman") + + + + + useAnyUnicode("Arial", "Arial") + + + + + useAnyUnicode("Courier New", "Courier New") + + + + + useAnyUnicode("Comic Sans MS", "Comic Sans MS") + + + + + + + + size: + + + + + + + 90,30,20,10 + + + + + + + boxes + + + true + + + + + + + anti-aliase + + + true + + + + + + + HQ anti-aliase + + + + + + + Text anti-aliase + + + true + + + + + + + smooth transform + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - 75 true @@ -808,17 +815,32 @@ - - - - + + + + true - - - + + + + 0 + 0 + + + + + 16777215 + 48 + + + + QFrame::NoFrame + + + QFrame::Plain diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp index 838d07e2a3..3e34e751b4 100644 --- a/lib/jkqtmathtext/jkqtmathtext.cpp +++ b/lib/jkqtmathtext/jkqtmathtext.cpp @@ -62,9 +62,12 @@ JKQTMathText::JKQTMathText(QObject* parent): fontSize=10; brace_factor=1.04; subsuper_size_factor=0.7; + subsuper_mode_selection_by_size_factor=1.01; italic_correction_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; fontColor=QColor("black"); @@ -77,7 +80,10 @@ JKQTMathText::JKQTMathText(QObject* parent): decoration_width_reduction_Xfactor=0.2; brace_y_shift_factor=0.7;//-1; operatorsubsuper_size_factor=0.65; + operatorsubsuper_distance_factor=0.25; + operatorsubsuper_extraspace_factor=0.5; mathoperator_width_factor=1.5; + bigmathoperator_font_factor=1.8; 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_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_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(); 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(); + 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_shift_factor=settings.value(group+"frac_shift_factor", frac_shift_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_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_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(); @@ -226,14 +237,19 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const settings.setValue(group+ "brace_factor", brace_factor); settings.setValue(group+ "brace_shrink_factor", brace_shrink_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+ "sub_shift_factor", sub_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_shift_factor", frac_shift_factor); settings.setValue(group+ "underbrace_factor", underbrace_factor); settings.setValue(group+ "undersetFactor", underset_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+ "brace_y_shift_factor", brace_y_shift_factor); settings.setValue(group+ "decoration_height_factor", decoration_height_factor); @@ -358,10 +374,8 @@ void JKQTMathText::addReplacementFont(const QString &nonUseFont, const QString & QPair JKQTMathText::getReplacementFont(const QString &nonUseFont, const QString &defaultFont, JKQTMathTextFontEncoding defaultFontEncoding) const { QPair res(defaultFont, defaultFontEncoding); - bool foundFont=false; for (auto it=fontReplacements.begin(); it!=fontReplacements.end(); ++it) { if (it.key().toLower()==nonUseFont.toLower()) { - foundFont=true; res.first=it.value(); res.second=fontEncodingReplacements.value(res.first, res.second); return res; @@ -639,6 +653,16 @@ double JKQTMathText::getSubsuperSizeFactor() const 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) { this->italic_correction_factor = __value; @@ -659,6 +683,26 @@ double JKQTMathText::getOperatorsubsuperSizeFactor() const 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) { this->mathoperator_width_factor = __value; @@ -669,6 +713,16 @@ double JKQTMathText::getMathoperatorWidthFactor() const 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) { this->super_shift_factor = __value; @@ -689,6 +743,26 @@ double JKQTMathText::getSubShiftFactor() const 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) { this->brace_shrink_factor = __value; @@ -1174,6 +1248,17 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType 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") { //std::cout<<"found '[' after '"<addChild(new JKQTMathTextTextNode(this, "[", false)); } } else { + bool subSuperscriptAboveBelowNode=false; //std::cout<<"did not find '{' after '"<addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDvec, new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); - } else if (n0=='c' && n1.isLetter()) { - done=true; - //std::cout<<"found \\v... command\n"; - nl->addChild(new JKQTMathTextInstruction1Node(this, "mathcal", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); - } - } 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))); - } + nl->addChild(new JKQTMathTextSymbolNode(this, currentInstructionName, false)); + + static QSet subsupOperations= (QSet()<<"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"); + if (subsupOperations.contains(currentInstructionName) && parsingMathEnvironment) { + nl->getLastChild()->setSubSuperscriptAboveBelowNode(true); + } + if (currentToken==MTTinstruction && currentTokenName=="limits") { + if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true); + } else if (currentToken==MTTinstruction && currentTokenName=="nolimits") { + if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false); + } else { + getNew=false; } - if (!done) nl->addChild(new JKQTMathTextSymbolNode(this, currentInstructionName, false));//, addWhite)); } } @@ -1387,7 +1464,6 @@ bool JKQTMathText::parse(const QString& text, bool addSpaceBeforeAndAfter){ QString ntext; if (addSpaceBeforeAndAfter) ntext=QString("\\;")+text+QString("\\;"); else ntext=text; - ntext=ntext.remove("\\limits"); if (parsedNode && parseString==ntext) return true; diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h index b98e536cb7..90f7be78b2 100644 --- a/lib/jkqtmathtext/jkqtmathtext.h +++ b/lib/jkqtmathtext/jkqtmathtext.h @@ -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. * You should use fonts that contain as many of the mathematical symbols as possible to ensure good rendering results. * - * setAnyUnicode("Times New Roman", "Times New Roman"):
    \image html jkqtmathtext/jkqtmathparser_timesnewroman.png

    - * setAnyUnicode("Arial", "Arial"):
    \image html jkqtmathtext/jkqtmathparser_arial.png

    - * setAnyUnicode("Courier New", "Courier New"):
    \image html jkqtmathtext/jkqtmathparser_couriernew.png

    - * setAnyUnicode("Comic Sans MS", "Comic Sans MS"):
    \image html jkqtmathtext/jkqtmathparser_comicsans.png

    + * useAnyUnicode("Times New Roman", "Times New Roman"):
    \image html jkqtmathtext/jkqtmathparser_timesnewroman.png

    + * useAnyUnicode("Arial", "Arial"):
    \image html jkqtmathtext/jkqtmathparser_arial.png

    + * useAnyUnicode("Courier New", "Courier New"):
    \image html jkqtmathtext/jkqtmathparser_couriernew.png

    + * useAnyUnicode("Comic Sans MS", "Comic Sans MS"):
    \image html jkqtmathtext/jkqtmathparser_comicsans.png

    * */ void useAnyUnicode(QString timesFont=QString(""), const QString& sansFont=QString(""), JKQTMathTextFontEncoding encodingTimes=JKQTMathTextFontEncoding::MTFEunicode, JKQTMathTextFontEncoding encodingSans=JKQTMathTextFontEncoding::MTFEunicode); @@ -430,11 +430,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { void setBraceFactor(double __value); /** \copydoc brace_factor */ double getBraceFactor() const; - /** \copydoc subsuper_size_factor */ + /** \copydoc subsuper_size_factor */ void setSubsuperSizeFactor(double __value); - /** \copydoc subsuper_size_factor */ + /** \copydoc subsuper_size_factor */ double getSubsuperSizeFactor() const; - /** \copydoc italic_correction_factor */ + /** \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 */ void setItalicCorrectionFactor(double __value); /** \copydoc italic_correction_factor */ double getItalicCorrectionFactor() const; @@ -442,19 +446,39 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { void setOperatorsubsuperSizeFactor(double __value); /** \copydoc operatorsubsuper_size_factor */ double getOperatorsubsuperSizeFactor() const; - /** \copydoc mathoperator_width_factor */ + /** \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 */ void setMathoperatorWidthFactor(double __value); - /** \copydoc mathoperator_width_factor */ + /** \copydoc mathoperator_width_factor */ double getMathoperatorWidthFactor() const; - /** \copydoc super_shift_factor */ + /** \copydoc bigmathoperator_font_factor */ + void setBigMathoperatorFontFactor(double __value); + /** \copydoc bigmathoperator_font_factor */ + double getBigMathoperatorFontFactor() const; + /** \copydoc super_shift_factor */ void setSuperShiftFactor(double __value); - /** \copydoc super_shift_factor */ + /** \copydoc super_shift_factor */ double getSuperShiftFactor() const; - /** \copydoc sub_shift_factor */ + /** \copydoc sub_shift_factor */ void setSubShiftFactor(double __value); - /** \copydoc sub_shift_factor */ + /** \copydoc sub_shift_factor */ double getSubShiftFactor() const; - /** \copydoc brace_shrink_factor */ + /** \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 */ void setBraceShrinkFactor(double __value); /** \copydoc brace_shrink_factor */ double getBraceShrinkFactor() const; @@ -529,10 +553,37 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { double brace_shrink_factor; /** \brief resizing factor for font size in sub-/superscript */ 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: + * + * Default mode: + * \image html jkqtmathtext_superscriptnode_getSizeInternal.png + * \image html jkqtmathtext_subscriptnode_getSizeInternal.png + * + * Special mode: + * + * + * 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 */ 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; + /** \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 * * 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 */ 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: * 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 */ 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 diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp index aa13744a73..4fefc17369 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp @@ -36,12 +36,6 @@ #include -QSet JKQTMathTextListNode::subsupOperations= (QSet()<<"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): JKQTMathTextMultiChildNode(_parent) { @@ -50,7 +44,7 @@ JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent): } JKQTMathTextListNode::~JKQTMathTextListNode() { - clearChildren(true); + clearChildrenImpl(true); } QString JKQTMathTextListNode::getTypeName() const @@ -63,7 +57,12 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro overallHeight=0; baselineHeight=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()); @@ -71,23 +70,30 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro bool wasBrace=false; for (int i=0; i0 && wasBrace) { + if (i>0) { 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(nodes[i]); + JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast(nodes[i]); bool doDraw=true; - JKQTMathTextSymbolNode* smb=dynamic_cast(nodes[i]); // 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 (dynamic_cast(nodes[i])) { + if (nodeI_SuperScript) { if (i+1(nodes[i+1])) { // is this subscript? 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) { overallHeight=overallHeight+bh-baselineHeight; @@ -100,7 +106,7 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro } 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: "<getTypeName()<<" w2="<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; + double w1=0, wsub=0, wsup=0; + double oh1=0, ohsub=0, ohsup=0; + double bh1=0, bhsub=0, bhsup=0; + double sp1=0, spsub=0, spsup=0; nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); //qDebug()<<"sub_super: node: "<getTypeName()<<" w1="<getTypeName()<<" w2="<getTypeName()<<" w3="<getOperatorsubsuperSizeFactor(); - double w1=0, w2=0; - double oh1=0, oh2=0; - double bh1=0, bh2=0; - double sp1=0, sp2=0;//, sp3=0; + double w1=0, wsub=0; + double oh1=0, ohsub=0; + double bh1=0, bhsub=0; + double sp1=0, spsub=0;//, sp3=0; 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 d2=oh2-bh2; - double oh=oh1+oh2; - double sh=oh1-bh1+oh2*1.1; - if (oh>overallHeight) overallHeight=oh; - if (bh1>baselineHeight) baselineHeight=bh1; - if (sh>overallHeight-baselineHeight) { - overallHeight=baselineHeight+sh; + const double newDescent=oh1-bh1+ohsub+subsupershift; + if (newDescent>overallHeight-baselineHeight) { + const double extraDescent=newDescent-(overallHeight-baselineHeight); + overallHeight=overallHeight+extraDescent; } - double w=qMax(w1, w2)+fm.boundingRect(' ').width(); + const double neww=qMax(w1, wsub)+subsuperextrawidth; i++; doDraw=false; - xnew+=w; + xnew+=neww; + //qDebug()<<"### subsupop: sub overallHeight="<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; i0 && wasBrace) { + if (i>0) { 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(nodes[i]); + JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast(nodes[i]); - JKQTMathTextSymbolNode* smb=dynamic_cast(nodes[i]); // 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 (dynamic_cast(nodes[i])) { + if (nodeI_SuperScript) { if (i+1(nodes[i+1])) { // is this subscript? //painter.setPen(QPen("red")); //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++; //painter.setPen(QPen("magenta")); //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++; xnew=qMax(xnew1, xnew2); doDraw=false; } } - } else if (dynamic_cast(nodes[i])) { - if (i+1(nodes[i+1])) { // is this subscript? //painter.setPen(QPen("red")); //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++; //painter.setPen(QPen("magenta")); //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++; xnew=qMax(xnew1, xnew2); doDraw=false; } } } else { - if (smb) { - QString s=smb->getSymbolName(); - if (subsupOperations.contains(s)) { - JKQTMathTextSubscriptNode* subn=nullptr; - if (i+1(nodes[i+1]); - JKQTMathTextSuperscriptNode* supn=nullptr; - if (i+2(nodes[i+2]); - //std::cout<<"symbol ='"<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); - //double xnew1= - double xn1=nodes[i]->draw(painter, xnew+(w-w1)/2.0, ynew, currentEv); - i++; - //double xnew2= - double xn2=subn->getChild()->draw(painter, xnew+(w-w2)/2.0, ynew+bh2+d1, ev); - i++; - //double xnew3= - double xn3=supn->getChild()->draw(painter, xnew+(w-w3)/2.0, ynew-bh1-d3-fm.xHeight()/4.0, ev); - doDraw=false; - xnew=qMax(qMax(xn1, xn2), xn3)+fm.boundingRect(' ').width(); - } else if (subn) { // is this subscript and not superscript? - JKQTMathTextEnvironment ev=currentEv; - ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); - double w1=0, w2=0; - double oh1=0, oh2=0; - double bh1=0, bh2=0, sp=0; - nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); - subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp); - double d1=oh1-bh1; - //double d2=oh2-bh2; + if (nodes[i]->isSubSuperscriptAboveBelowNode()) { + JKQTMathTextSubscriptNode* subn=nullptr; + JKQTMathTextSuperscriptNode* supn=nullptr; + JKQTMathTextSubscriptNode* subn2=nullptr; + JKQTMathTextSuperscriptNode* supn2=nullptr; + if (i+1(nodes[i+1]); + supn=dynamic_cast(nodes[i+1]); + } + if (i+2(nodes[i+2]); + supn2=dynamic_cast(nodes[i+2]); + } + //std::cout<<"symbol ='"<getOperatorsubsuperSizeFactor(); + double w1=0, wsub=0, wsup=0; + 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); - //double xnew1= - double xn2=nodes[i]->draw(painter, xnew+(w-w1)/2.0, ynew, currentEv); - i++; - //double xnew2= - double xn1=subn->getChild()->draw(painter, xnew+(w-w2)/2.0, ynew+bh2+d1, ev)+fm.boundingRect(' ').width(); - doDraw=false; - //xnew+=w; - xnew=qMax(xn1, xn2); - } else if (supn) { // is this subscript and superscript? - JKQTMathTextEnvironment ev=currentEv; - ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); - double w1=0, w3=0; - double oh1=0, oh3=0; - double bh1=0, bh3=0, sp; - nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); - supn->getChild()->getSize(painter, ev, w3, bh3, oh3, sp); - //double d1=oh1-bh1; - //double d2=oh2-bh2; - double d3=oh3-bh3; + const double neww=qMax(qMax(w1, wsub), wsup)+subsuperextrawidth; + //double xnew1= + const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv); + i++; + //double xnew2= + const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0, ynew+bhsub+descent1+subsupershift, ev); + i++; + //double xnew3= + const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0, ynew-bh1-descent3-subsupershift, ev); + doDraw=false; + xnew=qMax(qMax(xn1, xnsub), xnsup)+subsuperextrawidth/2.0; + } else if (subn) { // is this subscript and no following superscript? + JKQTMathTextEnvironment ev=currentEv; + ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); + double w1=0, wsub=0; + double oh1=0, ohsub=0; + double bh1=0, bhsub=0, sp=0, spsub=0; + nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); + subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub); + const double descent1=oh1-bh1; + //double d2=oh2-bh2; - double w=qMax(w1, w3); - //double xnew1= - double xn1=nodes[i]->draw(painter, xnew+(w-w1)/2.0, ynew, currentEv); - i++; - //double xnew3= - double xn3=supn->getChild()->draw(painter, xnew+(w-w3)/2.0, ynew-bh1-d3-fm.xHeight()/4.0, ev); - doDraw=false; - xnew=qMax(xn1, xn3)+fm.boundingRect(' ').width(); - } + const double neww=qMax(w1, wsub)+subsuperextrawidth; + //double xnew1= + const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv); + i++; + //double xnew2= + const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0, ynew+bhsub+descent1+subsupershift, ev)+subsupershift; + doDraw=false; + //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 (idraw(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(nodes[i]); } return xnew; } @@ -437,7 +472,7 @@ int JKQTMathTextListNode::childCount() const } -void JKQTMathTextListNode::clearChildren(bool deleteChildren) +void JKQTMathTextListNode::clearChildrenImpl(bool deleteChildren) { if (deleteChildren) { for (int i=0; i nodes; - /** \brief the instructions in this can have the sub-script/superscript set below/above, not besides the node */ - static QSet subsupOperations; + private: + /** \brief internal implementation of clearChildren() that is non-virtual, so can be used in the destructor */ + void clearChildrenImpl(bool deleteChildren); }; #endif // JKQTMATHTEXTLISTNODE_H diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp index 8d5e478f8a..fe72b22894 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp @@ -41,7 +41,8 @@ JKQTMathTextNode::JKQTMathTextNode(JKQTMathText *_parent): parentMathText(_parent), parentNode(nullptr), - drawBoxes(false) + drawBoxes(false), + subSuperscriptAboveBelowNode(false) { } @@ -140,6 +141,16 @@ const JKQTMathTextNode *JKQTMathTextNode::getParentNode() const return parentNode; } +bool JKQTMathTextNode::isSubSuperscriptAboveBelowNode() const +{ + return subSuperscriptAboveBelowNode; +} + +void JKQTMathTextNode::setSubSuperscriptAboveBelowNode(bool __value) +{ + subSuperscriptAboveBelowNode=__value; +} + JKQTMathTextSingleChildNode::JKQTMathTextSingleChildNode(JKQTMathTextNode *_child, JKQTMathText *parentMathText): JKQTMathTextNode(parentMathText), child(_child) @@ -302,6 +313,26 @@ QList JKQTMathTextMultiChildNode::getChildren() const 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) { 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) { JKQTMathTextNode::setDrawBoxes(draw); diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextnode.h index 28662f8e91..541a93ce3f 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextnode.h +++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.h @@ -84,6 +84,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode { JKQTMathTextNode* getParentNode(); /** \copydoc parentNode */ const JKQTMathTextNode* getParentNode() const; + /** \copydoc subSuperscriptAboveBelowNode */ + bool isSubSuperscriptAboveBelowNode() const; + /** \copydoc subSuperscriptAboveBelowNode */ + void setSubSuperscriptAboveBelowNode(bool __value); + protected: /** \brief determine the size of the node, overwrite this function in derived classes * @@ -104,6 +109,12 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode { JKQTMathTextNode* parentNode; /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ 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 * * \param painter QPainter to use @@ -189,6 +200,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMultiChildNode: public JKQTMathTextNod /** \brief returns the i-th child node */ 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 */ 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 */ 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 */ virtual void clearChildren(bool deleteChildren=true) =0; diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp index 0a55b1e914..8742a3ad78 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp @@ -49,16 +49,19 @@ void JKQTMathTextSuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathTex JKQTMathTextEnvironment ev=currentEv; ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor(); const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); - const QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); - double cstrikeoutPos=0; - getChild()->getSize(painter, ev, width, baselineHeight, overallHeight, cstrikeoutPos); - double shift=parentMathText->getSuperShiftFactor()*tbr.height(); + const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); + double cStrikeoutPos=0, cWidth=0, cBaselineHeight=0, cOverallHeight=0; + getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); + const double childDescent=cOverallHeight-cBaselineHeight; + double shiftToChildBottom=parentMathText->getSuperShiftFactor()*tbr_of_letterM.height(); - if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { - shift=prevNodeSize->baselineHeight-(overallHeight-baselineHeight)-shift; + if (prevNodeSize!=nullptr) { + 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; else strikeoutPos=fm.strikeOutPos(); 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; getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); - QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); - QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); - double shift=parentMathText->getSuperShiftFactor()*tbr.height(); + const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device()); + QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); + const double childDescent=cOverallHeight-cBaselineHeight; + double shiftToChildBottom=parentMathText->getSuperShiftFactor()*tbr_of_letterM.height(); - if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { - shift=prevNodeSize->baselineHeight-(cOverallHeight-cBaselineHeight)-shift; + if (prevNodeSize!=nullptr) { + const double modifiedShift=prevNodeSize->baselineHeight-childDescent-parentMathText->getSpecialSuperShiftFactor()*cBaselineHeight-childDescent; + if (modifiedShift>shiftToChildBottom) shiftToChildBottom=modifiedShift; } - double yshift=shift+cOverallHeight-cBaselineHeight; double xx=x; 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) { JKQTMathTextEnvironment ev=currentEv; 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()); - QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); - double shift=parentMathText->getSubShiftFactor()*tbr.height(); - - if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { - shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); + if (prevNodeSize!=nullptr) { + //qDebug()<<"oldshift="<overallHeight="<overallHeight<<", prevNodeSize->baselineHeight="<baselineHeight; + 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="<strikeoutPos; else strikeoutPos=fm.strikeOutPos(); + width=cWidth; 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); JKQTMathTextEnvironment ev=currentEv; ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor(); - QFontMetricsF fm(ev.getFont(parentMathText), painter.device()); - QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); + const QFontMetricsF fm(ev.getFont(parentMathText), painter.device()); + const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device()); - double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; - getChild()->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - double shift=parentMathText->getSubShiftFactor()*tbr.height(); + double cWidth=0, cBaselineHeight=0, cOverallHeight=0, cStrikeoutPos=0; + getChild()->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); + double shift_to_childBaseline=cBaselineHeight-parentMathText->getSubShiftFactor()*tbr_of_letterM.height(); - if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { + if (prevNodeSize!=nullptr) { //qDebug()<<"oldshift="<overallHeight="<overallHeight<<", prevNodeSize->baselineHeight="<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="<draw(painter, xx, y+shift_to_childBaseline, ev);//+0.5*fm.boundingRect("A").width(); } QString JKQTMathTextSubscriptNode::getTypeName() const diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp index 61b5031154..e169713ad9 100644 --- a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp @@ -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 == "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 == "bigcap") { props.symbol = QChar(0x22C2); 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; 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 == "bighat") { props.symbol = QChar(0x22C0); 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; } + 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; } else if (n == "int") { props.symbol = QChar(0x222B); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } else {return false;} return true; @@ -653,7 +653,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps& props.font = fnt.first; if (fnt.second==MTFEunicode) { 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; } } else if (fnt.second==MTFEunicodeLimited) { @@ -661,7 +661,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps& if (!getUnicodeBaseSymbolProp(props, n) && !getGreekSymbolProp(props, n, currentEv, mathFontFactor)) { if (fntSym.second==MTFEunicode) { 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; } } else if (fntSym.second==MTFEunicodeLimited) { @@ -684,7 +684,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps& if (!getWinSymbolProp(props, n, currentEv, mathFontFactor)) { if (fntSym.second==MTFEunicode) { 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; } } else if (fntSym.second==MTFEunicodeLimited) { @@ -707,7 +707,7 @@ bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps& if (!getStandardTextSymbolProp(props, n)) { if (fntSym.second==MTFEunicode) { 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; } } else if (fntSym.second==MTFEunicodeLimited) { @@ -1271,12 +1271,14 @@ bool JKQTMathTextSymbolNode::toHtml(QString &html, JKQTMathTextEnvironment curre QMap::iterator itS = entitylut.find(symbolName); if (itS!=entitylut.end()) { s=itS.value(); } - else if (symbolName == "sum") { ev.fontSize*=1.7; s="∑"; } - else if (symbolName == "prod") { ev.fontSize*=1.7; s="∏"; } - else if (symbolName == "bigcap") { ev.fontSize*=1.7; s="∩"; } - else if (symbolName == "bigcup") { ev.fontSize*=1.7; s="∪"; } - else if (symbolName == "bigvee") { ev.fontSize*=1.7; s="∨"; } - else if (symbolName == "bighat") { ev.fontSize*=1.7; s="∧"; } + else if (symbolName == "sum") { + ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="∑"; } + else if (symbolName == "prod") { + ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="∏"; } + else if (symbolName == "bigcap") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="∩"; } + else if (symbolName == "bigcup") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="∪"; } + else if (symbolName == "bigvee") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="∨"; } + else if (symbolName == "bighat") { ev.fontSize*=parentMathText->getBigMathoperatorFontFactor(); s="∧"; } else ok=false; if (ok) html=html+ev.toHtmlStart(defaultEv)+s+ev.toHtmlAfter(defaultEv);