diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index f1e11c9beb..766adfcf4d 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -26,8 +26,9 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
  • NEW: new "seaborn" style for plots
  • NEW/BREAKING CHANGE: changed JKQTPColorDerivationMode into a struct, which extends its capabilities above the previously available few enum-items
  • NEW: added debug-feature to show boxes around text in the plot
  • -
  • NEW: JKQTMathText supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve
  • +
  • NEW: JKQTMathText: now supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve
  • NEW: JKQTMathText: reworked drawing of decorations: improved appearance and positioning!
  • +
  • NEW: JKQTMathText: reworked code structure: broke up large, single CPP-files into several smaller files!
  • \subsection page_whatsnew_TRUNK_DOWNLOAD trunk: Download diff --git a/examples/jkqtmathtext_simpletest/README.md b/examples/jkqtmathtext_simpletest/README.md index 9c579ea66c..3c238256f3 100644 --- a/examples/jkqtmathtext_simpletest/README.md +++ b/examples/jkqtmathtext_simpletest/README.md @@ -23,7 +23,7 @@ And the source code of the main application is (see [`jkqtmathtext_simpletest.cp #include #include #include -#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtmathtext/jkqtmathtextlabel.h" int main(int argc, char* argv[]) { diff --git a/examples/jkqtmathtext_simpletest/jkqtmathtext_simpletest.cpp b/examples/jkqtmathtext_simpletest/jkqtmathtext_simpletest.cpp index b6314f204e..5680ca3f6a 100644 --- a/examples/jkqtmathtext_simpletest/jkqtmathtext_simpletest.cpp +++ b/examples/jkqtmathtext_simpletest/jkqtmathtext_simpletest.cpp @@ -7,7 +7,7 @@ #include #include #include -#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtmathtext/jkqtmathtextlabel.h" int main(int argc, char* argv[]) { diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp index 58bdef11c2..d93c50aebe 100644 --- a/examples/jkqtmathtext_test/testform.cpp +++ b/examples/jkqtmathtext_test/testform.cpp @@ -1,6 +1,16 @@ #include "testform.h" #include "ui_testform.h" #include +#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h" +#include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h" +#include "jkqtmathtext/nodes/jkqtmathtextfracnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextlistnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextmatrixnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsqrtnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h" TestForm::TestForm(QWidget *parent) : @@ -8,24 +18,24 @@ TestForm::TestForm(QWidget *parent) : ui(new Ui::TestForm) { ui->setupUi(this); - ui->cmbTestset->addItem("fonts", "rm: \\textrm{ABCabc123}, sf: \\textsf{ABCabc123}, tt: \\texttt{ABCabc123}, cal: \\textcal{ABCabc123}, scr: \\textscr{ABCabc123}, bb: \\textbb{ABCabc123}, frak: \\textfrak{ABCabc123}, "); + ui->cmbTestset->addItem("text: fonts", "rm: \\textrm{ABCabc123}, sf: \\textsf{ABCabc123}, tt: \\texttt{ABCabc123}, cal: \\textcal{ABCabc123}, scr: \\textscr{ABCabc123}, bb: \\textbb{ABCabc123}, frak: \\textfrak{ABCabc123}, "); ui->cmbTestset->addItem("math-fonts", "rm: $\\mathrm{ABCabc123}$, sf: $\\mathsf{ABCabc123}$, tt: $\\mathtt{ABCabc123}$, cal: $\\mathcal{ABCabc123}$, scr: $\\mathscr{ABCabc123}$, bb: $\\mathbb{ABCabc123}$, frak: $\\mathfrak{ABCabc123}$, "); - ui->cmbTestset->addItem("simple relations", "$a{\\leq}b$, $a{\\geq}b$, $a{\\equiv}b$, $a=b$, $a{\\neq}b$, $ab$"); - ui->cmbTestset->addItem("simple relations in different modes", "math: $a{\\leq}b$, math/no braces: $a\\leq b$, no math: a{\\leq}b, no math/no braces: a\\leq b"); - ui->cmbTestset->addItem("named symbols 1", "ll: $\\ll$\\ gg: $\\gg$\\ leq: $\\leq$\\ geq: $\\geq$\\ pm: $\\pm$\\ mp: $\\mp$\\ "); - ui->cmbTestset->addItem("named symbols 2", "nexists: $\\nexists$\\ ni: $\\ni$\\ notni: $\\notni$\\ circ: $\\circ$\\ sim: $\\sim$\\ emptyset: $\\emptyset$\\ odot: $\\odot$\\ ominus: $\\ominus$\\ subsetnot: $\\subsetnot$\\ bot: $\\bot$"); - ui->cmbTestset->addItem("named symbols 3", "leftharpoonup: $\\leftharpoonup$\\ rightharpoonup: $\\rightharpoonup$\\ upharpoonleft: $\\upharpoonleft$\\ downharpoonleft: $\\downharpoonleft$\\ leftrightharpoon: $\\leftrightharpoon$\\ rightleftharpoon: $\\rightleftharpoon$"); - ui->cmbTestset->addItem("named symbols 4", "coprod: $\\coprod$\\ leftharpoondown: $\\leftharpoondown$\\ rightharpoondown: $\\rightharpoondown$\\ upharpoonright: $\\upharpoonright$\\ downharpoonright: $\\downharpoonright$\\ nwarrow: $\\nwarrow$\\ nearrow: $\\nearrow$\\ "); - ui->cmbTestset->addItem("named symbols 5", "searrow: $\\searrow$\\ swarrow: $\\swarrow$\\ mapsto: $\\mapsto$\\ div: $\\div$\\ multimap: $\\multimap$\\ maporiginal: $\\maporiginal$\\ mapimage: $\\mapimage$\\ "); - ui->cmbTestset->addItem("named symbols 6", "times: $\\times$\\ ast: $\\ast$\\ star: $\\star$\\ propto: $\\propto$\\ bullet: $\\bullet$\\ neq: $\\neq$\\ ne: $\\ne$\\ equiv: $\\equiv$\\ approx: $\\approx$\\ otimes: $\\otimes$\\ oplus: $\\oplus$"); - ui->cmbTestset->addItem("named symbols 7", "oslash: $\\oslash$\\ cap: $\\cap$\\ land: $\\land$\\ cup: $\\cup$\\ lor: $\\lor$\\ supset: $\\supset$\\ supseteq: $\\supseteq$\\ supsetnot: $\\supsetnot$\\ subset: $\\subset$"); - ui->cmbTestset->addItem("named symbols 8", "subseteq: $\\subseteq$\\ in: $\\in$\\ notin: $\\notin$\\ cdot: $\\cdot$\\ wedge: $\\wedge$\\ vee: $\\vee$\\ cong: $\\cong$\\ bot: $\\bot$"); - ui->cmbTestset->addItem("symbols", "$\\ll\\gg\\leq\\geq\\leftrightarrow\\leftarrow\\rightarrow\\to\\uparrow\\downarrow\\updownarrow\\Leftrightarrow\\iff\\Leftarrow\\Rightarrow\\Uparrow\\Downarrow\\Updownarrow\\pm\\mp\\nexists\\ni\\notni\\circ\\sim\\emptyset\\odot\\ominus\\subsetnot\\bot\\leftharpoonup\\rightharpoonup\\upharpoonleft\\downharpoonleft\\leftrightharpoon\\rightleftharpoon\\coprod\\leftharpoondown\\rightharpoondown\\upharpoonright\\downharpoonright\\nwarrow\\nearrow\\searrow\\swarrow\\mapsto\\div\\multimap\\maporiginal\\mapimage\\times\\propto\\bullet\\neq\\ne\\equiv\\approx\\otimes\\oplus\\oslash\\cap\\land\\cup\\lor\\supset\\supseteq\\supsetnot\\subset\\subseteq\\in\\notin\\cdot\\wedge\\vee\\cong\\bot$"); - ui->cmbTestset->addItem("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("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("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("like in label at bottom (no MM)", "\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)"); - ui->cmbTestset->addItem("like in label at bottom (MM)", "$\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)$"); + ui->cmbTestset->addItem("math: simple relations", "$a{\\leq}b$, $a{\\geq}b$, $a{\\equiv}b$, $a=b$, $a{\\neq}b$, $ab$"); + ui->cmbTestset->addItem("text/math: simple relations in different modes", "math: $a{\\leq}b$, math/no braces: $a\\leq b$, no math: a{\\leq}b, no math/no braces: a\\leq b"); + ui->cmbTestset->addItem("math: named symbols 1", "ll: $\\ll$\\ gg: $\\gg$\\ leq: $\\leq$\\ geq: $\\geq$\\ pm: $\\pm$\\ mp: $\\mp$\\ "); + ui->cmbTestset->addItem("math: named symbols 2", "nexists: $\\nexists$\\ ni: $\\ni$\\ notni: $\\notni$\\ circ: $\\circ$\\ sim: $\\sim$\\ emptyset: $\\emptyset$\\ odot: $\\odot$\\ ominus: $\\ominus$\\ subsetnot: $\\subsetnot$\\ bot: $\\bot$"); + ui->cmbTestset->addItem("math: named symbols 3", "leftharpoonup: $\\leftharpoonup$\\ rightharpoonup: $\\rightharpoonup$\\ upharpoonleft: $\\upharpoonleft$\\ downharpoonleft: $\\downharpoonleft$\\ leftrightharpoon: $\\leftrightharpoon$\\ rightleftharpoon: $\\rightleftharpoon$"); + ui->cmbTestset->addItem("math: named symbols 4", "coprod: $\\coprod$\\ leftharpoondown: $\\leftharpoondown$\\ rightharpoondown: $\\rightharpoondown$\\ upharpoonright: $\\upharpoonright$\\ downharpoonright: $\\downharpoonright$\\ nwarrow: $\\nwarrow$\\ nearrow: $\\nearrow$\\ "); + ui->cmbTestset->addItem("math: named symbols 5", "searrow: $\\searrow$\\ swarrow: $\\swarrow$\\ mapsto: $\\mapsto$\\ div: $\\div$\\ multimap: $\\multimap$\\ maporiginal: $\\maporiginal$\\ mapimage: $\\mapimage$\\ "); + ui->cmbTestset->addItem("math: named symbols 6", "times: $\\times$\\ ast: $\\ast$\\ star: $\\star$\\ propto: $\\propto$\\ bullet: $\\bullet$\\ neq: $\\neq$\\ ne: $\\ne$\\ equiv: $\\equiv$\\ approx: $\\approx$\\ otimes: $\\otimes$\\ oplus: $\\oplus$"); + ui->cmbTestset->addItem("math: named symbols 7", "oslash: $\\oslash$\\ cap: $\\cap$\\ land: $\\land$\\ cup: $\\cup$\\ lor: $\\lor$\\ supset: $\\supset$\\ supseteq: $\\supseteq$\\ supsetnot: $\\supsetnot$\\ subset: $\\subset$"); + ui->cmbTestset->addItem("math: named symbols 8", "subseteq: $\\subseteq$\\ in: $\\in$\\ notin: $\\notin$\\ cdot: $\\cdot$\\ wedge: $\\wedge$\\ vee: $\\vee$\\ cong: $\\cong$\\ bot: $\\bot$"); + ui->cmbTestset->addItem("math: symbols", "$\\ll\\gg\\leq\\geq\\leftrightarrow\\leftarrow\\rightarrow\\to\\uparrow\\downarrow\\updownarrow\\Leftrightarrow\\iff\\Leftarrow\\Rightarrow\\Uparrow\\Downarrow\\Updownarrow\\pm\\mp\\nexists\\ni\\notni\\circ\\sim\\emptyset\\odot\\ominus\\subsetnot\\bot\\leftharpoonup\\rightharpoonup\\upharpoonleft\\downharpoonleft\\leftrightharpoon\\rightleftharpoon\\coprod\\leftharpoondown\\rightharpoondown\\upharpoonright\\downharpoonright\\nwarrow\\nearrow\\searrow\\swarrow\\mapsto\\div\\multimap\\maporiginal\\mapimage\\times\\propto\\bullet\\neq\\ne\\equiv\\approx\\otimes\\oplus\\oslash\\cap\\land\\cup\\lor\\supset\\supseteq\\supsetnot\\subset\\subseteq\\in\\notin\\cdot\\wedge\\vee\\cong\\bot$"); + 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 0", "text"); ui->cmbTestset->addItem("text 1", "text \\mathbf{bold}"); ui->cmbTestset->addItem("text 2", "text \\mathbf{bold}\\textcolor{red}{RED}"); @@ -33,76 +43,88 @@ TestForm::TestForm(QWidget *parent) : 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("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("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("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("f() test", "$f(\\vec{x})=\\frac{1}{\\sqrt{2\\pi\\cdot\\sigma^2}}\\exp\\left(-\\frac{(\\vec{x}-\\vec{x}_0)^2}{\\sigma^2}\\right)$"); - ui->cmbTestset->addItem("chi^2 test", "$\\vec{p}^\\ast=\\argmax\\limits_{\\vec{p}}\\chi^2=\\argmax\\limits_{\\vec{p}}\\sum\\limits_{i=1}^N\\left|\\frac{\\hat{f}_i-f(x_i;\\vec{p})}{\\sigma_i}\\right|^2$"); - ui->cmbTestset->addItem("symbol test", "\\vdots\\cdots\\ddots\\iddots\\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\sum\\int \\iint \\oint \\prod \\leftrightarrow \\leftarrow\\Leftarrow\\rightarrow\\Rightarrow\\pm\\mp\\leq\\geq\\ll\\gg\\hbar\\euro\\bbC\\bbH\\bbN\\bbP\\bbQ\\bbZ\\bbR\\Angstrom\\Alef\\Bet\\Gimel\\Dalet\\nexists\\ni\\notni\\circ\\tilde\\oiint\\oiiint\\emptyset\\odot\\ominus\\subsetnot\\DC\\bot\\cdots\\perthousand\\leftharpoonup\\rightharpoonup \\upharpoonleft \\downharpoonleft \\leftrightharpoon \\rightleftharpoon \\coprod \\leftharpoondown \\rightharpoondown \\nwarrow \\nearrow \\mapsto \\cent \\pound \\yen \\div \\multimap \\maporiginal \\mapimage \\bigcap \\bigcup \\benzene \\times \\cdot \\propto \\equiv \\Im \\Re \\ "); - ui->cmbTestset->addItem("arrowtest 1", "$\\leftarrow \\longleftarrow \\Leftarrow \\Longleftarrow \\rightarrow \\longrightarrow \\Rightarrow \\Longrightarrow \\uparrow \\Uparrow \\downarrow \\Downarrow \\leftrightarrow \\Leftrightarrow \\longleftrightarrow \\Longleftrightarrow$"); - ui->cmbTestset->addItem("arrowtest 2", "$\\nwarrow \\nearrow \\searrow \\swarrow \\mapsto \\leftharpoonup \\rightharpoonup \\upharpoonleft \\downharpoonleft \\leftrightharpoon \\rightleftharpoon \\leftharpoondown \\rightharpoondown \\upharpoonright \\downharpoonright $"); - ui->cmbTestset->addItem("math: greek letters", "$\\alpha\\beta\\gamma\\delta\\epsilon\\varepsilon\\zeta\\eta\\theta\\vartheta\\iota\\kappa\\lambda\\mu\\nu\\xi\\pi\\varpi\\rho\\varrho\\sigma\\varsigma\\tau\\upsilon\\phi\\varphi\\chi\\psi\\omega\\Omega\\Gamma\\Delta\\Theta\\Lambda\\Xi\\Pi\\Sigma\\Upsilon\\Phi\\Psi$"); - ui->cmbTestset->addItem("text: greek letters", "\\alpha\\beta\\gamma\\delta\\epsilon\\varepsilon\\zeta\\eta\\theta\\vartheta\\iota\\kappa\\lambda\\mu\\nu\\xi\\pi\\varpi\\rho\\varrho\\sigma\\varsigma\\tau\\upsilon\\phi\\varphi\\chi\\psi\\omega\\Omega\\Gamma\\Delta\\Theta\\Lambda\\Xi\\Pi\\Sigma\\Upsilon\\Phi\\Psi"); - ui->cmbTestset->addItem("math: blackboard", "$\\mathbb{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: bf", "$\\mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: it", "$\\mathit{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: frak", "$\\mathfrak{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: sf", "$\\mathsf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: rm", "$\\mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: cal", "$\\mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: script", "$\\mathscr{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("math: tt", "$\\mathtt{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); - ui->cmbTestset->addItem("bf", "\\textbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("it", "\\textit{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("frak", "\\textfrak{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("sf", "\\textsf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("rm", "\\textrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("cal", "\\textcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("script", "\\textscr{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("tt", "\\texttt{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); - ui->cmbTestset->addItem("subscript test", "$r_{123}\\ \\ r_{\\frac{1}{2}}$"); - ui->cmbTestset->addItem("subscript0 test", "$r_{123}$"); - ui->cmbTestset->addItem("subscript1 test", "$r_{123}\\ $"); - ui->cmbTestset->addItem("subscript2 test", "$r_{123}\\ \\ $"); - ui->cmbTestset->addItem("subscript3 test", "$r_{123}r_{\\frac{1}{2}}$"); - ui->cmbTestset->addItem("superscript test", "$r^{123}\\ \\ r^{\\frac{1}{2}}$"); - ui->cmbTestset->addItem("superscript0 test", "$r^{123}$"); - ui->cmbTestset->addItem("superscript1 test", "$r^{123}\\ $"); - ui->cmbTestset->addItem("superscript2 test", "$r^{123}\\ \\ $"); - ui->cmbTestset->addItem("superscript3 test", "$r^{123}r^{\\frac{1}{2}}$"); - ui->cmbTestset->addItem("asuperscript test", "$a^{123}\\ \\ a^{\\frac{1}{2}}$"); - ui->cmbTestset->addItem("asuperscript0 test", "$a^{123}$"); - ui->cmbTestset->addItem("gsuperscript1 test", "$g^{123}\\ $"); - ui->cmbTestset->addItem("gsuperscript2 test", "$g^{123}\\ \\ $"); - ui->cmbTestset->addItem("gsuperscript3 test", "$g^{123}g^{\\frac{1}{2}}$"); - ui->cmbTestset->addItem("subsuperscript test", "$r_{123}^2$\\ \\ $r^2_{123}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_{123}^2$\\ \\ $\\left(\\stackrel{a}{b}\\right)^2_{123}$\\ \\ $r_{\\frac{1}{2}}^2$\\ \\ $r^2_{\\frac{1}{2}}$\\ \\ $r^{\\frac{1}{2}}_2$\\ \\ $r_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)^{\\frac{1}{2}}_2$"); - ui->cmbTestset->addItem("frac test", "$\\frac{a}{b}+\\frac{g}{a}-\\frac{a^2}{b^2}\\cdot\\frac{a^2}{b^{\\frac{1}{2}}}$"); - ui->cmbTestset->addItem("tfrac test", "$\\tfrac{a}{b}+\\tfrac{g}{a}-\\tfrac{a^2}{b^2}\\cdot\\tfrac{a^2}{b^{\\tfrac{1}{2}}}$"); - ui->cmbTestset->addItem("dfrac test", "$\\dfrac{a}{b}+\\dfrac{g}{a}-\\dfrac{a^2}{b^2}\\cdot\\dfrac{a^2}{b^{\\dfrac{1}{2}}}$"); - ui->cmbTestset->addItem("sfrac test", "$\\sfrac{a}{b}+\\sfrac{g}{a}-\\sfrac{a^2}{b^2}\\cdot\\sfrac{a^2}{b^{\\sfrac{1}{2}}}$"); - ui->cmbTestset->addItem("stfrac test", "$\\stfrac{a}{b}+\\stfrac{g}{a}-\\stfrac{a^2}{b^2}\\cdot\\stfrac{a^2}{b^{\\stfrac{1}{2}}}$"); - ui->cmbTestset->addItem("number fractions test", "frac: \\frac{1}{2}, \\frac{3}{4},\\ \\ \\ tfrac: \\tfrac{1}{2}, \\tfrac{3}{4},\\ \\ \\ sfrac: \\sfrac{1}{2}, \\sfrac{3}{4},\\ \\ \\ stfrac: \\stfrac{1}{2}, \\stfrac{3}{4},\\ \\ \\ "); - ui->cmbTestset->addItem("stackrel test", "$\\stackrel{a}{b}+\\stackrel{g}{a}-\\stackrel{a^2}{b^2}\\cdot\\stackrel{a^2}{b^{\\stackrel{1}{2}}}$"); - ui->cmbTestset->addItem("brace0 test", "\\langle\\langle -- $\\langle\\langle$"); - ui->cmbTestset->addItem("brace1 test", "\\langle\\langle r^{123} -- $\\langle\\langle r^{123}$"); - ui->cmbTestset->addItem("brace2 test", "\\langle\\langle r^{123}\\rangle\\rangle -- $\\langle\\langle r^{123}\\rangle\\rangle$"); - ui->cmbTestset->addItem("brace3 test", "\\left\\langle r^{123}\\right\\rangle -- $\\left\\langle r^{123}\\right\\rangle$"); - ui->cmbTestset->addItem("brace4 test", "\\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle -- $\\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle$"); - ui->cmbTestset->addItem("brace5 test: ( )", "\\left(\\left(\\left( r^{123}\\right)\\right)\\right) -- $\\left(\\left(\\left( r^{123}\\right)\\right)\\right)$"); - ui->cmbTestset->addItem("brace6 test: [ ]", "\\left[\\left[\\left[ r^{123}\\right]\\right]\\right] -- $\\left[\\left[\\left[ r^{123}\\right]\\right]\\right]$"); - ui->cmbTestset->addItem("brace7 test: { }", "\\left\\{\\left\\{\\left\\{ r^{123}\\right\\}\\right\\}\\right\\} -- $\\left\\{\\left\\{\\left\\{ r^{123}\\right\\}\\right\\}\\right\\}$"); - ui->cmbTestset->addItem("brace8 test: || ||", "\\left\\|\\left\\|\\left\\| r^{123}\\right\\|\\right\\|\\right\\| -- $\\left\\|\\left\\|\\left\\| r^{123}\\right\\|\\right\\|\\right\\|$"); - ui->cmbTestset->addItem("brace9 test: | |", "\\left|\\left|\\left| r^{123}\\right|\\right|\\right| -- $\\left|\\left|\\left| r^{123}\\right|\\right|\\right|$"); - ui->cmbTestset->addItem("brace10 test", "\\left\\{\\left[\\left( r^{123}\\right)\\right]\\right\\} -- $\\left\\{\\left[\\left( r^{123}\\right)\\right]\\right\\}$"); - ui->cmbTestset->addItem("brace11 test: floor", "\\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor -- $\\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor$"); - ui->cmbTestset->addItem("brace12 test: ceil", "\\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil -- $\\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil$"); - ui->cmbTestset->addItem("brace13 test: non-left/right ( )", "(((r^{123}))) -- $(((r^{123})))$"); - ui->cmbTestset->addItem("brace14 test: non-left/right [ ]", "[[[r^{123}]]] -- $[[[r^{123}]]]$"); - ui->cmbTestset->addItem("brace15 test: non-left/right { }", "\\{\\{\\{r^{123}\\}\\}\\} -- $\\{\\{\\{ r^{123}\\}\\}\\}$"); - ui->cmbTestset->addItem("brace16 test: non-left/right | |", "|||r^{123}||| -- $|||r^{123}|||$"); - ui->cmbTestset->addItem("brace17 test: non-left/right { | }", "\\{r^{123}|r\\equiv 5\\} -- $\\{r^{123}|r\\equiv 5\\}$"); - ui->cmbTestset->addItem("sub-, superscript test", "r^{1234}_{321} r_{321}^{1234} -- $r^{1234}_{321} r_{321}^{1234} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$"); - ui->cmbTestset->addItem("super-, subscript test", "r^{123}_{4321} r_{4321}^{123} -- $r^{123}_{4321} r_{4321}^{123} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$"); + 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$"); + ui->cmbTestset->addItem("math: f() test", "$f(\\vec{x})=\\frac{1}{\\sqrt{2\\pi\\cdot\\sigma^2}}\\exp\\left(-\\frac{(\\vec{x}-\\vec{x}_0)^2}{\\sigma^2}\\right)$"); + ui->cmbTestset->addItem("math: chi^2 test", "$\\vec{p}^\\ast=\\argmax\\limits_{\\vec{p}}\\chi^2=\\argmax\\limits_{\\vec{p}}\\sum\\limits_{i=1}^N\\left|\\frac{\\hat{f}_i-f(x_i;\\vec{p})}{\\sigma_i}\\right|^2$"); + ui->cmbTestset->addItem("text: symbol test", "\\vdots\\cdots\\ddots\\iddots\\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\sum\\int \\iint \\oint \\prod \\leftrightarrow \\leftarrow\\Leftarrow\\rightarrow\\Rightarrow\\pm\\mp\\leq\\geq\\ll\\gg\\hbar\\euro\\bbC\\bbH\\bbN\\bbP\\bbQ\\bbZ\\bbR\\Angstrom\\Alef\\Bet\\Gimel\\Dalet\\nexists\\ni\\notni\\circ\\tilde\\oiint\\oiiint\\emptyset\\odot\\ominus\\subsetnot\\DC\\bot\\cdots\\perthousand\\leftharpoonup\\rightharpoonup \\upharpoonleft \\downharpoonleft \\leftrightharpoon \\rightleftharpoon \\coprod \\leftharpoondown \\rightharpoondown \\nwarrow \\nearrow \\mapsto \\cent \\pound \\yen \\div \\multimap \\maporiginal \\mapimage \\bigcap \\bigcup \\benzene \\times \\cdot \\propto \\equiv \\Im \\Re \\ "); + ui->cmbTestset->addItem("math: arrowtest 1", "$\\leftarrow \\longleftarrow \\Leftarrow \\Longleftarrow \\rightarrow \\longrightarrow \\Rightarrow \\Longrightarrow \\uparrow \\Uparrow \\downarrow \\Downarrow \\leftrightarrow \\Leftrightarrow \\longleftrightarrow \\Longleftrightarrow$"); + ui->cmbTestset->addItem("math: arrowtest 2", "$\\nwarrow \\nearrow \\searrow \\swarrow \\mapsto \\leftharpoonup \\rightharpoonup \\upharpoonleft \\downharpoonleft \\leftrightharpoon \\rightleftharpoon \\leftharpoondown \\rightharpoondown \\upharpoonright \\downharpoonright $"); + ui->cmbTestset->addItem("math-font: greek letters", "$\\alpha\\beta\\gamma\\delta\\epsilon\\varepsilon\\zeta\\eta\\theta\\vartheta\\iota\\kappa\\lambda\\mu\\nu\\xi\\pi\\varpi\\rho\\varrho\\sigma\\varsigma\\tau\\upsilon\\phi\\varphi\\chi\\psi\\omega\\Omega\\Gamma\\Delta\\Theta\\Lambda\\Xi\\Pi\\Sigma\\Upsilon\\Phi\\Psi$"); + ui->cmbTestset->addItem("text-font: greek letters", "\\alpha\\beta\\gamma\\delta\\epsilon\\varepsilon\\zeta\\eta\\theta\\vartheta\\iota\\kappa\\lambda\\mu\\nu\\xi\\pi\\varpi\\rho\\varrho\\sigma\\varsigma\\tau\\upsilon\\phi\\varphi\\chi\\psi\\omega\\Omega\\Gamma\\Delta\\Theta\\Lambda\\Xi\\Pi\\Sigma\\Upsilon\\Phi\\Psi"); + ui->cmbTestset->addItem("math-font: blackboard", "$\\mathbb{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: bf", "$\\mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: it", "$\\mathit{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: frak", "$\\mathfrak{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: sf", "$\\mathsf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: rm", "$\\mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: cal", "$\\mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: script", "$\\mathscr{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("math-font: tt", "$\\mathtt{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); + ui->cmbTestset->addItem("text: bf", "\\textbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: it", "\\textit{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: frak", "\\textfrak{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: sf", "\\textsf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: rm", "\\textrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: cal", "\\textcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: script", "\\textscr{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("text: tt", "\\texttt{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}"); + ui->cmbTestset->addItem("math: subscript test", "$r_{123}\\ \\ r_{\\frac{1}{2}}$"); + ui->cmbTestset->addItem("math: subscript0 test", "$r_{123}$"); + ui->cmbTestset->addItem("math: subscript1 test", "$r_{123}\\ $"); + ui->cmbTestset->addItem("math: subscript2 test", "$r_{123}\\ \\ $"); + ui->cmbTestset->addItem("math: subscript3 test", "$r_{123}r_{\\frac{1}{2}}$"); + ui->cmbTestset->addItem("math: superscript test", "$r^{123}\\ \\ r^{\\frac{1}{2}}$"); + ui->cmbTestset->addItem("math: superscript0 test", "$r^{123}$"); + ui->cmbTestset->addItem("math: superscript1 test", "$r^{123}\\ $"); + ui->cmbTestset->addItem("math: superscript2 test", "$r^{123}\\ \\ $"); + ui->cmbTestset->addItem("math: superscript3 test", "$r^{123}r^{\\frac{1}{2}}$"); + ui->cmbTestset->addItem("math: asuperscript test", "$a^{123}\\ \\ a^{\\frac{1}{2}}$"); + ui->cmbTestset->addItem("math: asuperscript0 test", "$a^{123}$"); + ui->cmbTestset->addItem("math: gsuperscript1 test", "$g^{123}\\ $"); + ui->cmbTestset->addItem("math: gsuperscript2 test", "$g^{123}\\ \\ $"); + ui->cmbTestset->addItem("math: gsuperscript3 test", "$g^{123}g^{\\frac{1}{2}}$"); + ui->cmbTestset->addItem("math: subsuperscript test", "$r_{123}^2$\\ \\ $r^2_{123}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_{123}^2$\\ \\ $\\left(\\stackrel{a}{b}\\right)^2_{123}$\\ \\ $r_{\\frac{1}{2}}^2$\\ \\ $r^2_{\\frac{1}{2}}$\\ \\ $r^{\\frac{1}{2}}_2$\\ \\ $r_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)^{\\frac{1}{2}}_2$"); + ui->cmbTestset->addItem("math: radicals", "$\\sqrt{a}\\sqrt{5}\\sqrt{-1}\\sqrt{h}\\sqrt{jA}\\sqrt{\\vec{A}}\\sqrt{\\frac{1}{a}}\\frac{\\sqrt{a}}{\\sqrt{a}}\\sqrt{\\frac{1}{1+\\frac{1}{a}}}\\frac{1}{\\sqrt{1+\\frac{1}{a}}}\\sqrt{a+\\sqrt{a+b}}$"); + ui->cmbTestset->addItem("text: radicals", "\\sqrt{a}\\sqrt{5}\\sqrt{-1}\\sqrt{h}\\sqrt{jA}\\sqrt{\\vec{A}}\\sqrt{\\frac{1}{a}}\\frac{\\sqrt{a}}{\\sqrt{a}}\\sqrt{\\frac{1}{1+\\frac{1}{a}}}\\frac{1}{\\sqrt{1+\\frac{1}{a}}}\\sqrt{a+\\sqrt{a+b}}"); + ui->cmbTestset->addItem("math: 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("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: 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}}}$"); + ui->cmbTestset->addItem("math: dfrac test", "$\\dfrac{a}{b}+\\dfrac{g}{a}-\\dfrac{a^2}{b^2}\\cdot\\dfrac{a^2}{b^{\\dfrac{1}{2}}}$"); + ui->cmbTestset->addItem("math: sfrac test", "$\\sfrac{a}{b}+\\sfrac{g}{a}-\\sfrac{a^2}{b^2}\\cdot\\sfrac{a^2}{b^{\\sfrac{1}{2}}}$"); + ui->cmbTestset->addItem("math: stfrac test", "$\\stfrac{a}{b}+\\stfrac{g}{a}-\\stfrac{a^2}{b^2}\\cdot\\stfrac{a^2}{b^{\\stfrac{1}{2}}}$"); + ui->cmbTestset->addItem("text: number fractions test", "frac: \\frac{1}{2}, \\frac{3}{4},\\ \\ \\ tfrac: \\tfrac{1}{2}, \\tfrac{3}{4},\\ \\ \\ sfrac: \\sfrac{1}{2}, \\sfrac{3}{4},\\ \\ \\ stfrac: \\stfrac{1}{2}, \\stfrac{3}{4},\\ \\ \\ "); + ui->cmbTestset->addItem("math: stackrel test", "$\\stackrel{a}{b}+\\stackrel{g}{a}-\\stackrel{a^2}{b^2}\\cdot\\stackrel{a^2}{b^{\\stackrel{1}{2}}}$"); + ui->cmbTestset->addItem("text/math: brace0 test", "text: \\langle\\langle -- math: $\\langle\\langle$"); + ui->cmbTestset->addItem("text/math: brace1 test", "text: \\langle\\langle r^{123} -- math: $\\langle\\langle r^{123}$"); + ui->cmbTestset->addItem("text/math: brace2 test", "text: \\langle\\langle r^{123}\\rangle\\rangle -- math: $\\langle\\langle r^{123}\\rangle\\rangle$"); + ui->cmbTestset->addItem("text/math: brace3 test", "text: \\left\\langle r^{123}\\right\\rangle -- math: $\\left\\langle r^{123}\\right\\rangle$"); + ui->cmbTestset->addItem("text/math: brace4 test", "text: \\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle -- math: $\\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle$"); + ui->cmbTestset->addItem("text/math: brace5 test: ( )", "text: \\left(\\left(\\left( r^{123}\\right)\\right)\\right) -- math: $\\left(\\left(\\left( r^{123}\\right)\\right)\\right)$"); + ui->cmbTestset->addItem("text/math: brace6 test: [ ]", "text: \\left[\\left[\\left[ r^{123}\\right]\\right]\\right] -- math: $\\left[\\left[\\left[ r^{123}\\right]\\right]\\right]$"); + ui->cmbTestset->addItem("text/math: brace7 test: { }", "text: \\left\\{\\left\\{\\left\\{ r^{123}\\right\\}\\right\\}\\right\\} -- math: $\\left\\{\\left\\{\\left\\{ r^{123}\\right\\}\\right\\}\\right\\}$"); + ui->cmbTestset->addItem("text/math: brace8 test: || ||", "text: \\left\\|\\left\\|\\left\\| r^{123}\\right\\|\\right\\|\\right\\| -- math: $\\left\\|\\left\\|\\left\\| r^{123}\\right\\|\\right\\|\\right\\|$"); + ui->cmbTestset->addItem("text/math: brace9 test: | |", "text: \\left|\\left|\\left| r^{123}\\right|\\right|\\right| -- math: $\\left|\\left|\\left| r^{123}\\right|\\right|\\right|$"); + ui->cmbTestset->addItem("text/math: brace10 test", "text: \\left\\{\\left[\\left( r^{123}\\right)\\right]\\right\\} -- math: $\\left\\{\\left[\\left( r^{123}\\right)\\right]\\right\\}$"); + ui->cmbTestset->addItem("text/math: brace11 test: floor", "text: \\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor -- math: $\\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor$"); + ui->cmbTestset->addItem("text/math: brace12 test: ceil", "text: \\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil -- math: $\\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil$"); + ui->cmbTestset->addItem("text/math: brace13 test: non-left/right ( )", "text: (((r^{123}))) -- math: $(((r^{123})))$"); + ui->cmbTestset->addItem("text/math: brace14 test: non-left/right [ ]", "text: [[[r^{123}]]] -- math: $[[[r^{123}]]]$"); + ui->cmbTestset->addItem("text/math: brace15 test: non-left/right { }", "text: \\{\\{\\{r^{123}\\}\\}\\} -- math: $\\{\\{\\{ r^{123}\\}\\}\\}$"); + ui->cmbTestset->addItem("text/math: brace16 test: non-left/right | |", "text: |||r^{123}||| -- math: $|||r^{123}|||$"); + ui->cmbTestset->addItem("text/math: brace17 test: non-left/right { | }", "text: \\{r^{123}|r\\equiv 5\\} -- math: $\\{r^{123}|r\\equiv 5\\}$"); + ui->cmbTestset->addItem("text/math: sub-, superscript test", "text: r^{1234}_{321} r_{321}^{1234} -- math: $r^{1234}_{321} r_{321}^{1234} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$"); + ui->cmbTestset->addItem("text/math: super-, subscript test", "text: r^{123}_{4321} r_{4321}^{123} -- math: $r^{123}_{4321} r_{4321}^{123} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$"); //ui->cmbTestset->addItem("", ""); ui->cmbTestset->addItem("math 1", "$f(x)=\\int_{-\\infty}^xe^{-t^2}\\;\\mathrm{d}t$"); ui->cmbTestset->addItem("math 2", "$\\sum_{i=1}^\\infty\\frac{-e^{i\\pi}}{2^n}$"); @@ -124,35 +146,35 @@ TestForm::TestForm(QWidget *parent) : ui->cmbTestset->addItem("math 18", "${}_pF_q(a_1,\\dots,a_p;c_1,\\dots,c_q;z)= \\sum_{n=0}^\\infty\\frac{(a_1)_n\\cdots(a_p)_n}{(c_1)_n\\cdots(c_q)_n}\\frac{z^n}{n!}$"); ui->cmbTestset->addItem("math 19 (overset)", "$X \\overset{=}{def} Y$\\ \\ \\ \\ \\ $X \\overset{=}{!} Y$\\ \\ \\ \\ \\ $X \\overset{\\rightarrow}{f} Y$\\ \\ \\ \\ \\ $\\frac{f(x+\\Delta x)-f(x)}{\\Delta x}\\overset{\\longrightarrow}{\\Delta x\\to 0}f'(x)$"); ui->cmbTestset->addItem("math 20 (underset)", "$X \\underset{=}{\\text{def (5)}} Y$\\ \\ \\ \\ \\ $X \\underset{\\rightarrow}{f} Y$\\ \\ \\ \\ \\ $\\frac{f(x+\\Delta x)-f(x)}{\\Delta x}\\underset{\\longrightarrow}{\\Delta x\\to 0}f'(x)$"); - ui->cmbTestset->addItem("Jacobi Matrix and VarCov matrix", "$J_{ij}= \\left.\\frac{\\partial f(x,\\vec{p})}{\\partial p_i}\\right|_{\\vec{p},x=x_j}\\ \\ \\ \\ \\ \\mat{C}=\\left(\\mat{J}^\\mathrm{T}\\ J\\right)^{-1}\\ \\ \\ \\ \\ test: \\left|\\frac{\\partial f(x,\\vec{p})}{\\partial p_i}\\right|_{\\vec{p},x=x_j}^2$"); - ui->cmbTestset->addItem("operator test (textmode)", "x=0\\ \\ y>0\\ \\ x+y\\ \\ -1\\ \\ x-2\\ \\ x\\cdot y\\ \\ x\\geq 4\\ \\ x~4"); - ui->cmbTestset->addItem("operator test (mathmode)", "$x=0\\ \\ y>0\\ \\ x+y\\ \\ -1\\ \\ x-2\\ \\ x\\cdot y\\ \\ x\\geq 4\\ \\ x~4$"); - ui->cmbTestset->addItem("color test", "\\textcolor{red}{RED}\\textcolor{blue}{BLUE}"); - ui->cmbTestset->addItem("boxed test", "test: \\boxed{boxed text} in the middle"); - ui->cmbTestset->addItem("mathboxed test", "\\fbox{2^{2^{\\colorbox{red}{2^{x}}}}}"); + ui->cmbTestset->addItem("math: Jacobi Matrix and VarCov matrix", "$J_{ij}= \\left.\\frac{\\partial f(x,\\vec{p})}{\\partial p_i}\\right|_{\\vec{p},x=x_j}\\ \\ \\ \\ \\ \\mat{C}=\\left(\\mat{J}^\\mathrm{T}\\ J\\right)^{-1}\\ \\ \\ \\ \\ test: \\left|\\frac{\\partial f(x,\\vec{p})}{\\partial p_i}\\right|_{\\vec{p},x=x_j}^2$"); + ui->cmbTestset->addItem("math: operator test (textmode)", "x=0\\ \\ y>0\\ \\ x+y\\ \\ -1\\ \\ x-2\\ \\ x\\cdot y\\ \\ x\\geq 4\\ \\ x~4"); + ui->cmbTestset->addItem("math: operator test (mathmode)", "$x=0\\ \\ y>0\\ \\ x+y\\ \\ -1\\ \\ x-2\\ \\ x\\cdot y\\ \\ x\\geq 4\\ \\ x~4$"); + ui->cmbTestset->addItem("text: color test", "\\textcolor{red}{RED}\\textcolor{blue}{BLUE}"); + ui->cmbTestset->addItem("text: boxed test", "test: \\boxed{boxed text} in the middle"); + ui->cmbTestset->addItem("mathboxed test", "$\\fbox{2^{2^{\\colorbox{red}{2^{x}}}}}$"); ui->cmbTestset->addItem("axiom of power test", "$\\forall A \\, \\exists P \\, \\forall B \\, [B \\in P \\iff \\forall C \\, (C \\in B \\Rightarrow C \\in A)]$"); - ui->cmbTestset->addItem("De Morgan's law", "$\\neg(P\\land Q)\\iff(\\neg P)\\lor(\\neg Q)$ or $\\overline{\\bigcap_{i \\in I} A_{i}}\\equiv\\bigcup_{i \\in I} \\overline{A_{i}}$ or $\\overline{A \\cup B}\\equiv\\overline{A} \\cap \\overline{B}$"); - ui->cmbTestset->addItem("quadratic formula", "$x=\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}$"); - ui->cmbTestset->addItem("combination", "$\\binom{n}{k} = \\frac{n(n-1)...(n-k+1)}{k(k-1)\\dots1}=\\frac{n!}{k!(n-k)!}$"); - ui->cmbTestset->addItem("Sophomore's dream 1", "$\\int_0^1 x^{-x}\\,dx = \\sum_{n=1}^\\infty n^{-n}(\\scriptstyle{= 1.29128599706266354040728259059560054149861936827\\dots)}$"); - ui->cmbTestset->addItem("Sophomore's dream 2", "$\\int_0^1 x^x \\,dx = \\sum_{n=1}^\\infty (-1)^{n+1}n^{-n} = - \\sum_{n=1}^\\infty (-n)^{-n} (\\scriptstyle{= 0.78343051071213440705926438652697546940768199014\\dots})$"); - ui->cmbTestset->addItem("divergence 1", "$\\operatorname{div}\\vec{F} = \\nabla\\cdot\\vec{F}=\\frac{\\partial U}{\\partial x}+\\frac{\\partial V}{\\partial y}+\\frac{\\partial W}{\\partial z}$"); - ui->cmbTestset->addItem("divergence 2", "$\\overrightarrow{\\operatorname{div}}\\,(\\mathbf{\\underline{\\underline{\\epsilon}}}) = " + ui->cmbTestset->addItem("math: De Morgan's law", "$\\neg(P\\land Q)\\iff(\\neg P)\\lor(\\neg Q)$ or $\\overline{\\bigcap_{i \\in I} A_{i}}\\equiv\\bigcup_{i \\in I} \\overline{A_{i}}$ or $\\overline{A \\cup B}\\equiv\\overline{A} \\cap \\overline{B}$"); + ui->cmbTestset->addItem("math: quadratic formula", "$x=\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}$"); + ui->cmbTestset->addItem("math: combination", "$\\binom{n}{k} = \\frac{n(n-1)...(n-k+1)}{k(k-1)\\dots1}=\\frac{n!}{k!(n-k)!}$"); + ui->cmbTestset->addItem("math: Sophomore's dream 1", "$\\int_0^1 x^{-x}\\,dx = \\sum_{n=1}^\\infty n^{-n}(\\scriptstyle{= 1.29128599706266354040728259059560054149861936827\\dots)}$"); + ui->cmbTestset->addItem("math: Sophomore's dream 2", "$\\int_0^1 x^x \\,dx = \\sum_{n=1}^\\infty (-1)^{n+1}n^{-n} = - \\sum_{n=1}^\\infty (-n)^{-n} (\\scriptstyle{= 0.78343051071213440705926438652697546940768199014\\dots})$"); + ui->cmbTestset->addItem("math: divergence 1", "$\\operatorname{div}\\vec{F} = \\nabla\\cdot\\vec{F}=\\frac{\\partial U}{\\partial x}+\\frac{\\partial V}{\\partial y}+\\frac{\\partial W}{\\partial z}$"); + ui->cmbTestset->addItem("math: divergence 2", "$\\overrightarrow{\\operatorname{div}}\\,(\\mathbf{\\underline{\\underline{\\epsilon}}}) = " "\\begin{bmatrix}" "\\frac{\\partial \\epsilon_{xx}}{\\partial x} +\\frac{\\partial \\epsilon_{yx}}{\\partial y} +\\frac{\\partial \\epsilon_{zx}}{\\partial z} \\\\" "\\frac{\\partial \\epsilon_{xy}}{\\partial x} +\\frac{\\partial \\epsilon_{yy}}{\\partial y} +\\frac{\\partial \\epsilon_{zy}}{\\partial z} \\\\" "\\frac{\\partial \\epsilon_{xz}}{\\partial x} +\\frac{\\partial \\epsilon_{yz}}{\\partial y} +\\frac{\\partial \\epsilon_{zz}}{\\partial z}" "\\end{bmatrix}$"); - ui->cmbTestset->addItem("lim, sum ...", "$\\lim_{x\\to\\infty} f(x) = \\binom{k}{r} + \\frac{a}{b} \\sum_{n=1}^\\infty a_n + \\displaystyle{ \\left\\{ \\frac{1}{13} \\sum_{n=1}^\\infty b_n \\right\\} }.$"); - ui->cmbTestset->addItem("array test", "$f(x) := \\left\\{\\begin{array} x^2 \\sin \\frac{1}{x} & \\textrm{if } x \\ne 0, \\\\ 0 & \\textrm{if } x = 0 . \\end{array}\\right.$"); - ui->cmbTestset->addItem("Schwinger-Dyson", "$\\left\\langle\\psi\\left|\\mathcal{T}\\{F \\phi^j\\}\\right|\\psi\\right\\rangle=\\left\\langle\\psi\\left|\\mathcal{T}\\{iF_{,i}D^{ij}-FS_{int,i}D^{ij}\\}\\right|\\psi\\right\\rangle.$"); - ui->cmbTestset->addItem(QLatin1String("Schrödinger's equation"), "$\\left[-\\frac{\\hbar^2}{2m}\\frac{\\partial^2}{\\partial x^2}+V\\right]\\Psi(x)=\\mathrm{i}\\hbar\\frac{\\partial}{\\partial t}\\Psi(x)$"); - ui->cmbTestset->addItem("Cauchy-Schwarz inequality", "$\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)$"); - ui->cmbTestset->addItem("Maxwell's equations", "$\\begin{aligned}\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac{1}{c}\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\ \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac{1}{c}\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \\end{aligned}$"); - ui->cmbTestset->addItem("Langevin Equation", "$m \\dot{v}(t) = -\\gamma v(t) + F(x,t)+ f(t)$"); - ui->cmbTestset->addItem("Fokker-Planck Equation", "$\\frac{\\partial}{\\partial t}P(y,t)=-\\frac{\\partial}{\\partial y}\\left[ A(y,t)P(y,t)\\right] +\\frac{\\Gamma}{2}\\frac{\\partial^2}{\\partial y^2}\\left[ P(y,t)\\right]$"); - ui->cmbTestset->addItem("Hamilton Equations of motion", "$\\mathcal{H}(\\mathbf{q},\\mathbf{p})=\\frac{\\mathbf{p}^2}{2\\,m}+V(\\mathbf{q})\\ \\ \\ \\text{and}\\ \\ \\ \\dot{q}_k =\\frac{p_k}{m}\\ ,\\ \\dot{p}_k = - \\frac{\\partial V}{\\partial q_k}$"); - ui->cmbTestset->addItem("Gaussian Distrubution", "$f(x | \\mu,\\sigma^2)=\\frac{1}{\\sqrt{2\\pi\\sigma^2}}\\operatorname{exp}\\left(-\\frac{(x-\\mu)^2}{2\\sigma^2}\\right)=\\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}\\quad -\\inftycmbTestset->addItem("math: lim, sum ...", "$\\lim_{x\\to\\infty} f(x) = \\binom{k}{r} + \\frac{a}{b} \\sum_{n=1}^\\infty a_n + \\displaystyle{ \\left\\{ \\frac{1}{13} \\sum_{n=1}^\\infty b_n \\right\\} }.$"); + ui->cmbTestset->addItem("math: array test", "$f(x) := \\left\\{\\begin{array} x^2 \\sin \\frac{1}{x} & \\textrm{if } x \\ne 0, \\\\ 0 & \\textrm{if } x = 0 . \\end{array}\\right.$"); + ui->cmbTestset->addItem("math: Schwinger-Dyson", "$\\left\\langle\\psi\\left|\\mathcal{T}\\{F \\phi^j\\}\\right|\\psi\\right\\rangle=\\left\\langle\\psi\\left|\\mathcal{T}\\{iF_{,i}D^{ij}-FS_{int,i}D^{ij}\\}\\right|\\psi\\right\\rangle.$"); + ui->cmbTestset->addItem(QLatin1String("math: Schrödinger's equation"), "$\\left[-\\frac{\\hbar^2}{2m}\\frac{\\partial^2}{\\partial x^2}+V\\right]\\Psi(x)=\\mathrm{i}\\hbar\\frac{\\partial}{\\partial t}\\Psi(x)$"); + ui->cmbTestset->addItem("math: Cauchy-Schwarz inequality", "$\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)$"); + ui->cmbTestset->addItem("math: Maxwell's equations", "$\\begin{aligned}\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac{1}{c}\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\ \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac{1}{c}\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \\end{aligned}$"); + ui->cmbTestset->addItem("math: Langevin Equation", "$m \\dot{v}(t) = -\\gamma v(t) + F(x,t)+ f(t)$"); + ui->cmbTestset->addItem("math: Fokker-Planck Equation", "$\\frac{\\partial}{\\partial t}P(y,t)=-\\frac{\\partial}{\\partial y}\\left[ A(y,t)P(y,t)\\right] +\\frac{\\Gamma}{2}\\frac{\\partial^2}{\\partial y^2}\\left[ P(y,t)\\right]$"); + ui->cmbTestset->addItem("math: Hamilton Equations of motion", "$\\mathcal{H}(\\mathbf{q},\\mathbf{p})=\\frac{\\mathbf{p}^2}{2\\,m}+V(\\mathbf{q})\\ \\ \\ \\text{and}\\ \\ \\ \\dot{q}_k =\\frac{p_k}{m}\\ ,\\ \\dot{p}_k = - \\frac{\\partial V}{\\partial q_k}$"); + ui->cmbTestset->addItem("math: Gaussian Distrubution", "$f(x | \\mu,\\sigma^2)=\\frac{1}{\\sqrt{2\\pi\\sigma^2}}\\operatorname{exp}\\left(-\\frac{(x-\\mu)^2}{2\\sigma^2}\\right)=\\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}\\quad -\\inftycmbTestset->addItem("User-Editable Text"); // //ui->cmbTestset->addItem("", "$$"); @@ -178,10 +200,10 @@ TestForm::TestForm(QWidget *parent) : ui->cmbEncodingFraktur->setCurrentIndex(static_cast(mt.getFontEncodingFraktur())); ui->cmbUnicodeBlackboard->setCurrentFont(QFont(mt.getFontBlackboard())); ui->cmbEncodingBlackboard->setCurrentIndex(static_cast(mt.getFontEncodingBlackboard())); - ui->cmbUnicodeSymbol->setCurrentFont(QFont(mt.getSymbolfontSymbol(JKQTMathText::MTenvironmentFont::MTEroman))); - ui->cmbEncodingSymbol->setCurrentIndex(static_cast(mt.getSymbolfontEncodingSymbol(JKQTMathText::MTenvironmentFont::MTEroman))); - ui->cmbUnicodeGreek->setCurrentFont(QFont(mt.getSymbolfontGreek(JKQTMathText::MTenvironmentFont::MTEroman))); - ui->cmbEncodingGreek->setCurrentIndex(static_cast(mt.getSymbolfontEncodingGreek(JKQTMathText::MTenvironmentFont::MTEroman))); + ui->cmbUnicodeSymbol->setCurrentFont(QFont(mt.getSymbolfontSymbol(JKQTMathTextEnvironmentFont::MTEroman))); + ui->cmbEncodingSymbol->setCurrentIndex(static_cast(mt.getSymbolfontEncodingSymbol(JKQTMathTextEnvironmentFont::MTEroman))); + ui->cmbUnicodeGreek->setCurrentFont(QFont(mt.getSymbolfontGreek(JKQTMathTextEnvironmentFont::MTEroman))); + ui->cmbEncodingGreek->setCurrentIndex(static_cast(mt.getSymbolfontEncodingGreek(JKQTMathTextEnvironmentFont::MTEroman))); ui->chkSimulateBlackboard->setChecked(mt.isFontBlackboardSimulated()); @@ -282,34 +304,34 @@ double TestForm::draw(QPainter& painter, double X, double YY, JKQTMathText& mt, return mt.getDescent(painter)+mt.getAscent(painter)+40; } -QTreeWidgetItem *TestForm::createTree(JKQTMathText::MTnode *node, QTreeWidgetItem* parent) +QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* parent) { QString name; - JKQTMathText::MTtextNode* txtN=dynamic_cast(node); - JKQTMathText::MTwhitespaceNode* spN=dynamic_cast(node); - JKQTMathText::MTsymbolNode* symN=dynamic_cast(node); - JKQTMathText::MTlistNode* lstN=dynamic_cast(node); - JKQTMathText::MTinstruction1Node* inst1N=dynamic_cast(node); - JKQTMathText::MTsubscriptNode* subN=dynamic_cast(node); - JKQTMathText::MTsuperscriptNode* superN=dynamic_cast(node); - JKQTMathText::MTbraceNode* braceN=dynamic_cast(node); - JKQTMathText::MTsqrtNode* sqrtN=dynamic_cast(node); - JKQTMathText::MTfracNode* fracN=dynamic_cast(node); - JKQTMathText::MTmatrixNode* matrixN=dynamic_cast(node); - JKQTMathText::MTdecoratedNode* decoN=dynamic_cast(node); + JKQTMathTextTextNode* txtN=dynamic_cast(node); + JKQTMathTextWhitespaceNode* spN=dynamic_cast(node); + JKQTMathTextSymbolNode* symN=dynamic_cast(node); + JKQTMathTextListNode* lstN=dynamic_cast(node); + JKQTMathTextInstruction1Node* inst1N=dynamic_cast(node); + JKQTMathTextSubscriptNode* subN=dynamic_cast(node); + JKQTMathTextSuperscriptNode* superN=dynamic_cast(node); + JKQTMathTextBraceNode* braceN=dynamic_cast(node); + JKQTMathTextSqrtNode* sqrtN=dynamic_cast(node); + JKQTMathTextFracNode* fracN=dynamic_cast(node); + JKQTMathTextMatrixNode* matrixN=dynamic_cast(node); + JKQTMathTextDecoratedNode* decoN=dynamic_cast(node); QTreeWidgetItem* ti=nullptr; if (parent) ti=new QTreeWidgetItem(parent); else ti=new QTreeWidgetItem(ui->tree); if (decoN) { - name=QString("MTdecoratedNode: mode='%1'").arg(JKQTMathText::decorationToString(decoN->getDecoration())); + name=QString("MTdecoratedNode: mode='%1'").arg(JKQTMathTextDecorationToString(decoN->getDecoration())); if (decoN->getChild()) ti->addChild(createTree(decoN->getChild(), ti)); } else if (matrixN) { int l=matrixN->getLines(); int c=matrixN->getColumns(); name=QString("MTmatrixNode: l*c=%1*%2").arg(l).arg(c); - QVector > children=matrixN->getChildren(); + QVector > children=matrixN->getChildren(); for (int y=0; ygetMode())); + name=QString("MTfracNode: mode='%1'").arg(JKQTMathTextFracModeToString(fracN->getMode())); if (fracN->getChild1()) ti->addChild(createTree(fracN->getChild1(), ti)); if (fracN->getChild2()) ti->addChild(createTree(fracN->getChild2(), ti)); } else if (sqrtN) { @@ -340,16 +362,16 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathText::MTnode *node, QTreeWidgetIte if (inst1N->getChild()) ti->addChild(createTree(inst1N->getChild(), ti)); } else if (lstN) { name=QString("MTlistNode"); - QList list=lstN->getNodes(); + QList list=lstN->getNodes(); for (int i=0; iaddChild(createTree(list[i], ti)); } } else if (symN) { - name=QString("MTsymbolNode: \'%1\' (addWhite: %2)").arg(symN->getSymbolName()).arg(symN->getAddWhitespace()); + name=QString("JKQTMathTextSymbolNode: \'%1\' (addWhite: %2)").arg(symN->getSymbolName()).arg(symN->getAddWhitespace()); } else if (spN) { - name=QString("MTwhitespaceNode :\'%1\'").arg(txtN->getText()); + name=QString("JKQTMathTextWhitespaceNode :\'%1\'").arg(txtN->getText()); } else if (txtN) { - name=QString("MTtextNode: \'%1\'").arg(txtN->getText()); + name=QString("JKQTMathTextTextNode: \'%1\'").arg(txtN->getText()); } else { name=QString("unknown"); @@ -418,17 +440,17 @@ void TestForm::updateMath() - 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.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: "< JKQTMathTextLabel QLabel -
    jkqtmathtext/jkqtmathtext.h
    +
    jkqtmathtext/jkqtmathtextlabel.h
    diff --git a/lib/jkqtmathtext.pri b/lib/jkqtmathtext.pri index 6bcf75b601..5689515586 100644 --- a/lib/jkqtmathtext.pri +++ b/lib/jkqtmathtext.pri @@ -5,9 +5,35 @@ isEmpty(JKQTP_MATHTEXT_PRI_INCLUDED) { INCLUDEPATH += $PWD - HEADERS += $$PWD/jkqtmathtext/jkqtmathtext.h + HEADERS += $$PWD/jkqtmathtext/jkqtmathtext.h \ + $$PWD/jkqtmathtext/jkqtmathtextlabel.h \ + $$PWD/jkqtmathtext/jkqtmathtexttools.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtexttextnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextbracenode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextdecoratednode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextfracnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextinstructionnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextlistnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextmatrixnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextsubsupernode.h \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h - SOURCES += $$PWD/jkqtmathtext/jkqtmathtext.cpp + SOURCES += $$PWD/jkqtmathtext/jkqtmathtext.cpp \ + $$PWD/jkqtmathtext/jkqtmathtextlabel.cpp \ + $$PWD/jkqtmathtext/jkqtmathtexttools.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextdecoratednode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextinstructionnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextmatrixnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp \ + $$PWD/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp include($$PWD/jkqtmathtext/resources/xits.pri) DEFINES += AUTOLOAD_XITS_FONTS diff --git a/lib/jkqtmathtext/CMakeLists.txt b/lib/jkqtmathtext/CMakeLists.txt index 53d56cba10..98b338c0a0 100644 --- a/lib/jkqtmathtext/CMakeLists.txt +++ b/lib/jkqtmathtext/CMakeLists.txt @@ -22,11 +22,50 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) # Set up source files set(SOURCES ${CMAKE_CURRENT_LIST_DIR}/jkqtmathtext.cpp + ${CMAKE_CURRENT_LIST_DIR}/jkqtmathtexttools.cpp + ${CMAKE_CURRENT_LIST_DIR}/jkqtmathtextlabel.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtexttextnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextbracenode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextdecoratednode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextfracnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextinstructionnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextlistnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextmatrixnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextsqrtnode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextsubsupernode.cpp + ${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextsymbolnode.cpp ) set(HEADERS $ $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ $ $ ) diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp index 65568512c2..492828c4f2 100644 --- a/lib/jkqtmathtext/jkqtmathtext.cpp +++ b/lib/jkqtmathtext/jkqtmathtext.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2008-2020 Jan W. Krieger () + Copyright (c) 2008-2022 Jan W. Krieger () @@ -20,8 +20,19 @@ #include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" #include "jkqtcommon/jkqtpcodestructuring.h" #include "jkqtcommon/jkqtpstringtools.h" +#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h" +#include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h" +#include "jkqtmathtext/nodes/jkqtmathtextfracnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextlistnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextmatrixnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsqrtnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h" #include #include #include @@ -33,3384 +44,9 @@ const double JKQTMathText::ABS_MIN_LINEWIDTH=0.02; -QPainterPath makeHBracePath(double x, double ybrace, double width, double bw, double cubicshrink=0.5, double cubiccontrolfac=0.3) { - double xl1=x-(width)*cubicshrink+bw*cubicshrink; - double xr2=x+(width)*cubicshrink-bw*cubicshrink; - double xl2=x-bw*cubicshrink; - double xr1=x+bw*cubicshrink; - QPainterPath path; - path.moveTo(xl1-bw*cubicshrink, ybrace-bw*cubicshrink); - path.cubicTo(xl1-bw*cubicshrink, ybrace-bw*cubicshrink+bw*cubiccontrolfac, xl1-bw*cubiccontrolfac, ybrace, xl1, ybrace); - path.lineTo(xl2, ybrace); - path.cubicTo(xl2+bw*cubiccontrolfac, ybrace, (xl2+xr1)/2.0, ybrace+bw*cubicshrink-bw*cubiccontrolfac, (xl2+xr1)/2.0, ybrace+bw*cubicshrink); - path.cubicTo((xl2+xr1)/2.0, ybrace+bw*cubicshrink-bw*cubiccontrolfac, xr1-bw*cubiccontrolfac, ybrace, xr1, ybrace); - path.lineTo(xr2, ybrace); - path.cubicTo(xr2+bw*cubiccontrolfac, ybrace, xr2+bw*cubicshrink, ybrace-bw*cubicshrink+bw*cubiccontrolfac, xr2+bw*cubicshrink, ybrace-bw*cubicshrink); - return path; -} -QPainterPath makeArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true) { - double x1=x; - double x2=x+width; - double x3=x2-arrowW/2.0; - double y3u=y-arrowW/2.0; - double y3d=y+arrowW/2.0; - double x3l=x+arrowW/2.0; - - QPainterPath path; - path.moveTo(x1, y); - path.lineTo(x2, y); - if (right) { - path.moveTo(x3, y3u); - path.lineTo(x2, y); - path.lineTo(x3, y3d); - } - if (left) { - path.moveTo(x3l, y3u); - path.lineTo(x1, y); - path.lineTo(x3l, y3d); - } - return path; -} - - -QPainterPath makeDArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true) { - double x1=x; - double x2=x+width; - double dx=arrowW/4.0; - double y1=y-dx; - double y2=y+dx; - double x3=x2-arrowW/2.0; - double y3u=y-arrowW/2.0; - double y3d=y+arrowW/2.0; - double x3l=x+arrowW/2.0; - - QPainterPath path; - path.moveTo(x1+dx, y1); - path.lineTo(x2-dx, y1); - path.moveTo(x1+dx, y2); - path.lineTo(x2-dx, y2); - if (right) { - path.moveTo(x3, y3u); - path.lineTo(x2, y); - path.lineTo(x3, y3d); - } - if (left) { - path.moveTo(x3l, y3u); - path.lineTo(x1, y); - path.lineTo(x3l, y3d); - } - return path; -} - - - -// -------------------------------------------------------------------------------------------------- -// -- implementation of the MTnode's methods -// -------------------------------------------------------------------------------------------------- - -JKQTMathText::MTenvironment::MTenvironment() { - color=QColor("black"); - font=MTEroman; - fontSize=10; - bold=false; - italic=false; - smallCaps=false; - underlined=false; - overline=false; - strike=false; - insideMath=false; -} - -QFont JKQTMathText::MTenvironment::getFont(JKQTMathText* parent) const { - QFont f; - switch (font) { - case MTEsans: if (insideMath) { - f.setFamily(parent->getFontMathSans()); - } else { - f.setFamily(parent->getFontSans()); - } - break; - case MTEmathSans: f.setFamily(parent->getFontMathSans()); break; - case MTEtypewriter: f.setFamily(parent->getFontTypewriter()); break; - case MTEscript: f.setFamily(parent->getFontScript()); break; - case MTEcaligraphic: f.setFamily(parent->getFontCaligraphic()); break; - case MTEblackboard: f.setFamily(parent->getFontBlackboard()); break; - case MTEfraktur: f.setFamily(parent->getFontFraktur()); break; - case MTEmathRoman: f.setFamily(parent->getFontMathRoman()); break; - default: - case MTEroman: if (insideMath) { - f.setFamily(parent->getFontMathRoman()); - } else { - f.setFamily(parent->getFontRoman()); - } - break; - } - f.setBold(bold); - f.setItalic(italic); - f.setUnderline(underlined); - f.setOverline(overline); - f.setStrikeOut(strike); - f.setCapitalization(QFont::MixedCase); - if (smallCaps) f.setCapitalization(QFont::SmallCaps); - f.setPointSizeF(fontSize); - f.setStyleStrategy(QFont::NoFontMerging); - return f; -} - -QString JKQTMathText::MTenvironment::toHtmlStart(MTenvironment defaultEv) const { - QString s; - s=s+"font-size: "+QLocale::c().toString(fontSize)+"pt; "; - if (insideMath) { - if (defaultEv.italic) { - if (!italic) s=s+"font-style: italic; "; - if (italic) s=s+"font-style: normal; "; - } else { - if (!italic) s=s+"font-style: italic; "; - } - } else { - if (!defaultEv.italic && italic) s=s+"font-style: italic; "; - } - if (bold && !defaultEv.bold) s=s+"font-weight: bold"; - - QStringList td; - if (underlined && !defaultEv.underlined) td<<"underline"; - if (overline && !defaultEv.overline) td<<"overline"; - if (strike && !defaultEv.strike) td<<"line-through"; - if (td.size()>0) s=s+"text-decoration: "+td.join(", "); - return ""; -} - -QString JKQTMathText::MTenvironment::toHtmlAfter(JKQTMathText::MTenvironment /*defaultEv*/) const { - return ""; -} - -JKQTMathText::MTnode::MTnode(JKQTMathText* parent) { - this->parent=parent; - drawBoxes=false; -} - -JKQTMathText::MTnode::~MTnode() -= default; - -void JKQTMathText::MTnode::getSize(QPainter &painter, JKQTMathText::MTenvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, const MTnodeSize* prevNodeSize) -{ - double w=width, b=baselineHeight, o=overallHeight, s=strikeoutPos; - getSizeInternal(painter, currentEv, w, b, o, s, prevNodeSize); - - if (w<1e5) width=w; - if (b<1e5) baselineHeight=b; - if (o<1e5) overallHeight=o; - if (s<1e5) strikeoutPos=s; -} - - -double JKQTMathText::MTnode::getNonItalicXCorretion(QPainter &painter, double width_potentiallyitalic, const MTenvironment &ev_potentiallyitalic, JKQTMathText::MTnode* child) const -{ - double italic_xcorrection=0.0; - if (ev_potentiallyitalic.italic) { - MTenvironment ev_nonitalic=ev_potentiallyitalic; - ev_nonitalic.italic=false; - double width_nonitalic=0, baselineHeight_nonitalic=0, overallHeight_nonitalic=0, strikeoutPos_nonitalic=0; - child->getSize(painter, ev_nonitalic, width_nonitalic, baselineHeight_nonitalic, overallHeight_nonitalic, strikeoutPos_nonitalic); - italic_xcorrection=width_potentiallyitalic-width_nonitalic; - } - return italic_xcorrection; -} - - -bool JKQTMathText::MTnode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment /*currentEv*/, JKQTMathText::MTenvironment /*defaultEv*/) { - return false; -} - -bool JKQTMathText::MTnode::getDrawBoxes() const { - return this->drawBoxes; -} - - -void JKQTMathText::MTnode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { - if (drawBoxes) { - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - double w, oh, bh, sp; - getSize(painter, currentEv, w, bh, oh, sp); - QPen p=painter.pen(); - p.setColor("lightcoral"); - p.setWidthF(0.5); - painter.setPen(p); - QRectF r(x, y-bh, w, oh); - painter.drawRect(r); - p.setColor("lightblue"); - painter.setPen(p); - if (w>0) painter.drawLine(QLineF(x, y, x+w, y)); - p.setColor("green"); - painter.setPen(p); - painter.drawEllipse(QRectF(x-3.0,y-3.0,6.0,6.0)); - p.setColor("lightgreen"); - painter.setPen(p); - painter.drawLine(QLineF(x-2.0, y, x+2.0, y)); - painter.drawLine(QLineF(x, y-2, x, y+2.0)); - - } -} - - -JKQTMathText::MTtextNode::MTtextNode(JKQTMathText* _parent, const QString& textIn, bool addWhitespace, bool stripInnerWhitepace): - JKQTMathText::MTnode(_parent) -{ - QString text=textIn; - - if (stripInnerWhitepace) { - text=""; - for (int i=0; itext=text; - // strip all whitespace from left - while (this->text.size()>1 && this->text[0].isSpace()) { - this->text=this->text.right(this->text.size()-1); - } - if (addWhitespace /*&& (this->text.size()>0)*/ && (!this->text[this->text.size()-1].isSpace())) this->text=this->text+" "; - //qDebug()<<"MTtextNode( text="< this->text="<text<<"]"; -} - -JKQTMathText::MTtextNode::~MTtextNode() = default; - -void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - QFont f=currentEv.getFont(parent); - if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" || - text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) || - text==QString(QChar(0x2309)) || text==QString(QChar(0x230A)) || text==QString(QChar(0x230B)))) { - f.setItalic(false); - //f.setFamily(parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Text).first); - } - QString txt=textTransform(text, currentEv, true); - QFontMetricsF fm(f, painter.device()); - QRectF br=fm.boundingRect(txt); - QRectF tbr=parent->getTightBoundingRect(f, txt, painter.device()); //fm.tightBoundingRect(txt); - if (txt=="|") { - br=fm.boundingRect("X"); - tbr=QRectF(0,0,fm.boundingRect("X").width(), fm.ascent());//fm.boundingRect("X"); - br.setWidth(0.7*br.width()); - } - width=br.width();//width(text); - - if (txt.size()>0) { - if (txt[0].isSpace() /*&& br.width()<=0*/) width=width+fm.boundingRect("I").width(); - if (txt.size()>1 && txt[txt.size()-1].isSpace() /*&& (fm.boundingRect("a ").width()==fm.boundingRect("a").width())*/) width=width+fm.boundingRect("I").width(); - } - - //qDebug()<<"text: "<" || - text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) || - text==QString(QChar(0x2309)) || text==QString(QChar(0x230A)) || text==QString(QChar(0x230B)))) { - f.setItalic(false); - } - - - if (onlyDigits && currentEv.insideMath) { - f.setItalic(false); - } - - painter.setFont(f); - - //qDebug()<<"MTtextNode: text="<blackboardSimulated) { - QPainterPath path; - path.addText(QPointF(x+dx, y), f, txt); - painter.drawPath(path); - } else { - painter.drawText(QPointF(x+dx, y), txt);//.simplified()); - } - } else { - int i=0; - double xx=x+dx; - QFont ff=f; - QFontMetricsF fmff(ff, painter.device()); - ff.setItalic(false); - while (iblackboardSimulated) { - QPainterPath path; - path.addText(QPointF(xx, y), ff, QString(txt[i])); - painter.drawPath(path); - } else { - painter.setFont(ff); - painter.drawText(QPointF(xx, y), QString(txt[i])); - } - xx=xx+fmff.boundingRect(txt[i]).width(); - } else { - if (currentEv.font==MTEblackboard && parent->blackboardSimulated) { - QPainterPath path; - path.addText(QPointF(xx, y), f, QString(txt[i])); - painter.drawPath(path); - } else { - painter.setFont(f); - painter.drawText(QPointF(xx, y), QString(txt[i])); - } - xx=xx+fm.boundingRect(txt[i]).width(); - } - i++; - } - } - painter.setPen(pold); - painter.setFont(fold); - - return x+width; -} - -bool JKQTMathText::MTtextNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - html=html+currentEv.toHtmlStart(defaultEv)+text+currentEv.toHtmlAfter(defaultEv); - return true; -} - -QString JKQTMathText::MTtextNode::getText() const { - return this->text; -} - -QString JKQTMathText::MTtextNode::getTypeName() const -{ - return QLatin1String("MTtextNode(")+text+")"; -} - -QString JKQTMathText::MTtextNode::textTransform(const QString &text, JKQTMathText::MTenvironment currentEv, bool /*forSize*/) -{ - QString txt=text; - auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath); - if (fnt.second==MTFEunicode || fnt.second==MTFEunicodeLimited) { - if (currentEv.insideMath) { - txt=""; - for (int i=0; i': txt+=QString(QString(" >")); break; - case '=': txt+=QString(QString(" =")); break; - case ';': txt+=QString(QString("; ")); break; - case ',': txt+=QString(QString(", ")); break; - default: txt+=c; break; - } - } - txt=txt.replace(" ", " "); - } - } - - return txt; -} - - - - - - - -JKQTMathText::MTinstruction1Node::MTinstruction1Node(JKQTMathText* _parent, const QString& name, MTnode* child, const QStringList& parameters): - JKQTMathText::MTnode(_parent) -{ - this->name=name; - this->child=child; - this->parameters=parameters; - - JKQTMathText::MTenvironment ev; - if (!setupMTenvironment(ev)) { - parent->error_list.append(tr("unknown instruction '%1' found!").arg(name)); - } -} - -JKQTMathText::MTinstruction1Node::~MTinstruction1Node() { - if (child!=nullptr) delete child; -} - -QString JKQTMathText::MTinstruction1Node::getTypeName() const -{ - return QLatin1String("MTinstruction1Node(")+name+")"; -} - -void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - JKQTMathText::MTenvironment ev=currentEv; - - setupMTenvironment(ev); - - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - if (name=="colorbox" || name=="fbox" || name=="boxed") { - QFontMetricsF fm(ev.getFont(parent)); - double xw=fm.boundingRect("x").width(); - width+=xw; - overallHeight+=xw; - baselineHeight+=xw/2.0; - } -} - -double JKQTMathText::MTinstruction1Node::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* /*prevNodeSize*/) { - doDrawBoxes(painter, x, y, currentEv); - JKQTMathText::MTenvironment ev=currentEv; - - setupMTenvironment(ev); - - QPen oldPen=painter.pen(); - double shiftX=0; - if (name=="colorbox" || name=="fbox" || name=="boxed") { - QColor fcol=currentEv.color; - if (name=="colorbox") fcol=QColor(parameters.value(0, ev.color.name())); - //qDebug()<<"COLOR="<getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - QPen p=painter.pen(); - QFontMetricsF fm(currentEv.getFont(parent)); - double xw=fm.boundingRect("x").width(); - p.setColor(fcol); - painter.setPen(p); - painter.drawRect(QRectF(x,y-baselineHeight-xw/2,width+xw,overallHeight+xw)); - shiftX=xw/2.0; - } - - double xnew= child->draw(painter, x+shiftX, y, ev); - painter.setPen(oldPen); - return xnew; -} - -bool JKQTMathText::MTinstruction1Node::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - JKQTMathText::MTenvironment ev=currentEv; - - setupMTenvironment(ev); - - return child->toHtml(html, ev, defaultEv); -} - -void JKQTMathText::MTinstruction1Node::setDrawBoxes(bool draw) -{ - drawBoxes=draw; - child->setDrawBoxes(draw); -} - -JKQTMathText::MTnode *JKQTMathText::MTinstruction1Node::getChild() const { - return this->child; -} - -QString JKQTMathText::MTinstruction1Node::getName() const { - return this->name; -} - -QStringList JKQTMathText::MTinstruction1Node::getParameters() const { - return this->parameters; -} - -bool JKQTMathText::MTinstruction1Node::setupMTenvironment(JKQTMathText::MTenvironment &ev) -{ - if (name=="bf" || name=="textbf" || name=="mathbf") ev.bold=true; - else if (name=="em") ev.italic=!ev.italic; - else if (name=="it" || name=="textit" || name=="mathit") ev.italic=true; - else if (name=="textcolor" || name=="mathcolor" || name=="color") ev.color=QColor(parameters.value(0, ev.color.name())); - else if (name=="ensuremath" || name=="equation") { ev.italic=true; ev.insideMath=true; } - else if (name=="sc" || name=="textsc" || name=="mathsc") ev.smallCaps=true; - else if (name=="ul" || name=="underline" || name=="underlined") ev.underlined=true; - else if (name=="ol" || name=="overline" || name=="overlined") ev.overline=true; - else if (name=="strike") ev.strike=true; - else if (name=="rm" || name=="textrm") { ev.font=JKQTMathText::MTEroman; ev.italic=false; } - else if (name=="mathrm" || name=="unit" || name=="operatorname") { ev.font=JKQTMathText::MTEroman; ev.italic=false; } - else if (name=="mathbfit" || name=="bfit" || name=="textbfit") { ev.bold=true; ev.italic=true; } - else if (name=="text" || name=="mbox" || name=="ensuretext") { ev.insideMath=false; ev.font=JKQTMathText::MTEroman; ev.italic=false; } - else if (name=="mat") { ev.font=JKQTMathText::MTEroman; ev.italic=false; ev.bold=true; } - else if (name=="cal" || name=="textcal" || name=="mathcal") { ev.font=JKQTMathText::MTEcaligraphic; ev.italic=false; } - else if (name=="fcal" || name=="textfcal" || name=="mathfcal") { ev.font=JKQTMathText::MTEcaligraphic; ev.bold=true; } - else if (name=="frak" || name=="textfrak" || name=="mathfrak") { ev.font=JKQTMathText::MTEfraktur; ev.italic=false; } - else if (name=="ffrak" || name=="textffrak" || name=="mathffrak") { ev.font=JKQTMathText::MTEfraktur; ev.bold=true; } - else if (name=="bb" || name=="textbb" || name=="mathbb") { ev.font=JKQTMathText::MTEblackboard; ev.italic=false; } - else if (name=="tt" || name=="texttt" || name=="mathtt") { ev.font=JKQTMathText::MTEtypewriter; ev.italic=false; } - else if (name=="sf" || name=="textsf" || name=="mathsf") { ev.font=JKQTMathText::MTEsans; ev.italic=false; } - else if (name=="sfit" || name=="textsfit" || name=="mathsfit") { ev.font=JKQTMathText::MTEsans; ev.italic=true; } - else if (name=="script" || name=="scr" || name=="textscript" || name=="textscr" || name=="mathscript" || name=="mathscr") { ev.font=JKQTMathText::MTEscript; ev.italic=false; } - else if (name=="fscript" || name=="fscr" || name=="textfscript" || name=="textfscr" || name=="mathfscript" || name=="mathfscr") { ev.font=JKQTMathText::MTEscript; ev.bold=true; ev.italic=false; } - else if (name=="displaystyle") { ev.fontSize=ev.fontSize/0.8; } - else if (name=="scriptstyle") { ev.fontSize=ev.fontSize*0.8; } - else if (name=="scriptscriptstyle") { ev.fontSize=ev.fontSize*0.8*0.8; } - else { - return false; - } - - return true; -} - - - - -JKQTMathText::MTsubscriptNode::MTsubscriptNode(JKQTMathText* _parent, MTnode* child): - JKQTMathText::MTnode(_parent) -{ - this->child=child; -} - -JKQTMathText::MTsubscriptNode::~MTsubscriptNode() { - if (child!=nullptr) delete child; -} - -void JKQTMathText::MTsubscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { - JKQTMathText::MTenvironment ev=currentEv; - ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - - QFontMetricsF fm(ev.getFont(parent), painter.device()); - QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); - double shift=parent->getSubShiftFactor()*tbr.height(); - - if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { - shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); - } - - double yshift=baselineHeight-shift; - baselineHeight=shift; - strikeoutPos=fm.strikeOutPos()+yshift; - if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.boundingRect(' ').width())*parent->getItalicCorrectionFactor(); -} - -double JKQTMathText::MTsubscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { - doDrawBoxes(painter, x, y, currentEv); - JKQTMathText::MTenvironment ev=currentEv; - ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - QFontMetricsF fm(ev.getFont(parent), painter.device()); - QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); - - double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - double shift=parent->getSubShiftFactor()*tbr.height(); - - if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { - //qDebug()<<"oldshift="<overallHeight="<overallHeight<<", prevNodeSize->baselineHeight="<baselineHeight; - shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); - //qDebug()<<"newshift="<child; -} - - -bool JKQTMathText::MTsubscriptNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - html=html+""; - bool ok=child->toHtml(html, currentEv, defaultEv); - html=html+""; - return ok; -} - -void JKQTMathText::MTsubscriptNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - child->setDrawBoxes(draw); - -} - - - - - -JKQTMathText::MTsqrtNode::MTsqrtNode(JKQTMathText* _parent, MTnode* child, int degree): - JKQTMathText::MTnode(_parent) -{ - this->child=child; - this->degree=degree; -} - -JKQTMathText::MTsqrtNode::~MTsqrtNode() { - if (child!=nullptr) delete child; -} - -void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - QFontMetricsF fm(currentEv.getFont(parent), painter.device()); - - child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - - overallHeight=overallHeight*1.2;//+fm.ascent()*0.1; - baselineHeight=baselineHeight*1.2;//+fm.ascent()*0.1; - width=width+fm.boundingRect("A").width()*2; // 1.53 -} - -double JKQTMathText::MTsqrtNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* /*prevNodeSize*/) { - doDrawBoxes(painter, x, y, currentEv); - double width=0, baselineHeight=0, overallHeight=0, sp=0; - child->getSize(painter, currentEv, width, baselineHeight, overallHeight, sp); - QFont f=currentEv.getFont(parent); - QFont fsmall=f; - QFontMetricsF fm(f, painter.device()); - double w=fm.boundingRect("A").width(); - double a=baselineHeight*1.15; - double d=overallHeight-baselineHeight; - //painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - QPen p=painter.pen(); - p.setColor(currentEv.color); - p.setWidthF(fm.lineWidth()); - //painter.setPen(p); - QPainterPath path; - if (w>0) { - path.moveTo(x+0.1*w, y-0.4*a); - path.lineTo(x+0.33*w, y-0.4*a); - path.lineTo( x+0.66*w, y+0.5*d); - path.lineTo(x+w, y-a); - } - if (degree!=2) { - fsmall.setPointSizeF(fsmall.pointSizeF()/2.0); - fsmall.setItalic(false); - painter.setFont(fsmall); - painter.drawText(QPointF(x+0.33*w, y-0.55*a), QLocale::c().toString(degree)); - } - //painter.restore(); - double xnew=child->draw(painter, x+1.2*w, y, currentEv); - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.setPen(p); - if (w>0) { - path.lineTo( xnew+0.2*w, y-a); - path.lineTo(xnew+0.2*w, y-0.8*a); - painter.drawPath(path); - } - - return xnew+0.33*w; -} - -bool JKQTMathText::MTsqrtNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - html=html+"√"; - bool ok=child->toHtml(html, currentEv, defaultEv); - html=html+" "; - return ok; -} - -void JKQTMathText::MTsqrtNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - child->setDrawBoxes(draw); - -} - -QString JKQTMathText::MTsqrtNode::getTypeName() const -{ - return "MTsqrtNode"; -} - -JKQTMathText::MTnode *JKQTMathText::MTsqrtNode::getChild() const { - return this->child; -} - -int JKQTMathText::MTsqrtNode::getDegree() const { - return this->degree; -} - - - - - - -JKQTMathText::MTfracNode::MTfracNode(JKQTMathText* _parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode): - JKQTMathText::MTnode(_parent) -{ - this->child1=child_top; - this->child2=child_bottom; - this->mode=mode; -} - -JKQTMathText::MTfracNode::~MTfracNode() { - if (child1!=nullptr) delete child1; - if (child2!=nullptr) delete child2; -} - -QString JKQTMathText::MTfracNode::getTypeName() const -{ - return "MTfracNode"; -} - -void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - QFontMetricsF fm(currentEv.getFont(parent), painter.device()); - JKQTMathText::MTenvironment ev1=currentEv; - JKQTMathText::MTenvironment ev2=currentEv; - - double xh=fm.xHeight(); //tightBoundingRect("x").height(); - double sp=xh; - double Ah=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()).height();//fm.ascent(); - double xw=fm.boundingRect("x").width(); - - if (mode==MTFMunderbrace || mode==MTFMoverbrace) { - ev2.fontSize=ev2.fontSize*parent->getUnderbraceFactor(); - } else if (mode==MTFMunderset || mode==MTFMoverset) { - ev2.fontSize=ev2.fontSize*parent->getUndersetFactor(); - } else if (mode==MTFMfrac || mode==MTFMsfrac) { - ev1.fontSize=ev1.fontSize*parent->getFracFactor(); - ev2.fontSize=ev2.fontSize*parent->getFracFactor(); - } else if (mode==MTFMtfrac || mode==MTFMstfrac) { - ev1.fontSize=ev1.fontSize*parent->getFracFactor()*0.7; - ev2.fontSize=ev2.fontSize*parent->getFracFactor()*0.7; - } - - - double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos1=0; - double width2=0, baselineHeight2=0, overallHeight2=0, strikeoutPos2=0; - child1->getSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos1); - child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos2); - - overallHeight=0; - baselineHeight=0; - width=0; - if (mode==MTFMfrac || mode==MTFMdfrac || mode==MTFMtfrac) { - //std::cout<<"\nxh="< baselineHeight="<getTightBoundingRect(f, "M", painter.device()).height();//fm.ascent(); - double bw=Ah/2.0; - - if (mode==MTFMunderbrace || mode==MTFMoverbrace) { - ev2.fontSize=ev2.fontSize*parent->getUnderbraceFactor(); - } else if (mode==MTFMunderset || mode==MTFMoverset) { - ev2.fontSize=ev2.fontSize*parent->getUndersetFactor(); - } else if (mode==MTFMfrac || mode==MTFMsfrac) { - ev1.fontSize=ev1.fontSize*parent->getFracFactor(); - ev2.fontSize=ev2.fontSize*parent->getFracFactor(); - } else if (mode==MTFMtfrac || mode==MTFMstfrac) { - ev1.fontSize=ev1.fontSize*parent->getFracFactor()*0.7; - ev2.fontSize=ev2.fontSize*parent->getFracFactor()*0.7; - } - - - double width1=0, baselineHeight1=0, overallHeight1=0;//, strikeoutPos1=0; - double width2=0, baselineHeight2=0, overallHeight2=0, strikeoutPos=0; - child1->getSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos); - child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos); - double ascent1=baselineHeight1; - double descent1=overallHeight1-baselineHeight1; - double ascent2=baselineHeight2; - double descent2=overallHeight2-baselineHeight2; - - double yline=y-xh*0.5; - - - //double overallHeight=overallHeight1+overallHeight2+xh; - //double baselineHeight=3.0*xh/2.0+overallHeight1; - double width=qMax(width1, width2); - - QPen p=painter.pen(); - p.setColor(ev1.color); - p.setStyle(Qt::SolidLine); - p.setWidthF(qMax(JKQTMathText::ABS_MIN_LINEWIDTH, lw)); - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.setPen(p); - if (mode==MTFMfrac || mode==MTFMdfrac || mode==MTFMtfrac) { - QLineF l(x+xw/4.0, yline, x+width+xw/2.0, yline); - if (l.length()>0) painter.drawLine(l); - child1->draw(painter, x+xw/2.0+(width-width1)/2.0, yline-xh*(parent->getFracShiftFactor())-descent1, ev1); - child2->draw(painter, x+xw/2.0+(width-width2)/2.0, yline+xh*(parent->getFracShiftFactor())+ascent2, ev2); - } else if (mode==MTFMstfrac || mode==MTFMsfrac) { - child1->draw(painter, x, yline-descent1, ev1); - child2->draw(painter, x+width+xw, yline+ascent2, ev2); - QLineF l(x+width+1.2*xw, yline-descent1-ascent1, x+width-0.2*xw, yline+ascent1+descent1); - if (l.length()>0) painter.drawLine(l); - } else if (mode==MTFMstackrel) { - child1->draw(painter, x+xw/2.0+(width-width1)/2.0, yline-xh*(parent->getFracShiftFactor())-descent1, ev1); - child2->draw(painter, x+xw/2.0+(width-width2)/2.0, yline+xh*(parent->getFracShiftFactor())+ascent2, ev2); - } else if (mode==MTFMunderset) { - child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); - child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y+descent1+xh/6.0+ascent2, ev2); - } else if (mode==MTFMunderbrace) { - double ybrace=y+descent1+bw/2.0; - QPainterPath path=makeHBracePath(x+xw/2.0+(width1)/2.0, ybrace, width, bw); - painter.drawPath(path); - - child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); - child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y+descent1+bw+ascent2, ev2); - } else if (mode==MTFMoverset) { - child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); - child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-xh/6.0-descent2, ev2); - } else if (mode==MTFMoverbrace) { - double ybrace=y-ascent1-bw/2.0; - - { - painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(x+xw/2.0+(width1)/2.0, ybrace); - painter.rotate(180); - QPainterPath path=makeHBracePath(0,0, width, bw); - painter.drawPath(path); - } - - child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); - child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-bw-descent2, ev2); - } - - - if (mode==MTFMstackrel) return x+width+ xw; - else if (mode==MTFMstfrac || mode==MTFMsfrac) return x+width+width2+xw; - else return x+width+xw; - -} - -bool JKQTMathText::MTfracNode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment /*currentEv*/, JKQTMathText::MTenvironment /*defaultEv*/) { - bool ok=false; - - - - return ok; -} - -void JKQTMathText::MTfracNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - child1->setDrawBoxes(draw); - child2->setDrawBoxes(draw); - -} - -JKQTMathText::MTnode *JKQTMathText::MTfracNode::getChild1() const { - return this->child1; -} - -JKQTMathText::MTnode *JKQTMathText::MTfracNode::getChild2() const { - return this->child2; -} - -JKQTMathText::MTfracMode JKQTMathText::MTfracNode::getMode() const { - return this->mode; -} - - - - - - - - - -JKQTMathText::MTmatrixNode::MTmatrixNode(JKQTMathText* _parent, QVector > children): - JKQTMathText::MTnode(_parent) -{ - this->lines=children.size(); - this->columns=0; - for (int i=0; ithis->columns) this->columns=children[i].size(); - } - this->children=children; -} - -JKQTMathText::MTmatrixNode::~MTmatrixNode() { - for (int i=0; igetFracFactor(); - - - QVector colwidth, rowheight; - //QVector > widths, heights, baselines; - - double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos1=0; - //widths.resize(lines); - colwidth.resize(columns); for (int i=0; igetSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos1); - /*widths[i].operator[](j)=width1; - baselines[i].operator[](j)=baselineHeight; - heights[i].operator[](j)=overallHeight1;*/ - if (overallHeight1>rowheight[i]) rowheight[i]=overallHeight1; - if (width1>colwidth[j]) colwidth[j]=width1; - } - } - - - overallHeight=(lines-1)*xw/2.0; - width=columns*xw; - for (int i=0; igetFracFactor(); - - - QVector colwidth, rowheight, rowascent; - //QVector > widths, heights, baselines; - - double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos=0; - //widths.resize(lines); - colwidth.resize(columns); for (int i=0; igetSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos); - /*widths[i].operator[](j)=width1; - baselines[i].operator[](j)=baselineHeight; - heights[i].operator[](j)=overallHeight1;*/ - if (overallHeight1>rowheight[i]) rowheight[i]=overallHeight1; - if (baselineHeight1>rowascent[i]) rowascent[i]=baselineHeight1; - if (width1>colwidth[j]) colwidth[j]=width1; - } - } - - double overallHeight=(lines-1)*xw/2.0; - double width=(columns)*xw; - for (int i=0; i0) yy=yy+rowascent[0]; - for (int i=0; idraw(painter, xx, yy, ev1); - xx=xx+colwidth[j]+xw; - } - - if (i > JKQTMathText::MTmatrixNode::getChildren() const { - return this->children; -} - -int JKQTMathText::MTmatrixNode::getColumns() const { - return this->columns; -} - -int JKQTMathText::MTmatrixNode::getLines() const { - return this->lines; -} - -void JKQTMathText::MTmatrixNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - for (int i=0; isetDrawBoxes(draw); - } - } - -} - - - - - - - - -JKQTMathText::MTdecoratedNode::MTdecoratedNode(JKQTMathText* _parent, MTdecoration decoration, MTnode* child): - JKQTMathText::MTnode(_parent) -{ - this->child=child; - this->decoration=decoration; -} - -JKQTMathText::MTdecoratedNode::~MTdecoratedNode() { - if (child!=nullptr) delete child; -} - -void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - const QFontMetricsF fm(currentEv.getFont(parent), painter.device()); - - child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - - const double italic_xcorrection=getNonItalicXCorretion(painter, width, currentEv, child); - const double decoheightfactor=parent->getDecorationHeightFactor(); - const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection; - - const double decoAboveAscent_yposdelta=fm.ascent()*(1.0+2.0*decoheightfactor); - const double decoAboveBaselineheight_yposdelta=baselineHeight*(1.0+decoheightfactor); - - - const double descent=overallHeight-baselineHeight; - baselineHeight=decoAboveBaselineheight_yposdelta; - if (decoration==MTDbar) { - baselineHeight=std::max(baselineHeight, decoAboveAscent_yposdelta); - } - overallHeight=baselineHeight+descent; - width=std::max(deco_miniwidth,width); -} - -double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* /*prevNodeSize*/) { - doDrawBoxes(painter, x, y, currentEv); - MTenvironment ev=currentEv; - double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - const QFont font=ev.getFont(parent); - const QFontMetricsF fm(font, painter.device()); - const double width_X=fm.boundingRect("X").width(); - const double width_x=fm.boundingRect("x").width(); - const double width_dot=fm.boundingRect(".").width()/2.0; - const double decoheightfactor=parent->getDecorationHeightFactor(); - const double deco_ypos=y-baselineHeight*(1.0+decoheightfactor); - const double decoAboveAscent_ypos=y-fm.ascent()*(1.0+decoheightfactor); - const double strike_ypos=y-baselineHeight/2.0; - const double decobelow_ypos=y+qMax((overallHeight-baselineHeight)*(1.0+decoheightfactor), fm.xHeight()*decoheightfactor); - const double deco_height=decoheightfactor*baselineHeight; - const double italic_xcorrection=getNonItalicXCorretion(painter, width, ev, child); - const double deco_xoffset=parent->getDecorationWidthReductionXFactor()*width_X/2.0; - const double deco_width=std::max(width_x*0.5,width-2.0*deco_xoffset-italic_xcorrection); - const double deco_vecwidth=width_x*0.33; - const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection; - const double decotop_xcenter=x+italic_xcorrection+(width-italic_xcorrection)/2.0; - const double decotop_xstart=decotop_xcenter-deco_width/2.0; - const double decotop_xend=decotop_xcenter+deco_width/2.0; - const double decobot_xstart=x; - const double decobot_xend=x+width-italic_xcorrection; - const double decobot_xcenter=(decobot_xstart+decobot_xend)/2.0; - - - - QPen pold=painter.pen(); - QPen p=pold; - p.setColor(ev.color); - p.setWidthF(qMax(JKQTMathText::ABS_MIN_LINEWIDTH, fm.lineWidth()));//ceil(currentEv.fontSize/16.0)); - - double xnew=child->draw(painter, x, y, ev); - - if (decoration==MTDvec) { - painter.setPen(p); - QPolygonF poly; - poly<0) painter.drawLine(l); - painter.setPen(pold); - } else if (decoration==MTDbar) { - painter.setPen(p); - const QLineF l(decotop_xstart, decoAboveAscent_ypos, decotop_xend, decoAboveAscent_ypos); - if (l.length()>0) painter.drawLine(l); - painter.setPen(pold); - } else if (decoration==MTDdoubleoverline) { - painter.setPen(p); - const QLineF l(decotop_xstart, deco_ypos, decotop_xend, deco_ypos); - if (l.length()>0) painter.drawLine(l); - const QLineF l2(decotop_xstart, deco_ypos-2.0*p.widthF(), decotop_xend, deco_ypos-2.0*p.widthF()); - if (l2.length()>0) painter.drawLine(l2); - painter.setPen(pold); - } else if (decoration==MTDunderline) { - painter.setPen(p); - const QLineF l(decobot_xstart, decobelow_ypos, decobot_xend, decobelow_ypos); - if (l.length()>0) painter.drawLine(l); - painter.setPen(pold); - } else if (decoration==MTDdoubleunderline) { - painter.setPen(p); - const QLineF l(decobot_xstart, decobelow_ypos, decobot_xend, decobelow_ypos); - if (l.length()>0) painter.drawLine(l); - QLineF l2(decobot_xstart, decobelow_ypos+2.0*p.widthF(), decobot_xend, decobelow_ypos+2.0*p.widthF()); - if (l2.length()>0) painter.drawLine(l2); - painter.setPen(pold); - } else if (decoration==MTDarrow) { - painter.setPen(p); - const QLineF l(decotop_xstart, deco_ypos+deco_height/2.0, decotop_xend, deco_ypos+deco_height/2.0); - if (l.length()>0) painter.drawLine(l); - QPolygonF poly; - poly<0) painter.drawLine(l); - painter.setPen(pold); - } else if (decoration==MTDcancel) { - painter.setPen(p); - const QLineF l(decobot_xstart, decobelow_ypos, decotop_xend, deco_ypos); - if (l.length()>0) painter.drawLine(l); - painter.setPen(pold); - } else if (decoration==MTDbcancel) { - painter.setPen(p); - const QLineF l(decobot_xstart, deco_ypos, decotop_xend, decobelow_ypos); - if (l.length()>0) painter.drawLine(l); - painter.setPen(pold); - } else if (decoration==MTDxcancel) { - painter.setPen(p); - const QLineF l(decobot_xstart, deco_ypos, decotop_xend, decobelow_ypos); - if (l.length()>0) painter.drawLine(l); - const QLineF l1(decobot_xstart, decobelow_ypos, decotop_xend, deco_ypos); - if (l1.length()>0) painter.drawLine(l1); - painter.setPen(pold); - } - - /*painter.setPen(QPen(Qt::red, 1.5)); - painter.drawLine(QLineF(x, deco_ypos, xnew, deco_ypos)); - painter.setPen(QPen(Qt::green, 1.5)); - painter.drawLine(QLineF(deco_xstart, deco_ypos+2, deco_xend, deco_ypos+2)); - painter.drawEllipse(QPointF(deco_xpos_center, deco_ypos+2), 5, 5); - painter.setPen(pold);*/ - return xnew; -} - -bool JKQTMathText::MTdecoratedNode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment /*currentEv*/, JKQTMathText::MTenvironment /*defaultEv*/) { - //QString f; - //JKQTMathText::MTenvironment ev=currentEv; - - //bool ok=child->toHtml(html, ev, defaultEv); - - return false; -} - -void JKQTMathText::MTdecoratedNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - child->setDrawBoxes(draw); - -} - -QString JKQTMathText::MTdecoratedNode::getTypeName() const -{ - return "MTdecoratedNode"; -} - -JKQTMathText::MTnode *JKQTMathText::MTdecoratedNode::getChild() const { - return this->child; -} - -JKQTMathText::MTdecoration JKQTMathText::MTdecoratedNode::getDecoration() const { - return this->decoration; -} - - - - - - -JKQTMathText::MTsuperscriptNode::MTsuperscriptNode(JKQTMathText* _parent, MTnode* child): - JKQTMathText::MTnode(_parent) -{ - this->child=child; -} - -JKQTMathText::MTsuperscriptNode::~MTsuperscriptNode() { - if (child!=nullptr) delete child; -} - -void JKQTMathText::MTsuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) { - JKQTMathText::MTenvironment ev=currentEv; - ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - QFontMetricsF fm(currentEv.getFont(parent), painter.device()); - QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); - child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - double shift=parent->getSuperShiftFactor()*tbr.height(); - - if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { - shift=prevNodeSize->baselineHeight-(overallHeight-baselineHeight)-shift; - } - - double yshift=shift+overallHeight-baselineHeight; - baselineHeight=overallHeight=overallHeight+shift; - strikeoutPos=strikeoutPos-yshift; - if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.boundingRect(' ').width())*parent->getItalicCorrectionFactor(); -} - -double JKQTMathText::MTsuperscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) { - doDrawBoxes(painter, x, y, currentEv); - JKQTMathText::MTenvironment ev=currentEv; - ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); - - double cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos; - child->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); - - QFontMetricsF fm(currentEv.getFont(parent), painter.device()); - QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); - double shift=parent->getSuperShiftFactor()*tbr.height(); - - if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { - shift=prevNodeSize->baselineHeight-(cOverallHeight-cBaselineHeight)-shift; - } - - double yshift=shift+cOverallHeight-cBaselineHeight; - double xx=x; - if (currentEv.italic && prevNodeSize==nullptr) xx=xx+double(fm.boundingRect(' ').width())*parent->getItalicCorrectionFactor(); - - return child->draw(painter, xx, y-yshift, ev);//+0.5*fm.boundingRect("A").width(); -} - -JKQTMathText::MTnode *JKQTMathText::MTsuperscriptNode::getChild() const { - return this->child; -} - - -QString JKQTMathText::MTsuperscriptNode::getTypeName() const -{ - return "MTsuperscriptNode"; -} - - -bool JKQTMathText::MTsuperscriptNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) -{ - html=html+""; - bool ok=child->toHtml(html, currentEv, defaultEv); - html=html+""; - return ok; -} - -void JKQTMathText::MTsuperscriptNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - child->setDrawBoxes(draw); - -} - - - - - - -JKQTMathText::MTbraceNode::MTbraceNode(JKQTMathText* _parent, const QString& openbrace, const QString& closebrace, MTnode* child, bool showRightBrace): - JKQTMathText::MTnode(_parent) -{ - this->child=child; - this->openbrace=openbrace; - this->closebrace=closebrace; - this->showRightBrace=showRightBrace; -} - -JKQTMathText::MTbraceNode::~MTbraceNode() { - if (child!=nullptr) delete child; -} - -void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - - JKQTMathText::MTenvironment ev=currentEv; - child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - - double bracewidth=0, braceheight=0; - getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight); - - bracewidth=bracewidth/parent->getBraceShrinkFactor(); - - baselineHeight=/*qMin(baselineHeight, braceheight)*/ baselineHeight*parent->getBraceFactor(); - overallHeight=qMax(overallHeight, braceheight)*parent->getBraceFactor(); //fm.height(); - - width=width+bracewidth*2.0; - - -} - -double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* /*prevNodeSize*/) { - //std::cout<<"drawing brace-node: '"<getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - - double bracewidth=0, braceheight=0; - getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight); - - double cWidth=0; - double cBaselineHeight=0; - double cOverallHeight=0, cstrikeoutPos=0; - - getSize(painter, currentEv, cWidth, cBaselineHeight, cOverallHeight, cstrikeoutPos); - - double lw=qMax(0.25,ceil(currentEv.fontSize/16.0));//fm.lineWidth(); - - double xnew=x+lw; - - QPen pold=painter.pen(); - QPen p=pold; - p.setWidthF(lw); - p.setColor(currentEv.color); - painter.setPen(p); - double brace_fraction=0.85; - if (openbrace=="(") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+brace_fraction*bracewidth, y1); - path.cubicTo(xnew, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+brace_fraction*bracewidth, y2); - painter.drawPath(path); - } else if (openbrace=="[") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+brace_fraction*bracewidth, y1); - path.lineTo(xnew+lw/2.0, y1); - path.lineTo(xnew+lw/2.0, y2); - path.lineTo(xnew+brace_fraction*bracewidth, y2); - painter.drawPath(path); - } else if (openbrace=="{") { - QPainterPath path=makeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction); - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(xnew+bracewidth*(1.0-brace_fraction), y-cBaselineHeight+cOverallHeight/2.0); - painter.rotate(90); - painter.drawPath(path); - - } else if (openbrace=="_") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+brace_fraction*bracewidth, y1); - path.lineTo(xnew, y1); - path.lineTo(xnew, y2); - painter.drawPath(path); - } else if (openbrace=="~") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew, y1); - path.lineTo(xnew, y2); - path.lineTo(xnew+brace_fraction*bracewidth, y2); - painter.drawPath(path); - } else if (openbrace=="|") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); - if (l.length()>0) painter.drawLine(l); - painter.drawPath(path); - } else if (openbrace=="#" || openbrace=="||") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); - if (l.length()>0) painter.drawLine(l); - l=QLineF(xnew+brace_fraction*bracewidth-1.5*lw, y1, xnew+brace_fraction*bracewidth-1.5*lw, y2); - if (l.length()>0) painter.drawLine(l); - } else if (openbrace=="<") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+brace_fraction*bracewidth, y1); - path.lineTo(xnew, (y2+y1)/2.0); - path.lineTo(xnew+brace_fraction*bracewidth, y2); - painter.drawPath(path); - } - - painter.setPen(pold); - - xnew= child->draw(painter, xnew+bracewidth/parent->getBraceShrinkFactor()-lw, y, currentEv)+lw; - - if (showRightBrace) { - painter.setPen(p); - if (closebrace==")") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); - path.cubicTo(xnew+bracewidth, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew+bracewidth, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+(1.0-brace_fraction)*bracewidth, y2); - painter.drawPath(path); - } else if (closebrace=="]") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); - path.lineTo(xnew+bracewidth-lw/2.0, y1); - path.lineTo(xnew+bracewidth-lw/2.0, y2); - path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); - painter.drawPath(path); - } else if (closebrace=="}") { - QPainterPath path=makeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction); - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(xnew+bracewidth*brace_fraction, y-cBaselineHeight+cOverallHeight/2.0); - painter.rotate(270); - painter.drawPath(path); - - } else if (closebrace=="_") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); - path.lineTo(xnew+bracewidth, y1); - path.lineTo(xnew+bracewidth, y2); - painter.drawPath(path); - } else if (closebrace=="~") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+bracewidth, y1); - path.lineTo(xnew+bracewidth, y2); - path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); - painter.drawPath(path); - } else if (closebrace=="|") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); - if (l.length()>0) painter.drawLine(l); - painter.drawPath(path); - } else if (closebrace=="#" || closebrace=="||") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); - if (l.length()>0) painter.drawLine(l); - l=QLineF(xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y1, xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y2); - if (l.length()>0) painter.drawLine(l); - } else if (closebrace==">") { - QPainterPath path; - double y1=y+(cOverallHeight-cBaselineHeight); - double y2=y-cBaselineHeight; - path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); - path.lineTo(xnew+bracewidth, (y2+y1)/2.0); - path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); - painter.drawPath(path); - } - painter.setPen(pold); - } - - //qDebug()<<" ==> "<getBraceShrinkFactor()-lw; -} - -bool JKQTMathText::MTbraceNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - QString ob=openbrace; - QString cb=closebrace; - if (ob=="<") ob="⟨"; - else if (ob=="_") ob="⌊"; - else if (ob=="~") ob="⌈"; - else if (ob=="||" || ob=="#") ob="||"; - if (cb=="<") cb="⟩"; - else if (cb=="_") cb="⌋"; - else if (cb=="~") cb="⌉"; - else if (cb=="||" || cb=="#") cb="||"; - - - html=html+ob; - - bool ok=child->toHtml(html, currentEv, defaultEv); - - html=html+cb; - - return ok; -} - -void JKQTMathText::MTbraceNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - child->setDrawBoxes(draw); - -} - -QString JKQTMathText::MTbraceNode::getTypeName() const -{ - return QLatin1String("MTbraceNode(")+openbrace+" "+closebrace+")"; -} - -void JKQTMathText::MTbraceNode::getBraceWidth(QPainter &/*painter*/, JKQTMathText::MTenvironment ev, double /*baselineHeight*/, double overallHeight, double &bracewidth, double &braceheight) -{ - /*QFont evf=ev.getFont(parent); - if (ev.insideMath) evf.setItalic(false); - ev.italic=false; - while (ev.fontSize<10*parent->getFontSize()) { - const QFontMetricsF fme(evf, painter.device()); - if (fme.ascent()>overallHeight) break; - ev.fontSize+=0.5; - evf.setPointSizeF(ev.fontSize); - } - ev.fontSize=ev.fontSize*parent->getBraceFactor(); - evf.setPointSizeF(ev.fontSize); - QFontMetricsF fm(evf, painter.device()); - QString bc="_X"; - bracewidth=fm.width("I")*parent->getBraceShrinkFactor(); - braceheight=parent->getTBR(evf, bc, painter.device()).height();*/ - double lw=qMax(0.25,ceil(ev.fontSize/12.0)); - braceheight=overallHeight*parent->getBraceFactor(); - bracewidth=0.6*pow(braceheight, 0.6); - if (openbrace=="{" || closebrace=="}") bracewidth=qMax(bracewidth, lw*3.5); - -} - - - - - -JKQTMathText::MTlistNode::MTlistNode(JKQTMathText* _parent): - JKQTMathText::MTnode(_parent) -{ - nodes.clear(); - // these operations cause sub/sup script to be typeset over/under the operator, not right besides! - subsupOperations<<"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"; -} - -JKQTMathText::MTlistNode::~MTlistNode() { - for (int i=0; igetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); - - - double xnew=0; - bool wasBrace=false; - for (int i=0; i0 && wasBrace) { - nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); - prevNodeSizePtr=&prevNodeSize; - } - - - bool doDraw=true; - MTsymbolNode* 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 (i+1(nodes[i+1])) { // is this subscript? - double w1, w2, oh, bh, sp; - nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr); - - if (bh>baselineHeight) { - overallHeight=overallHeight+bh-baselineHeight; - baselineHeight=bh; - strikeoutPos=sp; - } - if (baselineHeight+oh-bh>overallHeight) { - overallHeight=baselineHeight+oh-bh; - strikeoutPos=sp; - } - - i++; - nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtr); - //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; - 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; - nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); - subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp2); - //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; - } - double w=qMax(w1, w2)+fm.boundingRect(' ').width(); - i++; - doDraw=false; - xnew+=w; - //qDebug()<<"### subsupop: sub overallHeight="<0 && wasBrace) { - nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); - prevNodeSizePtr=&prevNodeSize; - } - - - MTsymbolNode* 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 (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); - i++; - //painter.setPen(QPen("magenta")); - //painter.drawEllipse(xnew-4,ynew-4,8,8); - double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); - //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); - i++; - //painter.setPen(QPen("magenta")); - //painter.drawEllipse(xnew-4,ynew-4,8,8); - double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); - //i++; - xnew=qMax(xnew1, xnew2); - doDraw=false; - } - } - } else { - if (smb) { - QString s=smb->getSymbolName(); - if (subsupOperations.contains(s)) { - MTsubscriptNode* subn=nullptr; - if (i+1(nodes[i+1]); - MTsuperscriptNode* 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? - MTenvironment ev=currentEv; - ev.fontSize=ev.fontSize*parent->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; - - 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? - MTenvironment ev=currentEv; - ev.fontSize=ev.fontSize*parent->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; - - 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(); - } - } - } - } - - if (idraw(painter, xnew, ynew, currentEv, prevNodeSizePtr); - } - wasBrace=dynamic_cast(nodes[i]); - } - return xnew; -} - -bool JKQTMathText::MTlistNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - bool ok=true; - for (int i=0; itoHtml(h, currentEv, defaultEv); - html=html+h; - } - return ok; -} - -void JKQTMathText::MTlistNode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; - for (int i=0; isetDrawBoxes(draw); - } -} - -QList JKQTMathText::MTlistNode::getNodes() const { - return this->nodes; -} - - - - - -JKQTMathText::MTsymbolNode::MTsymbolNode(JKQTMathText* _parent, const QString& name, bool _addWhitespace): - JKQTMathText::MTnode(_parent), symbolName(name), addWhitespace(_addWhitespace) -{ -} - -JKQTMathText::MTsymbolNode::~MTsymbolNode() = default; - -QString JKQTMathText::MTsymbolNode::getTypeName() const -{ - return QLatin1String("MTsymbolNode(")+symbolName+QLatin1String(")"); -} - -bool JKQTMathText::MTsymbolNode::getWinSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps& props, const QString &n, const MTenvironment& currentEv, double mathFontFactor) const -{ - auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Text); - auto fntSym=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Symbols); - - //qDebug()<<" +--- getWinSymbolProp("< winSymbolSymbol; - if (winSymbolSymbol.isEmpty()) { - winSymbolSymbol.insert("leftrightarrow", QChar(0xAB)); - winSymbolSymbol.insert("leftarrow", QChar(0xAC)); - winSymbolSymbol.insert("rightarrow", QChar(0xAE)); - winSymbolSymbol.insert("to", QChar(0xAE)); - winSymbolSymbol.insert("uparrow", QChar(0xAD)); - winSymbolSymbol.insert("downarrow", QChar(0xAF)); - winSymbolSymbol.insert("Leftrightarrow", QChar(0xDB)); - winSymbolSymbol.insert("iff", QChar(0xDB)); - winSymbolSymbol.insert("Leftarrow", QChar(0xDC)); - winSymbolSymbol.insert("Rightarrow", QChar(0xDE)); - winSymbolSymbol.insert("Uparrow", QChar(0xDD)); - winSymbolSymbol.insert("Downarrow", QChar(0xFF)); - winSymbolSymbol.insert("pm", QChar(0xB1)); - winSymbolSymbol.insert("leq", QChar(0xA3)); - winSymbolSymbol.insert("geq", QChar(0xB3)); - winSymbolSymbol.insert("le", QChar(0xA3)); - winSymbolSymbol.insert("ge", QChar(0xB3)); - winSymbolSymbol.insert("times", QChar(0xB4)); - winSymbolSymbol.insert("propto", QChar(0xB5)); - winSymbolSymbol.insert("partial", QChar(0xB6)); - winSymbolSymbol.insert("bullet", QChar(0xB7)); - winSymbolSymbol.insert("neq", QChar(0xB9)); - winSymbolSymbol.insert("ne", QChar(0xB9)); - winSymbolSymbol.insert("equiv", QChar(0xBA)); - winSymbolSymbol.insert("approx", QChar(0xBB)); - winSymbolSymbol.insert("ellipsis", QChar(0xBC)); - winSymbolSymbol.insert("Im", QChar(0xC1)); - winSymbolSymbol.insert("Re", QChar(0xC2)); - winSymbolSymbol.insert("otimes", QChar(0xC4)); - winSymbolSymbol.insert("oplus", QChar(0xC5)); - winSymbolSymbol.insert("oslash", QChar(0xC6)); - winSymbolSymbol.insert("cap", QChar(0xC7)); - winSymbolSymbol.insert("land", QChar(0xC7)); - winSymbolSymbol.insert("cup", QChar(0xC8)); - winSymbolSymbol.insert("lor", QChar(0xC8)); - winSymbolSymbol.insert("supset", QChar(0xC9)); - winSymbolSymbol.insert("supseteq", QChar(0xCA)); - winSymbolSymbol.insert("supsetnot", QChar(0xCB)); - winSymbolSymbol.insert("subset", QChar(0xCC)); - winSymbolSymbol.insert("subseteq", QChar(0xCD)); - winSymbolSymbol.insert("in", QChar(0xCE)); - winSymbolSymbol.insert("notin", QChar(0xCF)); - winSymbolSymbol.insert("angle", QChar(0xD0)); - winSymbolSymbol.insert("nabla", QChar(0xD1)); - winSymbolSymbol.insert("copyright", QChar(0xD3)); - winSymbolSymbol.insert("registered", QChar(0xD2)); - winSymbolSymbol.insert("circledR", QChar(0xD2)); - winSymbolSymbol.insert("trademark", QChar(0xD4)); - winSymbolSymbol.insert("textregistered", QChar(0xD4)); - winSymbolSymbol.insert("cdot", QChar(0xD7)); - winSymbolSymbol.insert("neg", QChar(0xD8)); - winSymbolSymbol.insert("wedge", QChar(0xD9)); - winSymbolSymbol.insert("vee", QChar(0xDA)); - winSymbolSymbol.insert("diamond", QChar(0xE0)); - winSymbolSymbol.insert("langle", QChar(0xE1)); - winSymbolSymbol.insert("rangle", QChar(0xF1)); - winSymbolSymbol.insert("forall", QChar(0x22)); - winSymbolSymbol.insert("exists", QChar(0x24)); - winSymbolSymbol.insert("cong", QChar(0x40)); - winSymbolSymbol.insert("bot", QChar(0x5E)); - winSymbolSymbol.insert("ll", "<<"); - winSymbolSymbol.insert("gg", ">>"); - winSymbolSymbol.insert("Alef", QChar(0xC0)); - winSymbolSymbol.insert("alef", QChar(0xC0)); - winSymbolSymbol.insert("tilde", "~"); - winSymbolSymbol.insert("emptyset", QChar(0xC6)); - winSymbolSymbol.insert("varnothing", QChar(0xC6)); - winSymbolSymbol.insert("lceil", QChar(0xE9)); - winSymbolSymbol.insert("rceil", QChar(0xF9)); - winSymbolSymbol.insert("lfloor", QChar(0xEB)); - winSymbolSymbol.insert("rfloor", QChar(0xFB)); - winSymbolSymbol.insert("subsetnot", QChar(0xCB)); - winSymbolSymbol.insert("DC", "="); - winSymbolSymbol.insert("mid", "|"); - winSymbolSymbol.insert("cdots", QString(3, QChar(0xD7))); - winSymbolSymbol.insert("dots", QChar(0xDC)); - winSymbolSymbol.insert("ldots", QChar(0xDC)); - winSymbolSymbol.insert("cent", "c"); - winSymbolSymbol.insert("sim", QChar(0x7E)); - winSymbolSymbol.insert("infty", QChar(0xA5)); - } - - QHash::iterator itsymbol = winSymbolSymbol.find(n); - if (itsymbol!=winSymbolSymbol.end()) { - props.symbol = itsymbol.value(); - } else if (n == "int") { props.symbol = QChar(0xF2); props.fontFactor = mathFontFactor; props.yfactor = +0.1; } - else if (n == "bbC") { props.symbol = "C"; props.bold = +1; props.italic = -1; } - else if (n == "bbH") { props.symbol = "H"; props.bold = +1; props.italic = -1; } - else if (n == "bbN") { props.symbol = "N"; props.bold = +1; props.italic = -1; } - else if (n == "bbP") { props.symbol = "P"; props.bold = +1; props.italic = -1; } - else if (n == "bbQ") { props.symbol = "Q"; props.bold = +1; props.italic = -1; } - else if (n == "bbR") { props.symbol = "R"; props.bold = +1; props.italic = -1; } - else if (n == "bbZ") { props.symbol = "Z"; props.bold = +1; props.italic = -1; } - else if (n == "iint") { props.symbol = QString(2, QChar(0xF2)); props.fontFactor = mathFontFactor; props.yfactor = +0.1; } - else if (n == "iiint") { props.symbol = QString(3, QChar(0xF2)); props.fontFactor = mathFontFactor; props.yfactor = +0.1; } - else if (n == "bigcap") { props.symbol = QChar(0xC7); props.fontFactor = 2; } - else if (n == "bigcup") { props.symbol = QChar(0xC8); props.fontFactor = 2; } - else if (n == "bigvee") { props.symbol = QChar(0xDA); props.fontFactor = 2; } - else if (n == "bighat") { props.symbol = QChar(0xD9); props.fontFactor = 2; } - - else { // here are text mode symbols, i.e. bold and italic won't be touched - props.bold = -1; - props.italic = -1; - props.font = fnt.first; - if (n == "_") { props.symbol = "_"; props.bold = 0; props.italic = 0; } - else if (n == "}") { props.symbol = "}"; props.italic=-1; } - else if (n == "{") { props.symbol = "{"; props.italic=-1; } - else if (n == "]") { props.symbol = "]"; props.italic=-1; } - else if (n == "[") { props.symbol = "["; props.italic=-1; } - else if (n == "(") { props.symbol = "("; props.italic=-1; } - else if (n == ")") { props.symbol = ")"; props.italic=-1; } - else if (n == "|") { props.symbol = "|"; props.italic=-1; } - else if (n == "hbar") { props.symbol = "h"; props.bold = 0; props.italic = 0; props.drawBar = true; } - else if (n == "euro") { props.symbol = ""; props.bold = 0; props.italic = 0; } - else if (n == "cent") { props.symbol = QChar(0xA2); props.bold = 0; props.italic = 0; } - else if (n == "pound") { props.symbol = QChar(0xA3); props.bold = 0; props.italic = 0; } - else if (n == "yen") { props.symbol = QChar(0xA5); props.bold = 0; props.italic = 0; } - else if (n == "div") { props.symbol = QChar(0xF7); props.bold = 0; props.italic = 0; } - else if (n == "backslash") { props.symbol = "\\"; props.bold = 0; props.italic = 0; } - //else if (n=="|") { symbol="||"; bold=0; italic=0; } - else if (n == "/") { props.symbol = "/"; props.bold = 0; props.italic = 0; } - else if (n == "+") { props.symbol = "+"; props.bold = 0; props.italic = 0; } - else if (n == "-") { props.symbol = "-"; props.bold = 0; props.italic = 0; } - else if (n == "*") { props.symbol = "*"; props.bold = 0; props.italic = 0; } - else if (n == "=") { props.symbol = "= "; props.bold = 0; props.italic = 0; } - else if (n == ">") { props.symbol = ">"; props.bold = 0; props.italic = 0; } - else if (n == "<") { props.symbol = "<"; props.bold = 0; props.italic = 0; } - else if (n == "$") { props.symbol = "$"; props.bold = 0; props.italic = 0; } - else if (n == "%") { props.symbol = "%"; props.bold = 0; props.italic = 0; } - else if (n == "&") { props.symbol = "&"; props.bold = 0; props.italic = 0; } - else if (n == "#") { props.symbol = "#"; props.bold = 0; props.italic = 0; } - else if (n == "ast") { props.symbol = "*"; props.bold = 0; props.italic = 0; } - else if (n == "asterisk") { props.symbol = "*"; props.bold = 0; props.italic = 0; } - else if (n == "glq") { props.symbol = "'"; props.bold = 0; props.italic = 0; } - else if (n == "grq") { props.symbol = "'"; props.bold = 0; props.italic = 0; } - else if (n == "glqq") { props.symbol = "\""; props.bold = 0; props.italic = 0; } - else if (n == "grqq") { props.symbol = "\""; props.bold = 0; props.italic = 0; } - else if (n == "flq") { props.symbol = "<"; props.bold = 0; props.italic = 0; } - else if (n == "frq") { props.symbol = ">"; props.bold = 0; props.italic = 0; } - else if (n == "flqq") { props.symbol = ""; props.bold = 0; props.italic = 0; } - else if (n == "frqq") { props.symbol = ""; props.bold = 0; props.italic = 0; } - else { return false; } - } - - return true; -} - -bool JKQTMathText::MTsymbolNode::getGreekSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps& props, const QString &n, const MTenvironment& currentEv, double mathFontFactor) const -{ - auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Text); - auto fntGreek=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Greek); - - //qDebug()<<" +--- getGreekSymbolProp("< winSymbolGreek; - if (winSymbolGreek.isEmpty()) { - winSymbolGreek.insert("alpha", "a"); - winSymbolGreek.insert("beta", "b"); - winSymbolGreek.insert("gamma", "g"); - winSymbolGreek.insert("delta", "d"); - winSymbolGreek.insert("epsilon", "e"); - winSymbolGreek.insert("varepsilon", "e"); - winSymbolGreek.insert("zeta", "z"); - winSymbolGreek.insert("eta", "h"); - winSymbolGreek.insert("theta", "q"); - winSymbolGreek.insert("vartheta", "J"); - winSymbolGreek.insert("iota", "i"); - winSymbolGreek.insert("kappa", "k"); - winSymbolGreek.insert("lambda", "l"); - winSymbolGreek.insert("mu", "m"); - winSymbolGreek.insert("nu", "n"); - winSymbolGreek.insert("xi", "x"); - winSymbolGreek.insert("pi", "p"); - winSymbolGreek.insert("varpi", "v"); - winSymbolGreek.insert("rho", "r"); - winSymbolGreek.insert("sigma", "s"); - winSymbolGreek.insert("varsigma", "V"); - winSymbolGreek.insert("tau", "t"); - winSymbolGreek.insert("upsilon", "u"); - winSymbolGreek.insert("phi", "f"); - winSymbolGreek.insert("varphi", "j"); - winSymbolGreek.insert("chi", "c"); - winSymbolGreek.insert("psi", "y"); - winSymbolGreek.insert("omega", "w"); - winSymbolGreek.insert("Gamma", "G"); - winSymbolGreek.insert("Delta", "D"); - winSymbolGreek.insert("Theta", "Q"); - winSymbolGreek.insert("Lambda", "L"); - winSymbolGreek.insert("Omega", "W"); - winSymbolGreek.insert("Xi", "X"); - winSymbolGreek.insert("Pi", "P"); - winSymbolGreek.insert("Sigma", "S"); - winSymbolGreek.insert("Upsilon", ""); - winSymbolGreek.insert("Phi", "F"); - winSymbolGreek.insert("Psi", "Y"); - } - - static QHash unicodeGreek; - if (unicodeGreek.isEmpty()) { - unicodeGreek.insert("alpha", QChar(0x3B1)); - unicodeGreek.insert("beta", QChar(0x3B2)); - unicodeGreek.insert("gamma", QChar(0x3B3)); - unicodeGreek.insert("delta", QChar(0x3B4)); - unicodeGreek.insert("epsilon", QChar(0x3B5)); - unicodeGreek.insert("varepsilon", QChar(0x3B5)); - unicodeGreek.insert("zeta", QChar(0x3B6)); - unicodeGreek.insert("eta", QChar(0x3B7)); - unicodeGreek.insert("theta", QChar(0x3B8)); - unicodeGreek.insert("vartheta", QChar(0x3D1)); - unicodeGreek.insert("iota", QChar(0x3B9)); - unicodeGreek.insert("kappa", QChar(0x3BA)); - unicodeGreek.insert("lambda", QChar(0x3BB)); - unicodeGreek.insert("mu", QChar(0x3BC)); - unicodeGreek.insert("nu", QChar(0x3BD)); - unicodeGreek.insert("xi", QChar(0x3BE)); - unicodeGreek.insert("pi", QChar(0x3C0)); - unicodeGreek.insert("varpi", QChar(0x3D6)); - unicodeGreek.insert("rho", QChar(0x3C1)); - unicodeGreek.insert("varrho", QChar(0x3F1)); - unicodeGreek.insert("sigma", QChar(0x3C3)); - unicodeGreek.insert("varsigma", QChar(0x3C2)); - unicodeGreek.insert("tau", QChar(0x3C4)); - unicodeGreek.insert("upsilon", QChar(0x3C5)); - unicodeGreek.insert("phi", QChar(0x3D5)); - unicodeGreek.insert("varphi", QChar(0x3C6)); - unicodeGreek.insert("chi", QChar(0x3C7)); - unicodeGreek.insert("psi", QChar(0x3C8)); - unicodeGreek.insert("omega", QChar(0x3C9)); - unicodeGreek.insert("Omega", QChar(0x3A9)); - unicodeGreek.insert("Gamma", QChar(0x393)); - unicodeGreek.insert("Delta", QChar(0x394)); - unicodeGreek.insert("Theta", QChar(0x398)); - unicodeGreek.insert("Lambda", QChar(0x39B)); - unicodeGreek.insert("Xi", QChar(0x39E)); - unicodeGreek.insert("Pi", QChar(0x3A0)); - unicodeGreek.insert("prod", QChar(0x3A0)); - unicodeGreek.insert("Sigma", QChar(0x3A3)); - unicodeGreek.insert("sum", QChar(0x3A3)); - unicodeGreek.insert("Upsilon", QChar(0x3A5)); - unicodeGreek.insert("Phi", QChar(0x3A6)); - unicodeGreek.insert("Psi", QChar(0x3A8)); - } - - //qDebug()<<"##SEARCHING "<::iterator itgreek = unicodeGreek.find(n); - if (itgreek!=unicodeGreek.end()) { - //qDebug()<<"##SEARCHING "<::iterator itgreek = unicodeGreek.find(n); - if (itgreek!=unicodeGreek.end()) { - //qDebug()<<"##SEARCHING "<::iterator itgreek = winSymbolGreek.find(n); - if (itgreek!=winSymbolGreek.end()) { - props.symbol = itgreek.value(); - //qDebug()<<"##SEARCHING "<") { props.symbol = ">"; props.bold = 0; } - else if (n == "|") { props.symbol = "|"; props.bold = 0; } - else if (n == "}") { props.symbol = "}"; } - else if (n == "{") { props.symbol = "{"; } - else if (n == "]") { props.symbol = "]"; } - else if (n == "[") { props.symbol = "["; } - else if (n == "(") { props.symbol = "("; } - else if (n == ")") { props.symbol = ")"; } - else if (n == "|") { props.symbol = "|"; } - else if (n == "$") { props.symbol = "$"; } - else if (n == "%") { props.symbol = "%"; } - else if (n == "&") { props.symbol = "&"; } - else if (n == "#") { props.symbol = "#"; } - else if (n == "ast") { props.symbol = "*"; } - else if (n == "dots") { props.symbol = "..."; } - else if (n == "ldots") { props.symbol = "..."; } - else if (n == "colon") { props.symbol = ":"; } - - else {return false;} - return true; -} - -bool JKQTMathText::MTsymbolNode::getUnicodeBaseSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps& props, const QString &n) const -{ - - //qDebug()<<"--- getUnicodeBaseSymbolProp("< unicodeBaseSymbol; - if (unicodeBaseSymbol.isEmpty()) { - - unicodeBaseSymbol.insert("diamond", QChar(0xE0)); - unicodeBaseSymbol.insert("infty", QChar(0x221E)); - unicodeBaseSymbol.insert("partial", QChar(0x2202)); - unicodeBaseSymbol.insert("times", QChar(0x2A2F)); - unicodeBaseSymbol.insert("*", QChar(0x2217)); - unicodeBaseSymbol.insert("ast", QChar(0x2217)); - unicodeBaseSymbol.insert("asterisk", QChar(0x2217)); - unicodeBaseSymbol.insert("star", QChar(0x22C6)); - unicodeBaseSymbol.insert("bullet", QChar(0x2219)); - unicodeBaseSymbol.insert("copyright", QChar(0x00A9)); - unicodeBaseSymbol.insert("registered", QChar(0x00AE)); - unicodeBaseSymbol.insert("circledR", QChar(0x00AE)); - unicodeBaseSymbol.insert("trademark", QChar(0x2122)); - unicodeBaseSymbol.insert("textregistered", QChar(0x2122)); - unicodeBaseSymbol.insert("cdot", QChar(0x00B7)); - unicodeBaseSymbol.insert("pm", QChar(0x00B1)); - unicodeBaseSymbol.insert("leq", QChar(0x2264)); - unicodeBaseSymbol.insert("geq", QChar(0x2265)); - unicodeBaseSymbol.insert("le", QChar(0x2264)); - unicodeBaseSymbol.insert("ge", QChar(0x2265)); - unicodeBaseSymbol.insert("hbar", QChar(0x210F)); - unicodeBaseSymbol.insert("EUR", QChar(0x20AC)); - unicodeBaseSymbol.insert("euro", QChar(0x20AC)); - unicodeBaseSymbol.insert("circ", QChar(0x2218)); - unicodeBaseSymbol.insert("cent", QChar(0x00A2)); - unicodeBaseSymbol.insert("pound", QChar(0x00A3)); - unicodeBaseSymbol.insert("yen", QChar(0x00A5)); - unicodeBaseSymbol.insert("dollar", QChar(0x0024)); - unicodeBaseSymbol.insert("neq", QChar(0x2260)); - unicodeBaseSymbol.insert("lnot", QChar(0x2260)); - unicodeBaseSymbol.insert("Angstrom", QChar(0x00AC)); - unicodeBaseSymbol.insert("co", QChar(0x2105)); - unicodeBaseSymbol.insert("No", QChar(0x2116)); - unicodeBaseSymbol.insert("Ohm", QChar(0x2126)); - unicodeBaseSymbol.insert("ohm", QChar(0x2126)); - unicodeBaseSymbol.insert("tcohm", QChar(0x2126)); - unicodeBaseSymbol.insert("partial", QChar(0x2202)); - unicodeBaseSymbol.insert("cdots", QString(QChar(0x00B7)) + QString(QChar(0x00B7)) + QString(QChar(0x00B7))); - unicodeBaseSymbol.insert("approx", QChar(0x2248)); - unicodeBaseSymbol.insert("Angstroem", QChar(0x212B)); - unicodeBaseSymbol.insert("-", QChar(0x2212)); - unicodeBaseSymbol.insert("dots", QChar(0x2026)); - unicodeBaseSymbol.insert("ldots", QChar(0x2026)); - } - - QHash::iterator itbasesymbol = unicodeBaseSymbol.find(n); - if (itbasesymbol!=unicodeBaseSymbol.end()) { - props.symbol = itbasesymbol.value(); - //qDebug()<<"### found "< unicodeSymbol; - if (unicodeSymbol.isEmpty()) { - unicodeSymbol.insert("leftrightarrow", QChar(0x2194)); - unicodeSymbol.insert("leftarrow", QChar(0x2190)); - unicodeSymbol.insert("rightarrow", QChar(0x2192)); - unicodeSymbol.insert("to", QChar(0x2192)); - unicodeSymbol.insert("uparrow", QChar(0x2191)); - unicodeSymbol.insert("downarrow", QChar(0x2193)); - unicodeSymbol.insert("updownarrow", QChar(0x2195)); - unicodeSymbol.insert("Leftrightarrow", QChar(0x21D4)); - unicodeSymbol.insert("iff", QChar(0x21D4)); - unicodeSymbol.insert("Leftarrow", QChar(0x21D0)); - unicodeSymbol.insert("Rightarrow", QChar(0x21D2)); - unicodeSymbol.insert("Uparrow", QChar(0x21D1)); - unicodeSymbol.insert("Downarrow", QChar(0x21D3)); - unicodeSymbol.insert("Updownarrow", QChar(0x21D5)); - unicodeSymbol.insert("mp", QChar(0x2213)); - unicodeSymbol.insert("ll", QChar(0x226A)); - unicodeSymbol.insert("gg", QChar(0x226B)); - unicodeSymbol.insert("Alef", QChar(0x2135)); - unicodeSymbol.insert("Aleph", QChar(0x2135)); - unicodeSymbol.insert("Bet", QChar(0x2136)); - unicodeSymbol.insert("Beth", QChar(0x2136)); - unicodeSymbol.insert("Gimel", QChar(0x2137)); - unicodeSymbol.insert("Dalet", QChar(0x2138)); - unicodeSymbol.insert("alef", QChar(0x2135)); - unicodeSymbol.insert("aleph", QChar(0x2135)); - unicodeSymbol.insert("bet", QChar(0x2136)); - unicodeSymbol.insert("beth", QChar(0x2136)); - unicodeSymbol.insert("gimel", QChar(0x2137)); - unicodeSymbol.insert("dalet", QChar(0x2138)); - unicodeSymbol.insert("nexists", QChar(0x2204)); - unicodeSymbol.insert("ni", QChar(0x220B)); - unicodeSymbol.insert("notni", QChar(0x220C)); - unicodeSymbol.insert("tilde", QChar(0x223C)); - unicodeSymbol.insert("sim", QChar(0x223C)); - unicodeSymbol.insert("emptyset", QChar(0x2300)); - unicodeSymbol.insert("varnothing", QChar(0x2300)); - unicodeSymbol.insert("odot", QChar(0x2299)); - unicodeSymbol.insert("ominus", QChar(0x2296)); - unicodeSymbol.insert("lceil", QChar(0x2308)); - unicodeSymbol.insert("rceil", QChar(0x2309)); - unicodeSymbol.insert("lfloor", QChar(0x230A)); - unicodeSymbol.insert("rfloor", QChar(0x230B)); - unicodeSymbol.insert("subsetnot", QChar(0x2284)); - unicodeSymbol.insert("DC", QChar(0x2393)); - unicodeSymbol.insert("bot", QChar(0x22A4)); - unicodeSymbol.insert("perp", QChar(0x22A5)); - unicodeSymbol.insert("sqcap", QChar(0x2293)); - unicodeSymbol.insert("sqcup", QChar(0x2294)); - unicodeSymbol.insert("triangle", QChar(0x2206)); - unicodeSymbol.insert("square", QChar(0x25A1)); - unicodeSymbol.insert("setminus", QChar(0x2216)); - unicodeSymbol.insert("mid", QChar(0x2223)); - unicodeSymbol.insert("nmid", QChar(0x2224)); - unicodeSymbol.insert("vdots", QChar(0x22EE)); - unicodeSymbol.insert("iddots", QChar(0x22F0)); - unicodeSymbol.insert("ddots", QChar(0x22F1)); - unicodeSymbol.insert("perthousand", QChar(0x2030)); - unicodeSymbol.insert("leftharpoonup", QChar(0x21BC)); - unicodeSymbol.insert("rightharpoonup", QChar(0x21C0)); - unicodeSymbol.insert("upharpoonleft", QChar(0x21BF)); - unicodeSymbol.insert("downharpoonleft", QChar(0x21C3)); - unicodeSymbol.insert("leftrightharpoon", QChar(0x21CB)); - unicodeSymbol.insert("rightleftharpoon", QChar(0x21CC)); - unicodeSymbol.insert("leftharpoondown", QChar(0x21BD)); - unicodeSymbol.insert("rightharpoondown", QChar(0x21C1)); - unicodeSymbol.insert("upharpoonright", QChar(0x21BE)); - unicodeSymbol.insert("downharpoonright", QChar(0x21C2)); - unicodeSymbol.insert("nwarrow", QChar(0x2196)); - unicodeSymbol.insert("nearrow", QChar(0x2197)); - unicodeSymbol.insert("searrow", QChar(0x2198)); - unicodeSymbol.insert("swarrow", QChar(0x2199)); - unicodeSymbol.insert("mapsto", QChar(0x21A6)); - unicodeSymbol.insert("div", QChar(0x00F7)); - unicodeSymbol.insert("multimap", QChar(0x22B8)); - unicodeSymbol.insert("maporiginal", QChar(0x22B6)); - unicodeSymbol.insert("mapimage", QChar(0x22B7)); - unicodeSymbol.insert("benzene", QChar(0x232C)); - unicodeSymbol.insert("propto", QChar(0x221D)); - unicodeSymbol.insert("ne", QChar(0x2260)); - unicodeSymbol.insert("equiv", QChar(0x2261)); - unicodeSymbol.insert("ellipsis", QChar(0x2026)); - unicodeSymbol.insert("Im", QChar(0x2111)); - unicodeSymbol.insert("Re", QChar(0x211C)); - unicodeSymbol.insert("otimes", QChar(0x2297)); - unicodeSymbol.insert("oplus", QChar(0x2295)); - unicodeSymbol.insert("oslash", QChar(0x2298)); - unicodeSymbol.insert("cap", QChar(0x2229)); - unicodeSymbol.insert("land", QChar(0x2229)); - unicodeSymbol.insert("cup", QChar(0x222A)); - unicodeSymbol.insert("lor", QChar(0x222A)); - unicodeSymbol.insert("supset", QChar(0x2283)); - unicodeSymbol.insert("supseteq", QChar(0x2286)); - unicodeSymbol.insert("supsetnot", QChar(0x2285)); - unicodeSymbol.insert("subset", QChar(0x2282)); - unicodeSymbol.insert("subseteq", QChar(0x2286)); - unicodeSymbol.insert("in", QChar(0x2208)); - unicodeSymbol.insert("notin", QChar(0x2209)); - unicodeSymbol.insert("angle", QChar(0x2220)); - unicodeSymbol.insert("measuredangle", QChar(0x2221)); - unicodeSymbol.insert("sphericalangle", QChar(0x2222)); - unicodeSymbol.insert("rightangle", QChar(0x221F)); - unicodeSymbol.insert("nabla", QChar(0x2207)); - unicodeSymbol.insert("parallel", QChar(0x2225)); - unicodeSymbol.insert("nparallel", QChar(0x2226)); - unicodeSymbol.insert("neg", QChar(0x00AC)); - unicodeSymbol.insert("wedge", QChar(0x2227)); - unicodeSymbol.insert("vee", QChar(0x2228)); - unicodeSymbol.insert("langle", QChar(0x2329)); - unicodeSymbol.insert("rangle", QChar(0x232A)); - unicodeSymbol.insert("forall", QChar(0x2200)); - unicodeSymbol.insert("exists", QChar(0x2203)); - unicodeSymbol.insert("bot", QChar(0x22A5)); - unicodeSymbol.insert("geqq", QChar(0x2267)); - unicodeSymbol.insert("leqq", QChar(0x2266)); - unicodeSymbol.insert("prec", QChar(0x227A)); - unicodeSymbol.insert("succ", QChar(0x227B)); - unicodeSymbol.insert("vartriangleleft", QChar(0x22B2)); - unicodeSymbol.insert("cong", QChar(0x2245)); - unicodeSymbol.insert("simeq", QChar(0x2243)); - unicodeSymbol.insert("therefore", QChar(0x2234)); - unicodeSymbol.insert("because", QChar(0x2235)); - unicodeSymbol.insert("lightning", QChar(0x21AF)); - unicodeSymbol.insert("blacksquare", QChar(0x220E)); - unicodeSymbol.insert("Box", QChar(0x25A1)); - unicodeSymbol.insert("celsius", QChar(0x2103)); - unicodeSymbol.insert("AC", QChar(0x223F)); - unicodeSymbol.insert("frown", QChar(0x2322)); - unicodeSymbol.insert("smile", QChar(0x2323)); - unicodeSymbol.insert("smiley", QChar(0x233A)); - unicodeSymbol.insert("blacksmiley", QChar(0x233B)); - unicodeSymbol.insert("frownie", QChar(0x2639)); - unicodeSymbol.insert("varhexagonlrbonds", QChar(0x232C)); - unicodeSymbol.insert("hexagon", QChar(0x2394)); - unicodeSymbol.insert("varcarriagereturn", QChar(0x23CE)); - unicodeSymbol.insert("benzenr", QChar(0x23E3)); - unicodeSymbol.insert("trapezium", QChar(0x23E2)); - unicodeSymbol.insert("female", QChar(0x2640)); - unicodeSymbol.insert("male", QChar(0x2642)); - - unicodeSymbol.insert("accurrent", QChar(0x23E6)); - } - - QHash::iterator itsymbol = unicodeSymbol.find(n); - - if (itsymbol!=unicodeSymbol.end()) { - props.symbol = itsymbol.value(); - } - else if (n == "sum") { props.symbol = QChar(0x2211); props.heightIsAscent = true; props.exactAscent = true; } - else if (n == "prod") { props.symbol = QChar(0x220F); props.heightIsAscent = true; props.exactAscent = true; } - else if (n == "bbC") { props.symbol = QChar(0x2102); props.italic = -1; } - else if (n == "bbH") { props.symbol = QChar(0x210D); props.italic = -1; } - else if (n == "bbN") { props.symbol = QChar(0x2115); props.italic = -1; } - else if (n == "bbP") { props.symbol = QChar(0x2119); props.italic = -1; } - else if (n == "bbQ") { props.symbol = QChar(0x211A); props.italic = -1; } - else if (n == "bbR") { props.symbol = QChar(0x211D); props.italic = -1; } - else if (n == "bbZ") { props.symbol = QChar(0x2124); props.italic = -1; } - else if (n == "iint") { props.symbol = QChar(0x222C); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } - else if (n == "iiint") { props.symbol = QChar(0x222D); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } - else if (n == "oint") { props.symbol = QChar(0x222E); 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 == "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 == "int") { props.symbol = QChar(0x222B); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } - else {return false;} - return true; -} - -bool JKQTMathText::MTsymbolNode::getSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps& props, const QString &n, const MTenvironment& currentEv, double mathFontFactor) const -{ - auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Text); - auto fntGreek=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Greek); - auto fntSym=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Symbols); - - //qDebug()<<"--- getSymbolProp("<getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Text); - auto fntSym=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Symbols); - auto fntGreek=parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Greek); - - JKQTMathText::MTsymbolNode::SymbolProps props; - double mathFontFactor=1.8; - props.symbol=""; - props.fontFactor=1.0; - props.bold=0; - props.italic=-1; - props.yfactor=0; - props.drawBar=false; - props.font=fnt.first; - props.heightIsAscent=false; - props.exactAscent=false; - props.extendWidthInMathmode=false; - - QString n=symName; - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // statische Lookup-Tabellen vorbereiten - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - static QStringList extendWInMM; - if (extendWInMM.isEmpty()) { - extendWInMM <<"ll"<<"gg"<<"leq"<<"geq"<<"leftrightarrow"<<"leftarrow"<<"rightarrow"<<"to"<<"uparrow"<<"downarrow"<<"updownarrow"<<"Leftrightarrow" - <<"iff"<<"Leftarrow"<<"Rightarrow"<<"Uparrow"<<"Downarrow"<<"Updownarrow"<<"pm"<<"mp"<<"nexists"<<"ni"<<"notni"<<"circ"<<"sim"<<"emptyset"<<"odot"<<"ominus" - <<"subsetnot"<<"bot"<<"leftharpoonup"<<"rightharpoonup"<<"upharpoonleft"<<"downharpoonleft"<<"leftrightharpoon"<<"rightleftharpoon"<<"coprod"<<"leftharpoondown" - <<"rightharpoondown"<<"upharpoonright"<<"downharpoonright"<<"nwarrow"<<"nearrow"<<"searrow"<<"swarrow"<<"mapsto"<<"div"<<"multimap"<<"maporiginal"<<"mapimage" - <<"times"<<"propto"<<"bullet"<<"neq"<<"ne"<<"equiv"<<"approx"<<"otimes"<<"oplus"<<"oslash"<<"cap"<<"land"<<"cup"<<"lor"<<"supset"<<"supseteq"<<"supsetnot" - <<"subset"<<"subseteq"<<"in"<<"notin"<<"cdot"<<"wedge"<<"vee"<<"cong"<<"bot"<<"mid"<<"+"<<"-"<<"|"<<"*"<<"/"<<"<"<<">"; - } - - if (extendWInMM.contains(n)) { - props.extendWidthInMathmode=true; - } - - - static QHash simpleTranslations; - if (simpleTranslations.isEmpty()) { - simpleTranslations.insert("", " "); - simpleTranslations.insert("sin", "sin"); - simpleTranslations.insert("cos", "cos"); - simpleTranslations.insert("tan", "tan"); - simpleTranslations.insert("sinh", "sinh"); - simpleTranslations.insert("cosh", "cosh"); - simpleTranslations.insert("tanh", "tanh"); - simpleTranslations.insert("atan", "atan"); - simpleTranslations.insert("acos", "acos"); - simpleTranslations.insert("asin", "asin"); - simpleTranslations.insert("arcsin", "arcsin"); - simpleTranslations.insert("arccos", "arccos"); - simpleTranslations.insert("arctan", "arctan"); - simpleTranslations.insert("degree", QLatin1String("\xB0")); - simpleTranslations.insert("textdegree ", QLatin1String("\xB0")); - simpleTranslations.insert("ii", "i"); - simpleTranslations.insert("dd", "d"); - simpleTranslations.insert("exp", "exp"); - simpleTranslations.insert("log", "log"); - simpleTranslations.insert("ln", "ln"); - simpleTranslations.insert("ld", "ld"); - simpleTranslations.insert("lb", "lb"); - simpleTranslations.insert("argmin", "argmin"); - simpleTranslations.insert("argmax", "argmax"); - simpleTranslations.insert("max", "max"); - simpleTranslations.insert("mod", "mod"); - simpleTranslations.insert("min", "min"); - simpleTranslations.insert("median", "median"); - simpleTranslations.insert("sign", "sign"); - simpleTranslations.insert("sgn", "sgn"); - simpleTranslations.insert("sec", "sec"); - simpleTranslations.insert("gcd", "gcd"); - simpleTranslations.insert("hom", "hom"); - simpleTranslations.insert("ker", "ker"); - simpleTranslations.insert("dim", "dim"); - simpleTranslations.insert("cot", "cot"); - simpleTranslations.insert("arg", "arg"); - simpleTranslations.insert("det", "det"); - simpleTranslations.insert("deg", "deg"); - simpleTranslations.insert("Pr", "Pr"); - simpleTranslations.insert("coth", "coth"); - } - - - static QHash simpleTranslations_heightIsAscent; - if (simpleTranslations_heightIsAscent.isEmpty()) { - simpleTranslations_heightIsAscent.insert("erf", "erf"); - simpleTranslations_heightIsAscent.insert("median", "median"); - simpleTranslations_heightIsAscent.insert("min", "min"); - simpleTranslations_heightIsAscent.insert("max", "max"); - simpleTranslations_heightIsAscent.insert("inf", "inf"); - simpleTranslations_heightIsAscent.insert("sup", "sup"); - simpleTranslations_heightIsAscent.insert("liminf", "liminf"); - simpleTranslations_heightIsAscent.insert("limsup", "limsup"); - simpleTranslations_heightIsAscent.insert("lim", "lim"); - } - - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - props.font=fnt.first; - QString errorExplanation=""; - QHash::iterator itsimple = simpleTranslations.find(n); - if (itsimple!= simpleTranslations.end()) { - props.symbol=itsimple.value(); - } else { - QHash::iterator itsimplehia = simpleTranslations_heightIsAscent.find(n); - if (itsimplehia != simpleTranslations_heightIsAscent.end()) { - props.symbol = itsimplehia.value(); - props.heightIsAscent = true; - } else { - props.font=fnt.first; - if (!getSymbolProp(props, n, currentEv, mathFontFactor)) { - errorExplanation="didn't find symbol given font def:"+fnt.first+"["+encoding2String(fnt.second)+"] / sym:"+fntSym.first+"["+encoding2String(fntSym.second)+"] / grk:"+fntGreek.first+"["+encoding2String(fntGreek.second)+"]"; - } - } - } - if (addWhitespace) props.symbol+=" "; - - static QSet extraSymbolName = { - "infty", - "|", " ", "quad", "qquad", "space", ";", ":", ",", "!","%" - "longleftarrow", "longrightarrow", - "Longleftarrow", "Longrightarrow", - "longleftrightarrow", "Longleftrightarrow" - }; - - - static QSet extraSymbolNonItalic = { - "+", "-", "*", "/", "<", ">", "=", "|", "{", "(", "[", "]", ")", "}", "\\" - }; - - if (props.symbol.simplified().isEmpty() && extraSymbolNonItalic.contains(n)) { - props.symbol=n; - if (n=="=") props.symbol="= "; - props.italic=-1; - } - - if (props.symbol.simplified().isEmpty() && !extraSymbolName.contains(n)) { - parent->error_list.append(tr("unknown symbol '%1' found (%2)!").arg(n).arg(errorExplanation)); - } - - //qDebug()<0) f.setItalic(true); - if (props.bold<0) f.setBold(false); - if (props.bold>0) f.setBold(true); - QFontMetricsF fm(f, painter.device()); - QString symb=props.symbol; - width=0; - if (currentEv.insideMath) width=qMax(parent->getTightBoundingRect(f, symb, painter.device()).width(),parent->getTightBoundingRect(f, "i", painter.device()).width());//fm.width(symbol); - else width=fm.boundingRect(symb).width();//fm.width(symbol); - - width=qMax(fm.boundingRect("j").width(), width); - if (symb.isEmpty()) { - width=fm.boundingRect("a").width(); - if (symbolName=="|") width=fm.boundingRect("1").width()*0.8; - else if (symbolName=="infty") width=fm.boundingRect("M").width(); - else if (symbolName=="quad" || symbolName=="qquad") width=parent->getTightBoundingRect(f, "M", painter.device()).width(); - else if (symbolName==" " || symbolName=="space") width=parent->getTightBoundingRect(f, "x", painter.device()).width(); - else if (symbolName==";") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.75; - else if (symbolName==":") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.5; - else if (symbolName==",") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.25; - else if (symbolName=="!") width=-parent->getTightBoundingRect(f, "x", painter.device()).width()*0.25; - else if (symbolName=="longleftarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="longrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="Longleftarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="Longrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="longleftrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } - else if (symbolName=="Longleftrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } - } - QRectF tbr=parent->getTightBoundingRect(f, symb, painter.device()); - overallHeight=tbr.height();// fm.height(); - baselineHeight=tbr.height()-tbr.bottom(); - if (props.exactAscent) { - //baselineHeight=fm.ascent()*0.8; - } - if (props.heightIsAscent) { - overallHeight=baselineHeight*1.1; - } - if (props.exactAscent && props.heightIsAscent) { - //qDebug()<getMathoperatorWidthFactor(); - -} - -double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* /*prevNodeSize*/) { - doDrawBoxes(painter, x, y, currentEv); - double width=0; - double baselineHeight=0; - double overallHeight=0, strikeoutPos=0; - getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - QPen pold=painter.pen(); - QFont fold=painter.font(); - QFont f=currentEv.getFont(parent); - QFont f1=f; - auto props=getSymbolProp(symbolName, currentEv); - f.setFamily(props.font); - f.setPointSizeF(f.pointSizeF()*props.fontFactor); - if (props.italic<0) f.setItalic(false); - if (props.italic>0) f.setItalic(true); - if (props.bold<0) f.setBold(false); - if (props.bold>0) f.setBold(true); - QFontMetricsF fm(f, painter.device()); - QFontMetricsF fm1(f1, painter.device()); - painter.setFont(f); - - double shift=0; - if (props.extendWidthInMathmode && currentEv.insideMath) { - double origwidth=width/parent->getMathoperatorWidthFactor(); - shift=0.5*(width-origwidth); - //width=width*parent->getMathoperatorWidthFactor(); - } - - //std::cout<<"symbol '"<getTightBoundingRect(f, "M", painter.device()).height()-fm.xHeight())/3.0; - QLineF l(xx, yy, xx+xwi/3.0+((currentEv.italic)?(xwi/3.0):0), yy); - if (props.drawBar&&l.length()>0) painter.drawLine(l); - - // try to draw some often used special symbols, by synthesizing them from - // standard characters in the current drawing font - } else if (symbolName=="infty") { - //std::cout<<"draw infty\n"; - f1.setItalic(false); - painter.setFont(f1); - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(x+shift+fm1.boundingRect("8").width()/3.0, y-fm1.xHeight()); - painter.rotate(90); - painter.drawText(QPointF(0,0), "8"); - - } else if (symbolName=="|") { - //std::cout<<"draw infty\n"; - f1.setItalic(false); - painter.setFont(f1); - - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.translate(x+shift, y); - painter.drawText(QPointF(0,0), "|"); - painter.translate(fm1.boundingRect("8").width()/3.0, 0); - painter.drawText(QPointF(0,0), "|"); - - - // here are some spaces - } else if (symbolName==" ") { // full space (width of x) - } else if (symbolName=="space") { // full space (width of x) - } else if (symbolName=="qquad") { // full space(width of M) - } else if (symbolName=="quad") { // full space(width of M) - } else if (symbolName==";") { // 75% space - } else if (symbolName==":") { // 50% space - } else if (symbolName==",") { // 25% space - } else if (symbolName=="!") { // -25% space - } else if (symbolName=="longleftarrow") { - double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); - painter.drawPath(path); - } else if (symbolName=="longrightarrow"){ - double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); - painter.drawPath(path); - } else if (symbolName=="Longleftarrow") { - double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); - painter.drawPath(path); - } else if (symbolName=="Longrightarrow") { - double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); - painter.drawPath(path); - } else if (symbolName=="longleftrightarrow") { - double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); - painter.drawPath(path); - } else if (symbolName=="Longleftrightarrow") { - double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0; - double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25; - double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0; - QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); - painter.drawPath(path); - } else { // draw a box to indicate an unavailable symbol - QRectF tbr=parent->getTightBoundingRect(f, "M", painter.device()); - painter.drawRect(QRectF(x+shift,y-tbr.height(), xwi, tbr.height()*0.8)); - } - painter.setPen(pold); - painter.setFont(fold); - return x+width; -} - -bool JKQTMathText::MTsymbolNode::toHtml(QString &html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) { - bool ok=true; - QString s; - JKQTMathText::MTenvironment ev=currentEv; - - static QMap entitylut; - if (entitylut.isEmpty()) { - entitylut.insert("sin", "sin"); - entitylut.insert("cos", "cos"); - entitylut.insert("tan", "tan"); - entitylut.insert("sinh", "sinh"); - entitylut.insert("cosh", "cosh"); - entitylut.insert("tanh", "tanh"); - entitylut.insert("atan", "atan"); - entitylut.insert("acos", "acos"); - entitylut.insert("asin", "asin"); - entitylut.insert("arcsin", "arcsin"); - entitylut.insert("arccos", "arccos"); - entitylut.insert("arctan", "arctan"); - entitylut.insert("ii", "i"); - entitylut.insert("dd", "d"); - entitylut.insert("exp", "exp"); - entitylut.insert("log", "log"); - entitylut.insert("ln", "ln"); - entitylut.insert("ld", "ld"); - entitylut.insert("lb", "lb"); - entitylut.insert("erf", "erf"); - entitylut.insert("mod", "mod"); - entitylut.insert("median", "median"); - entitylut.insert("min", "min"); - entitylut.insert("max", "max"); - entitylut.insert("argmin", "argmin"); - entitylut.insert("argmax", "argmax"); - entitylut.insert("inf", "inf"); - entitylut.insert("sup", "sup"); - entitylut.insert("liminf", "liminf"); - entitylut.insert("limsup", "limsup"); - entitylut.insert("lim", "lim"); - entitylut.insert("sec", "sec"); - entitylut.insert("gcd", "gcd"); - entitylut.insert("hom", "hom"); - entitylut.insert("ker", "ker"); - entitylut.insert("dim", "dim"); - entitylut.insert("cot", "cot"); - entitylut.insert("arg", "arg"); - entitylut.insert("det", "det"); - entitylut.insert("deg", "deg"); - entitylut.insert("sign", "sign"); - entitylut.insert("sgn", "sgn"); - entitylut.insert("Pr", "Pr"); - entitylut.insert("coth", "coth"); - entitylut.insert("alpha", "α"); - entitylut.insert("beta", "β"); - entitylut.insert("gamma", "γ"); - entitylut.insert("delta", "δ"); - entitylut.insert("epsilon", "ε"); - entitylut.insert("varepsilon", "ε"); - entitylut.insert("zeta", "ζ"); - entitylut.insert("eta", "η"); - entitylut.insert("theta", "θ"); - entitylut.insert("vartheta", "ϑ"); - entitylut.insert("iota", "ι"); - entitylut.insert("kappa", "κ"); - entitylut.insert("lambda", "λ"); - entitylut.insert("mu", "μ"); - entitylut.insert("nu", "ν"); - entitylut.insert("xi", "ξ"); - entitylut.insert("pi", "π"); - entitylut.insert("varpi", "ϖ"); - entitylut.insert("rho", "ρ"); - entitylut.insert("sigma", "σ"); - entitylut.insert("varsigma", "ς"); - entitylut.insert("tau", "τ"); - entitylut.insert("upsilon", "υ"); - entitylut.insert("phi", "φ"); - entitylut.insert("varphi", "φ"); - entitylut.insert("chi", "χ"); - entitylut.insert("psi", "ψ"); - entitylut.insert("omega", "ω"); - entitylut.insert("Gamma", "Γ"); - entitylut.insert("Delta", "Δ"); - entitylut.insert("Theta", "Θ"); - entitylut.insert("Lambda", "Λ"); - entitylut.insert("Omega", "Ω"); - entitylut.insert("Xi", "Ξ"); - entitylut.insert("Pi", "Π"); - entitylut.insert("Sigma", "Σ"); - entitylut.insert("Upsilon", "Υ"); - entitylut.insert("Phi", "Φ"); - entitylut.insert("Psi", "Ψ"); - entitylut.insert("leftrightarrow", "↔"); - entitylut.insert("leftarrow", "←"); - entitylut.insert("rightarrow", "→"); - entitylut.insert("to", "→"); - entitylut.insert("uparrow", "↑"); - entitylut.insert("downarrow", "↓"); - entitylut.insert("Leftrightarrow", "⇔"); - entitylut.insert("iff", "⇔"); - entitylut.insert("Leftarrow", "⇐"); - entitylut.insert("Rightarrow", "⇒"); - entitylut.insert("Uparrow", "⇑"); - entitylut.insert("Downarrow", "⇓"); - entitylut.insert("pm", "±"); - entitylut.insert("leq", "≤"); - entitylut.insert("geq", "≥"); - entitylut.insert("times", "×"); - entitylut.insert("propto", "∝"); - entitylut.insert("partial", "∂"); - entitylut.insert("bullet", "•"); - entitylut.insert("star", "⋆"); - entitylut.insert("ast", "∗"); - entitylut.insert("asterisk", "∗"); - entitylut.insert("neq", "≠"); - entitylut.insert("ne", "≠"); - entitylut.insert("equiv", "≡"); - entitylut.insert("approx", "≈"); - entitylut.insert("ellipsis", "..."); - entitylut.insert("Im", "ℑ"); - entitylut.insert("Re", "ℜ"); - entitylut.insert("otimes", "⊗"); - entitylut.insert("oplus", "⊕"); - entitylut.insert("oslash", "/"); - entitylut.insert("cap", "∩"); - entitylut.insert("cup", "∪"); - entitylut.insert("land", "∩"); - entitylut.insert("lor", "∪"); - entitylut.insert("supset", "⊃"); - entitylut.insert("supseteq", "⊇"); - entitylut.insert("supsetnot", "⊅"); - entitylut.insert("subset", "⊂"); - entitylut.insert("subseteq", "⊆"); - entitylut.insert("in", "∈"); - entitylut.insert("notin", "∉"); - entitylut.insert("angle", "∠"); - entitylut.insert("nabla", "∇"); - entitylut.insert("copyright", "©"); - entitylut.insert("registered", "®"); - entitylut.insert("trademark", "™"); - entitylut.insert("textregistered", "™"); - entitylut.insert("cdot", "⋅"); - entitylut.insert("neg", "¬"); - entitylut.insert("wedge", "∧"); - entitylut.insert("vee", "∨"); - entitylut.insert("diamond", "◊"); - entitylut.insert("langle", "⟨"); - entitylut.insert("rangle", "⟩"); - entitylut.insert("int", "∫"); - entitylut.insert("forall", "∀"); - entitylut.insert("exists", "∃"); - entitylut.insert("cong", "∼"); - entitylut.insert("bot", "⊥"); - - - entitylut.insert("ll", "<<"); - entitylut.insert("gg", ">>"); - entitylut.insert("bbC", "C"); - entitylut.insert("bbH", "H"); - entitylut.insert("bbN", "N"); - entitylut.insert("bbP", "P"); - entitylut.insert("bbQ", "Q"); - entitylut.insert("bbR", "R"); - entitylut.insert("bbZ", "Z"); - entitylut.insert("Alef", "ℵ"); - entitylut.insert("alef", "ℵ"); - entitylut.insert("tilde", "~"); - entitylut.insert("iint", "∫∫"); - entitylut.insert("iiint", "∫∫∫"); - entitylut.insert("emptyset", "∅"); - entitylut.insert("varnothing", "∅"); - entitylut.insert("lceil", "⌈"); - entitylut.insert("rceil", "⌉"); - entitylut.insert("lfloor", "⌊"); - entitylut.insert("rfloor", "⌋"); - entitylut.insert("subsetnot", "⊄"); - entitylut.insert("DC", "="); - entitylut.insert("cdots", "⋅⋅⋅"); - entitylut.insert("dots", "..."); - entitylut.insert("ldots", "..."); - - entitylut.insert("cent", "¢"); - - entitylut.insert("_", "_"); - entitylut.insert("}", "}"); - entitylut.insert("{", "{"); - entitylut.insert("hbar", "ℏ"); - entitylut.insert("euro", "€"); - entitylut.insert("pound", "£"); - entitylut.insert("yen", "¥"); - entitylut.insert("div", "÷"); - entitylut.insert("backslash", "\\"); - entitylut.insert("$", "$"); - entitylut.insert("%", "%"); - entitylut.insert("&", "&"); - entitylut.insert("#", "#"); - entitylut.insert("ast", "*"); - entitylut.insert("glq", "'"); - entitylut.insert("grq", "'"); - entitylut.insert("glqq", "\""); - entitylut.insert("grqq", "\""); - entitylut.insert("flq", "<"); - entitylut.insert("frq", ">"); - entitylut.insert("flqq", ""); - entitylut.insert("frqq", ""); - } - - - 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 ok=false; - - if (ok) html=html+ev.toHtmlStart(defaultEv)+s+ev.toHtmlAfter(defaultEv); - return ok; -} - -QString JKQTMathText::MTsymbolNode::getSymbolName() const { - return this->symbolName; -} - -QString JKQTMathText::MTsymbolNode::getSymbolfontName() const { - MTenvironment currentEv; - auto props=getSymbolProp(symbolName, currentEv); - return props.font; -} - -bool JKQTMathText::MTsymbolNode::getAddWhitespace() const -{ - return addWhitespace; -} - // -------------------------------------------------------------------------------------------------- // -- implementation of the JKQTMathText methods @@ -3667,7 +303,7 @@ bool JKQTMathText::useASANA(bool mathModeOnly) return res; } -void JKQTMathText::useAnyUnicode(QString timesFont, const QString &sansFont, JKQTMathText::MTfontEncoding encodingTimes, JKQTMathText::MTfontEncoding encodingSans) +void JKQTMathText::useAnyUnicode(QString timesFont, const QString &sansFont, JKQTMathTextFontEncoding encodingTimes, JKQTMathTextFontEncoding encodingSans) { if (!timesFont.isEmpty()) { setFontRoman(timesFont, encodingTimes); } if (!sansFont.isEmpty()) { setFontSans(sansFont, encodingSans); } @@ -3679,11 +315,11 @@ QString JKQTMathText::toHtml(bool *ok, double fontPointSize) { QString s; bool okk=false; if (getTree()!=nullptr) { - MTenvironment ev; + JKQTMathTextEnvironment ev; ev.color=fontColor; ev.fontSize=fontPointSize; - MTenvironment defaultev; + JKQTMathTextEnvironment defaultev; defaultev.fontSize=fontPointSize; okk=getTree()->toHtml(s, ev, defaultev); @@ -3692,16 +328,6 @@ QString JKQTMathText::toHtml(bool *ok, double fontPointSize) { return s; } -QString JKQTMathText::encoding2String(JKQTMathText::MTfontEncoding e) -{ - switch(e) { - case MTFEunicode: return "MTFEunicode"; - case MTFEStandard: return "MTFEStandard"; - case MTFEunicodeLimited: return "MTFEunicodeLimited"; - case MTFEwinSymbol: return "MTFEwinSymbol"; - } - return "???"; -} void JKQTMathText::setFontColor(const QColor &__value) { @@ -3723,7 +349,7 @@ double JKQTMathText::getFontSize() const return this->fontSize; } -void JKQTMathText::addReplacementFont(const QString &nonUseFont, const QString &useFont, MTfontEncoding useFontEncoding) { +void JKQTMathText::addReplacementFont(const QString &nonUseFont, const QString &useFont, JKQTMathTextFontEncoding useFontEncoding) { fontReplacements.insert(nonUseFont, useFont); fontEncodingReplacements.insert(nonUseFont, useFontEncoding); } @@ -3734,8 +360,8 @@ void JKQTMathText::addReplacementFont(const QString &nonUseFont, const QString & if (it!=fontEncodingReplacements.end()) fontEncodingReplacements.erase(it); } -QPair JKQTMathText::getReplacementFont(const QString &nonUseFont, const QString &defaultFont, JKQTMathText::MTfontEncoding defaultFontEncoding) const { - QPair res(defaultFont, defaultFontEncoding); +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()) { @@ -3748,25 +374,25 @@ QPair JKQTMathText::getReplacementFont(con return res; } -QPair JKQTMathText::getFontData(JKQTMathText::MTenvironmentFont font, bool in_math_environment, FontSubclass subclass) const +QPair JKQTMathText::getFontData(JKQTMathTextEnvironmentFont font, bool in_math_environment, FontSubclass subclass) const { if (in_math_environment) { if (font==MTEroman) font=MTEmathRoman; if (font==MTEsans) font=MTEmathSans; } const auto fd=fontDefinitions.value(font); - if (subclass==FontSubclass::Greek) return QPair(fd.symbolfontGreek, fd.symbolfontGreekEncoding); - if (subclass==FontSubclass::Symbols) return QPair(fd.symbolfontSymbol, fd.symbolfontSymbolEncoding); - return QPair(fd.fontName, fd.fontEncoding); + if (subclass==FontSubclass::Greek) return QPair(fd.symbolfontGreek, fd.symbolfontGreekEncoding); + if (subclass==FontSubclass::Symbols) return QPair(fd.symbolfontSymbol, fd.symbolfontSymbolEncoding); + return QPair(fd.fontName, fd.fontEncoding); } -void JKQTMathText::setFontRomanOrSpecial(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontRomanOrSpecial(const QString &__value, JKQTMathTextFontEncoding encoding) { setFontRomanOrSpecial(JKQTMathTextFontSpecifier::fromFontSpec(__value), encoding); } -void JKQTMathText::setFontRomanOrSpecial(const JKQTMathTextFontSpecifier &fontName, MTfontEncoding encoding) +void JKQTMathText::setFontRomanOrSpecial(const JKQTMathTextFontSpecifier &fontName, JKQTMathTextFontEncoding encoding) { if (!fontName.hasMathFontName()) { if (fontName.fontName().toUpper()=="XITS") useXITS(false); @@ -3785,7 +411,7 @@ void JKQTMathText::setFontRomanOrSpecial(const JKQTMathTextFontSpecifier &fontNa } } -void JKQTMathText::setFontRoman(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontRoman(const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[MTEroman].fontName = f.first; @@ -3797,12 +423,12 @@ QString JKQTMathText::getFontRoman() const return fontDefinitions[MTEroman].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingRoman() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingRoman() const { return fontDefinitions[MTEroman].fontEncoding; } -void JKQTMathText::setFontSans(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontSans(const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[MTEsans].fontName = f.first; @@ -3814,12 +440,12 @@ QString JKQTMathText::getFontSans() const return fontDefinitions[MTEsans].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingSans() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingSans() const { return fontDefinitions[MTEsans].fontEncoding; } -void JKQTMathText::setFontTypewriter(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontTypewriter(const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[MTEtypewriter].fontName = f.first; @@ -3831,12 +457,12 @@ QString JKQTMathText::getFontTypewriter() const return fontDefinitions[MTEtypewriter].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingTypewriter() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingTypewriter() const { return fontDefinitions[MTEtypewriter].fontEncoding; } -void JKQTMathText::setFontScript(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontScript(const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[MTEscript].fontName = f.first; @@ -3848,12 +474,12 @@ QString JKQTMathText::getFontScript() const return fontDefinitions[MTEscript].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingScript() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingScript() const { return fontDefinitions[MTEscript].fontEncoding; } -void JKQTMathText::setFontFraktur(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontFraktur(const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[MTEfraktur].fontName = f.first; @@ -3865,59 +491,59 @@ QString JKQTMathText::getFontFraktur() const return fontDefinitions[MTEfraktur].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingFraktur() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingFraktur() const { return fontDefinitions[MTEfraktur].fontEncoding; } -void JKQTMathText::setSymbolfontGreek(MTenvironmentFont font, const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setSymbolfontGreek(JKQTMathTextEnvironmentFont font, const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[font].symbolfontGreek = f.first; fontDefinitions[font].symbolfontGreekEncoding = f.second; } -void JKQTMathText::setSymbolfontGreek(const QString &fontName, JKQTMathText::MTfontEncoding encoding) +void JKQTMathText::setSymbolfontGreek(const QString &fontName, JKQTMathTextFontEncoding encoding) { for (int f=0; f(MTenvironmentFontCount); f++) { - setSymbolfontGreek(static_cast(f), fontName, encoding); + setSymbolfontGreek(static_cast(f), fontName, encoding); } } -QString JKQTMathText::getSymbolfontGreek(MTenvironmentFont font) const +QString JKQTMathText::getSymbolfontGreek(JKQTMathTextEnvironmentFont font) const { return fontDefinitions[font].symbolfontGreek; } -JKQTMathText::MTfontEncoding JKQTMathText::getSymbolfontEncodingGreek(MTenvironmentFont font) const +JKQTMathTextFontEncoding JKQTMathText::getSymbolfontEncodingGreek(JKQTMathTextEnvironmentFont font) const { return fontDefinitions[font].symbolfontGreekEncoding; } -void JKQTMathText::setSymbolfontSymbol(MTenvironmentFont font, const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setSymbolfontSymbol(JKQTMathTextEnvironmentFont font, const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[font].symbolfontSymbol = f.first; fontDefinitions[font].symbolfontSymbolEncoding = f.second; } -void JKQTMathText::setSymbolfontSymbol(const QString &fontName, JKQTMathText::MTfontEncoding encoding) +void JKQTMathText::setSymbolfontSymbol(const QString &fontName, JKQTMathTextFontEncoding encoding) { for (int f=0; f(MTenvironmentFontCount); f++) { - setSymbolfontSymbol(static_cast(f), fontName, encoding); + setSymbolfontSymbol(static_cast(f), fontName, encoding); } } -QString JKQTMathText::getSymbolfontSymbol(MTenvironmentFont font) const +QString JKQTMathText::getSymbolfontSymbol(JKQTMathTextEnvironmentFont font) const { return fontDefinitions[font].symbolfontSymbol; } -JKQTMathText::MTfontEncoding JKQTMathText::getSymbolfontEncodingSymbol(MTenvironmentFont font) const +JKQTMathTextFontEncoding JKQTMathText::getSymbolfontEncodingSymbol(JKQTMathTextEnvironmentFont font) const { return fontDefinitions[font].symbolfontSymbolEncoding; } -void JKQTMathText::setFontCaligraphic(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontCaligraphic(const QString &__value, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(__value, __value, encoding); fontDefinitions[MTEcaligraphic].fontName = f.first; @@ -3929,12 +555,12 @@ QString JKQTMathText::getFontCaligraphic() const return fontDefinitions[MTEcaligraphic].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingCaligraphic() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingCaligraphic() const { return fontDefinitions[MTEcaligraphic].fontEncoding; } -void JKQTMathText::setFontMathRoman(const QString &fontName, JKQTMathText::MTfontEncoding encoding) +void JKQTMathText::setFontMathRoman(const QString &fontName, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(fontName, fontName, encoding); fontDefinitions[MTEmathRoman].fontName = f.first; @@ -3946,7 +572,7 @@ QString JKQTMathText::getFontMathRoman() const return fontDefinitions[MTEmathRoman].fontName; } -void JKQTMathText::setFontMathSans(const QString &fontName, JKQTMathText::MTfontEncoding encoding) +void JKQTMathText::setFontMathSans(const QString &fontName, JKQTMathTextFontEncoding encoding) { auto f=getReplacementFont(fontName, fontName, encoding); fontDefinitions[MTEmathSans].fontName = f.first; @@ -3958,17 +584,17 @@ QString JKQTMathText::getFontMathSans() const return fontDefinitions[MTEmathSans].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingMathSans() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingMathSans() const { return fontDefinitions[MTEmathSans].fontEncoding; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingMathRoman() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingMathRoman() const { return fontDefinitions[MTEmathRoman].fontEncoding; } -void JKQTMathText::setFontBlackboard(const QString &__value, MTfontEncoding encoding) +void JKQTMathText::setFontBlackboard(const QString &__value, JKQTMathTextFontEncoding encoding) { blackboardSimulated=false; auto f=getReplacementFont(__value, __value, encoding); @@ -3991,7 +617,7 @@ QString JKQTMathText::getFontBlackboard() const return fontDefinitions[MTEblackboard].fontName; } -JKQTMathText::MTfontEncoding JKQTMathText::getFontEncodingBlackboard() const +JKQTMathTextFontEncoding JKQTMathText::getFontEncodingBlackboard() const { return fontDefinitions[MTEblackboard].fontEncoding; } @@ -4171,6 +797,11 @@ QStringList JKQTMathText::getErrorList() const { return this->error_list; } +void JKQTMathText::addToErrorList(const QString &error) +{ + error_list.append(error); +} + JKQTMathText::tokenType JKQTMathText::getToken() { @@ -4231,7 +862,7 @@ JKQTMathText::tokenType JKQTMathText::getToken() { } else { if (parsingMathEnvironment) { // inside math environments we split texts at every brace {[(|)]} so that - // braces form their own MTtextNode and may be formated accordingly + // braces form their own JKQTMathTextTextNode and may be formated accordingly static QSet mathEnvironmentSpecialChars, mathEnvironmentSpecialEndChars; if (mathEnvironmentSpecialChars.size()==0) { mathEnvironmentSpecialChars<<'(' << '[' << '|' << ')' << ']' << '+' << '-' << '*' << '/' << '<' << '>' << '='; @@ -4278,9 +909,9 @@ JKQTMathText::tokenType JKQTMathText::getToken() { return currentToken=MTTnone; } -JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& quitOnClosingBrace, const QString& quitOnEnvironmentEnd) { +JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOnClosingBrace, const QString& quitOnEnvironmentEnd) { //std::cout<<" entering parseLatexString()\n"; - MTlistNode* nl=new MTlistNode(this); + JKQTMathTextListNode* nl=new JKQTMathTextListNode(this); if (get) getToken(); bool getNew=true; while (currentToken!=MTTnone) { @@ -4295,12 +926,12 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu mathEnvironmentSpecialText<<"+"<<"-"<<"="<<"*"<<"<"<<">"<<"|"<<"/"; } if (mathEnvironmentSpecialText.contains(text.trimmed())) { - nl->addNode(new MTsymbolNode(this, text, addWhite)); + nl->addNode(new JKQTMathTextSymbolNode(this, text, addWhite)); } else { - nl->addNode(new MTtextNode(this, text, addWhite, parsingMathEnvironment)); + nl->addNode(new JKQTMathTextTextNode(this, text, addWhite, parsingMathEnvironment)); } } else { - nl->addNode(new MTtextNode(this, text, addWhite, parsingMathEnvironment)); + nl->addNode(new JKQTMathTextTextNode(this, text, addWhite, parsingMathEnvironment)); } } else if (currentToken==MTTinstruction) { QString name=currentTokenName; @@ -4309,9 +940,9 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu if (currentToken==MTTopenbrace) { //std::cout<<"found '{' after '"<addNode(new MTsqrtNode(this, parseLatexString(true))); + nl->addNode(new JKQTMathTextSqrtNode(this, parseLatexString(true))); } else if (name=="cbrt") { - nl->addNode(new MTsqrtNode(this, parseLatexString(true), 3)); + nl->addNode(new JKQTMathTextSqrtNode(this, parseLatexString(true), 3)); } else if (name=="verb") { QString text=""; currentTokenID++; @@ -4323,87 +954,87 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu if (currentTokenIDaddNode(new MTtextNode(this, text, false)); + nl->addNode(new JKQTMathTextTextNode(this, text, false)); } } else if (name=="frac") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMfrac)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMfrac)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="dfrac") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMdfrac)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMdfrac)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="sfrac" || name=="slantfrac" || name=="xfrac") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMsfrac)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMsfrac)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="stfrac" || name=="nicefrac" || name=="slanttextfrac" || name=="xtfrac") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMstfrac)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMstfrac)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="tfrac") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMtfrac)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMtfrac)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="stackrel") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMstackrel)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMstackrel)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="binom") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTbraceNode(this, "(", ")", new MTfracNode(this, n1, n2, MTFMstackrel))); + if (n1 && n2) nl->addNode(new JKQTMathTextBraceNode(this, "(", ")", new JKQTMathTextFracNode(this, n1, n2, MTFMstackrel))); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="underbrace") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMunderbrace)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMunderbrace)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="underset") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMunderset)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMunderset)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="overbrace") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMoverbrace)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMoverbrace)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="overset") { - MTnode* n1=parseLatexString(true); - MTnode* n2=nullptr; + JKQTMathTextNode* n1=parseLatexString(true); + JKQTMathTextNode* n2=nullptr; if (getToken()==MTTopenbrace) n2=parseLatexString(true); - if (n1 && n2) nl->addNode(new MTfracNode(this, n1, n2, MTFMoverset)); + if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, MTFMoverset)); else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); } else if (name=="begin") { if (getToken()==MTTtext) { QString envname=currentTokenName; while (currentToken!=MTTclosebrace) getToken(); // find closing brace '}' after '\\begin{name' if (envname=="matrix" || envname=="array" || envname=="aligned" || envname=="align" || envname=="cases" || envname=="pmatrix"|| envname=="bmatrix"|| envname=="Bmatrix"|| envname=="vmatrix"|| envname=="Vmatrix") { - QVector< QVector > items; + QVector< QVector > items; //int lines=0; //int cols=0; bool first=true; - QVector line; + QVector line; //std::cout<<"found \\begin{matrix}\n"; while (first || currentToken==MTTampersand || (currentToken==MTTinstruction && currentTokenName=="\\")) { - MTnode* it=parseLatexString(true, "", envname); + JKQTMathTextNode* it=parseLatexString(true, "", envname); if (currentToken==MTTampersand) { //std::cout<<" appending item\n"; line.append(it); @@ -4416,13 +1047,13 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu first=false; } //std::cout<<" creating matrix-node with "<addNode(new MTbraceNode(this, "(", ")", new MTmatrixNode(this, items))); - else if (envname=="cases") nl->addNode(new MTbraceNode(this, "{", "", new MTmatrixNode(this, items))); - else if (envname=="bmatrix") nl->addNode(new MTbraceNode(this, "[", "]", new MTmatrixNode(this, items))); - else if (envname=="Bmatrix") nl->addNode(new MTbraceNode(this, "{", "}", new MTmatrixNode(this, items))); - else if (envname=="vmatrix") nl->addNode(new MTbraceNode(this, "|", "|", new MTmatrixNode(this, items))); - else if (envname=="Vmatrix") nl->addNode(new MTbraceNode(this, "||", "||", new MTmatrixNode(this, items))); - else nl->addNode(new MTmatrixNode(this, items)); + if (envname=="pmatrix") nl->addNode(new JKQTMathTextBraceNode(this, "(", ")", new JKQTMathTextMatrixNode(this, items))); + else if (envname=="cases") nl->addNode(new JKQTMathTextBraceNode(this, "{", "", new JKQTMathTextMatrixNode(this, items))); + else if (envname=="bmatrix") nl->addNode(new JKQTMathTextBraceNode(this, "[", "]", new JKQTMathTextMatrixNode(this, items))); + else if (envname=="Bmatrix") nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", new JKQTMathTextMatrixNode(this, items))); + else if (envname=="vmatrix") nl->addNode(new JKQTMathTextBraceNode(this, "|", "|", new JKQTMathTextMatrixNode(this, items))); + else if (envname=="Vmatrix") nl->addNode(new JKQTMathTextBraceNode(this, "||", "||", new JKQTMathTextMatrixNode(this, items))); + else nl->addNode(new JKQTMathTextMatrixNode(this, items)); //std::cout<<" creating matrix-node ... done!\n"; } else { error_list.append(tr("error @ ch. %1: unknown environment '%2'").arg(currentTokenID).arg(envname)); @@ -4447,47 +1078,47 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu getNew=true; } } else if (name=="vec") { - nl->addNode(new MTdecoratedNode(this, MTDvec, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDvec, parseLatexString(true))); } else if (name=="overline"||name=="oline"||name=="ol") { - nl->addNode(new MTdecoratedNode(this, MTDoverline, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDoverline, parseLatexString(true))); } else if (name=="underline"||name=="uline"||name=="ul") { - nl->addNode(new MTdecoratedNode(this, MTDunderline, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDunderline, parseLatexString(true))); } else if (name=="uuline"||name=="uul") { - nl->addNode(new MTdecoratedNode(this, MTDdoubleunderline, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDdoubleunderline, parseLatexString(true))); } else if (name=="ooline"||name=="ool") { - nl->addNode(new MTdecoratedNode(this, MTDdoubleoverline, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDdoubleoverline, parseLatexString(true))); } else if (name=="arrow"||name=="overrightarrow"||name=="overarrow") { - nl->addNode(new MTdecoratedNode(this, MTDarrow, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDarrow, parseLatexString(true))); } else if (name=="hat" || name=="^") { - nl->addNode(new MTdecoratedNode(this, MTDhat, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDhat, parseLatexString(true))); } else if (name=="widehat") { - nl->addNode(new MTdecoratedNode(this, MTDwidehat, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDwidehat, parseLatexString(true))); } else if (name=="check" || name=="v") { - nl->addNode(new MTdecoratedNode(this, MTDcheck, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDcheck, parseLatexString(true))); } else if (name=="widecheck") { - nl->addNode(new MTdecoratedNode(this, MTDwidecheck, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDwidecheck, parseLatexString(true))); } else if (name=="bar") { - nl->addNode(new MTdecoratedNode(this, MTDbar, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDbar, parseLatexString(true))); } else if (name=="dot" || name==".") { - nl->addNode(new MTdecoratedNode(this, MTDdot, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDdot, parseLatexString(true))); } else if (name=="ocirc") { - nl->addNode(new MTdecoratedNode(this, MTDocirc, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDocirc, parseLatexString(true))); } else if (name=="tilde" || name=="~") { - nl->addNode(new MTdecoratedNode(this, MTDtilde, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDtilde, parseLatexString(true))); } else if (name=="breve" || name=="u") { - nl->addNode(new MTdecoratedNode(this, MTDbreve, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDbreve, parseLatexString(true))); } else if (name=="widetilde") { - nl->addNode(new MTdecoratedNode(this, MTDwidetilde, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDwidetilde, parseLatexString(true))); } else if (name=="ddot") { - nl->addNode(new MTdecoratedNode(this, MTDddot, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDddot, parseLatexString(true))); } else if (name=="cancel") { - nl->addNode(new MTdecoratedNode(this, MTDcancel, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDcancel, parseLatexString(true))); } else if (name=="xcancel") { - nl->addNode(new MTdecoratedNode(this, MTDxcancel, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDxcancel, parseLatexString(true))); } else if (name=="bcancel") { - nl->addNode(new MTdecoratedNode(this, MTDbcancel, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDbcancel, parseLatexString(true))); } else if (name=="strike" || name=="st" || name=="sout") { - nl->addNode(new MTdecoratedNode(this, MTDstrike, parseLatexString(true))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDstrike, parseLatexString(true))); } else { if (name=="textcolor" || name=="mathcolor" || name=="color" || name=="colorbox") { bool foundError=true; @@ -4501,11 +1132,11 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu } } if (foundError) error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name)); - else nl->addNode(new MTinstruction1Node(this, name, parseLatexString(true), QStringList(col))); + else nl->addNode(new JKQTMathTextInstruction1Node(this, name, parseLatexString(true), QStringList(col))); } else { - nl->addNode(new MTinstruction1Node(this, name, parseLatexString(true))); + nl->addNode(new JKQTMathTextInstruction1Node(this, name, parseLatexString(true))); } } } else { @@ -4557,51 +1188,51 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu if (currentTokenName.size()>0) { if (currentTokenName[0]=='(') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); // we already used the first character from the text token! - nl->addNode(new MTbraceNode(this, "(", ")", parseLatexString(currentTokenName.size()<=0, ")"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "(", ")", parseLatexString(currentTokenName.size()<=0, ")"), showRightBrace)); } else if (currentTokenName[0]=='[') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "[", "]", parseLatexString(currentTokenName.size()<=0, "]"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "[", "]", parseLatexString(currentTokenName.size()<=0, "]"), showRightBrace)); } else if (currentTokenName[0]=='{') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showRightBrace)); } else if (currentTokenName[0]=='<') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "<", ">", parseLatexString(currentTokenName.size()<=0, ">"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "<", ">", parseLatexString(currentTokenName.size()<=0, ">"), showRightBrace)); } else if (currentTokenName[0]=='|') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "|", "|", parseLatexString(currentTokenName.size()<=0, "|"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "|", "|", parseLatexString(currentTokenName.size()<=0, "|"), showRightBrace)); } else if (currentTokenName[0]=='~') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "~", "~", parseLatexString(currentTokenName.size()<=0, "~"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "~", "~", parseLatexString(currentTokenName.size()<=0, "~"), showRightBrace)); } else if (currentTokenName[0]=='_') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "_", "_", parseLatexString(currentTokenName.size()<=0, "_"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "_", "_", parseLatexString(currentTokenName.size()<=0, "_"), showRightBrace)); } else if (currentTokenName[0]=='#') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showRightBrace)); } else if (currentTokenName[0]=='.') { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - JKQTMathText::MTnode* cn=parseLatexString(currentTokenName.size()<=0, "any"); - nl->addNode(new MTbraceNode(this, ".", currentTokenName, cn, showRightBrace)); + JKQTMathTextNode* cn=parseLatexString(currentTokenName.size()<=0, "any"); + nl->addNode(new JKQTMathTextBraceNode(this, ".", currentTokenName, cn, showRightBrace)); } else { getNew=false; } } } else if (currentToken==MTTinstruction && currentTokenName=="langle") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "<", ">", parseLatexString(true, ">"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "<", ">", parseLatexString(true, ">"), showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="{") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "{", "}", parseLatexString(currentTokenName.size()<=0, "}"), showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="lfloor") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "_", "_", parseLatexString(true, "_"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "_", "_", parseLatexString(true, "_"), showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="lceil") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "~", "~", parseLatexString(true, "~"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "~", "~", parseLatexString(true, "~"), showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName=="|") { currentTokenName=currentTokenName.right(currentTokenName.size()-1); - nl->addNode(new MTbraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showRightBrace)); + nl->addNode(new JKQTMathTextBraceNode(this, "#", "#", parseLatexString(currentTokenName.size()<=0, "#"), showRightBrace)); } else if (currentToken==MTTinstruction && currentTokenName==quitOnClosingBrace) { break; } @@ -4616,11 +1247,11 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu if (n0=='v' && n1.isLetter()) { done=true; //std::cout<<"found \\v... command\n"; - nl->addNode(new MTdecoratedNode(this, MTDvec, new MTtextNode(this, QString(n1), false, parsingMathEnvironment))); + nl->addNode(new JKQTMathTextDecoratedNode(this, MTDvec, new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); } else if (n0=='c' && n1.isLetter()) { done=true; //std::cout<<"found \\v... command\n"; - nl->addNode(new MTinstruction1Node(this, "mathcal", new MTtextNode(this, QString(n1), false, parsingMathEnvironment))); + nl->addNode(new JKQTMathTextInstruction1Node(this, "mathcal", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); } } else if (name.size()==3) { QString n0=name.left(2); @@ -4628,74 +1259,74 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu if (n0=="bb" && n1.isLetter()) { done=true; //std::cout<<"found \\v... command\n"; - nl->addNode(new MTinstruction1Node(this, "mathbb", new MTtextNode(this, QString(n1), false, parsingMathEnvironment))); + nl->addNode(new JKQTMathTextInstruction1Node(this, "mathbb", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment))); } } - if (!done) nl->addNode(new MTsymbolNode(this, name, false));//, addWhite)); + if (!done) nl->addNode(new JKQTMathTextSymbolNode(this, name, false));//, addWhite)); } } } else if (currentToken==MTTwhitespace) { - if (!parsingMathEnvironment) nl->addNode(new MTwhitespaceNode(this)); + if (!parsingMathEnvironment) nl->addNode(new JKQTMathTextWhitespaceNode(this)); } else if (currentToken==MTTunderscore) { getToken(); - MTnode* child=nullptr; - MTnode* child2=nullptr; + JKQTMathTextNode* child=nullptr; + JKQTMathTextNode* child2=nullptr; if (currentToken==MTTinstruction) { QString name=currentTokenName; getToken(); // look at next token if (currentToken==MTTopenbrace) { - child=new MTinstruction1Node(this, name, parseLatexString(true)); + child=new JKQTMathTextInstruction1Node(this, name, parseLatexString(true)); } else { //bool addWhite=(currentToken==MTTwhitespace); //getNew=addWhite; - //child=new MTsymbolNode(this, name, addWhite); + //child=new JKQTMathTextSymbolNode(this, name, addWhite); getNew=false; - child=new MTsymbolNode(this, name, false); + child=new JKQTMathTextSymbolNode(this, name, false); } } else if (currentToken==MTTopenbrace) { child=parseLatexString(true); } else if (currentToken==MTTtext) { if (currentTokenName.size()<=1) { - child=new MTtextNode(this, currentTokenName, false, parsingMathEnvironment); + child=new JKQTMathTextTextNode(this, currentTokenName, false, parsingMathEnvironment); } else { - child=new MTtextNode(this, QString(currentTokenName[0]), false, parsingMathEnvironment); - child2=new MTtextNode(this, currentTokenName.right(currentTokenName.size()-1), false, parsingMathEnvironment); + child=new JKQTMathTextTextNode(this, QString(currentTokenName[0]), false, parsingMathEnvironment); + child2=new JKQTMathTextTextNode(this, currentTokenName.right(currentTokenName.size()-1), false, parsingMathEnvironment); } } else { getNew=false; } - if (child!=nullptr) nl->addNode(new MTsubscriptNode(this, child)); + if (child!=nullptr) nl->addNode(new JKQTMathTextSubscriptNode(this, child)); if (child2!=nullptr) nl->addNode(child2); } else if (currentToken==MTThat) { getToken(); - MTnode* child=nullptr; - MTnode* child2=nullptr; + JKQTMathTextNode* child=nullptr; + JKQTMathTextNode* child2=nullptr; if (currentToken==MTTinstruction) { QString name=currentTokenName; getToken(); // look at next token if (currentToken==MTTopenbrace) { - child=new MTinstruction1Node(this, name, parseLatexString(true)); + child=new JKQTMathTextInstruction1Node(this, name, parseLatexString(true)); } else { //bool addWhite=(currentToken==MTTwhitespace); //getNew=addWhite; - //child=new MTsymbolNode(this, name, addWhite); + //child=new JKQTMathTextSymbolNode(this, name, addWhite); getNew=false; - child=new MTsymbolNode(this, name, false); + child=new JKQTMathTextSymbolNode(this, name, false); } } else if (currentToken==MTTopenbrace) { child=parseLatexString(true); } else if (currentToken==MTTtext) { if (currentTokenName.size()<=1) { - child=new MTtextNode(this, currentTokenName, false, parsingMathEnvironment); + child=new JKQTMathTextTextNode(this, currentTokenName, false, parsingMathEnvironment); } else { - child=new MTtextNode(this, QString(currentTokenName[0]), false, parsingMathEnvironment); - child2=new MTtextNode(this, currentTokenName.right(currentTokenName.size()-1), false, parsingMathEnvironment); + child=new JKQTMathTextTextNode(this, QString(currentTokenName[0]), false, parsingMathEnvironment); + child2=new JKQTMathTextTextNode(this, currentTokenName.right(currentTokenName.size()-1), false, parsingMathEnvironment); } } else { getNew=false; } - if (child!=nullptr) nl->addNode(new MTsuperscriptNode(this, child)); + if (child!=nullptr) nl->addNode(new JKQTMathTextSuperscriptNode(this, child)); if (child2!=nullptr) nl->addNode(child2); } else if (currentToken==MTTopenbrace) { nl->addNode(parseLatexString(true)); @@ -4709,7 +1340,7 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu break; } else { // starting math environment parsingMathEnvironment=true; - nl->addNode(new MTinstruction1Node(this, "equation", parseLatexString(true))); + nl->addNode(new JKQTMathTextInstruction1Node(this, "equation", parseLatexString(true))); } } if (getNew) getToken(); @@ -4718,44 +1349,11 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu return nl; } -JKQTMathText::MTnode *JKQTMathText::getParsedNode() const { +JKQTMathTextNode *JKQTMathText::getParsedNode() const { return this->parsedNode; } -QList JKQTMathText::tbrs=QList(); -QHash JKQTMathText::tbrh=QHash(); - -QRectF JKQTMathText::getTightBoundingRect(const QFont &fm, const QString &text, QPaintDevice *pd) -{ - JKQTMathText::tbrDataH dh(fm, text, pd); - if (pd) { - if (tbrh.contains(dh)) return tbrh[dh]; - /*for (int i=0; ilogicalDpiX() && tbrs[i].ldpiY==pd->logicalDpiY() && tbrs[i].pdpiX==pd->physicalDpiX() && tbrs[i].pdpiY==pd->physicalDpiY())) { - //qDebug()<<" ### "<setDrawBoxes(drawBoxes); @@ -4873,566 +1471,13 @@ void JKQTMathText::draw(QPainter& painter, unsigned int flags, QRectF rect, bool } } -JKQTMathText::MTwhitespaceNode::MTwhitespaceNode(JKQTMathText *_parent): - MTtextNode(_parent, " ", false, false) -{ -} - -JKQTMathText::MTwhitespaceNode::~MTwhitespaceNode() -= default; - -QString JKQTMathText::MTwhitespaceNode::getTypeName() const -{ - return QLatin1String("MTwhitespaceNode(")+text+")"; -} - -bool JKQTMathText::MTwhitespaceNode::toHtml(QString &html, JKQTMathText::MTenvironment /*currentEv*/, JKQTMathText::MTenvironment /*defaultEv*/) { - html=html+" "; - return true; -} - -void JKQTMathText::MTnode::setDrawBoxes(bool draw) -{ - this->drawBoxes=draw; -} - -QString JKQTMathText::MTnode::getTypeName() const -{ - return "MTnode"; -} - -QString JKQTMathText::fracModeToString(JKQTMathText::MTfracMode mode) -{ - switch(mode) { - case MTFMfrac: - return "frac"; - case MTFMdfrac: - return "dfrac"; - case MTFMsfrac: - return "sfrac"; - case MTFMstfrac: - return "stfrac"; - case MTFMtfrac: - return "tfrac"; - case MTFMunderbrace: - return "underbrace"; - case MTFMoverbrace: - return "overbrace"; - case MTFMunderset: - return "underset"; - case MTFMoverset: - return "overset"; - case MTFMstackrel: - return "stackrel"; - } - return "unknown"; -} - - -QString JKQTMathText::decorationToString(JKQTMathText::MTdecoration mode) -{ - switch(mode) { - case MTDvec: - return "vec"; - case MTDtilde: - return "tilde"; - case MTDbreve: - return "breve"; - case MTDwidetilde: - return "widetilde"; - case MTDhat: - return "hat"; - case MTDwidehat: - return "widehat"; - case MTDcheck: - return "check"; - case MTDwidecheck: - return "widecheck"; - case MTDocirc: - return "ocirc"; - case MTDdot: - return "dot"; - case MTDddot: - return "ddot"; - case MTDbar: - return "bar"; - case MTDarrow: - return "arrow"; - case MTDoverline: - return "overline"; - case MTDdoubleoverline: - return "double overline"; - case MTDunderline: - return "underline"; - case MTDdoubleunderline: - return "double underline"; - case MTDcancel: - return "cancel"; - case MTDbcancel: - return "bcancel"; - case MTDxcancel: - return "xcancel"; - case MTDstrike: - return "strike"; - } - return "unknown"; -} - -JKQTMathText::MTnode *JKQTMathText::getTree() const { +JKQTMathTextNode *JKQTMathText::getTree() const { if (useUnparsed) return unparsedNode; return parsedNode; } -JKQTMathTextLabel::JKQTMathTextLabel(QWidget *parent): - QLabel(parent) -{ - m_mathText=new JKQTMathText(this); - m_mathText->useXITS(); - m_mathText->setFontSize(font().pointSizeF()*1.3); - lastText=""; - repaintDo=true; - buffer=QPixmap(); -} - -JKQTMathTextLabel::~JKQTMathTextLabel() -= default; - -JKQTMathText *JKQTMathTextLabel::getMathText() const -{ - return m_mathText; -} - -void JKQTMathTextLabel::setMath(const QString &text, bool doRepaint) -{ - if (text!=lastText || doRepaint){ - lastText=text; - repaintDo=true; - internalPaint(); - update(); - } -} - - -void JKQTMathTextLabel::internalPaint() -{ - //return; - //qDebug()<<"internalPaint "<parse(lastText)<<"\n "<getErrorList().join("\n")<<"\n\n"; - if (!m_mathText->parse(lastText)) { - //qDebug()<<"JKQTMathTextLabel::internalPaint(): parse '"<parse(lastText)<<"\n "<getErrorList().join("\n")<<"\n\n"; - } - if (buffer.width()<=0 || buffer.height()<=0) { - const qreal dpr = devicePixelRatioF(); - buffer=QPixmap(1000*dpr,100*dpr); - buffer.setDevicePixelRatio(dpr); - } - //qDebug()<<"internalPaint(): buffer "<getSize(p); - p.end(); - } - const qreal dpr = devicePixelRatioF(); - buffer=QPixmap(static_cast(qMax(32.0,size.width()*1.2))*dpr, static_cast(qMax(10.0,size.height()*1.1))*dpr); - buffer.setDevicePixelRatio(dpr); - buffer.fill(Qt::transparent); - { - qDebug()<<"internalPaint(): buffer.size()="<draw(p,alignment(), QRectF(QPointF(0,0), size)); - p.end(); - } - setPixmap(buffer); - //} - //qDebug()<<"internalPaint(): setPixmap"; - QApplication::processEvents(); - //qDebug()<<"internalPaint(): DONE"; -} - -void JKQTMathTextLabel::paintEvent(QPaintEvent *event) -{ - QLabel::paintEvent(event); -} -JKQTMathText::tbrData::tbrData(const QFont &f, const QString &text, QPaintDevice *pd): - fm(f, pd) -{ - this->text=text; - this->tbr=this->fm.tightBoundingRect(text); - this->f=f; - //this->pd=pd; - if (pd) { - ldpiX=pd->logicalDpiX(); - ldpiY=pd->logicalDpiY(); - pdpiX=pd->physicalDpiX(); - pdpiY=pd->physicalDpiY(); - } else { - ldpiX=0; - ldpiY=0; - pdpiX=0; - pdpiY=0; - } -} -bool JKQTMathText::tbrData::operator==(const JKQTMathText::tbrData &other) const -{ - return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f; -} - - -JKQTMathText::tbrDataH::tbrDataH(const QFont &f, const QString &text, QPaintDevice *pd) -{ - this->text=text; - this->f=f; - if (pd) { - ldpiX=pd->logicalDpiX(); - ldpiY=pd->logicalDpiY(); - pdpiX=pd->physicalDpiX(); - pdpiY=pd->physicalDpiY(); - } else { - ldpiX=0; - ldpiY=0; - pdpiX=0; - pdpiY=0; - } -} - -bool JKQTMathText::tbrDataH::operator==(const JKQTMathText::tbrDataH &other) const -{ - return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f; - -} - - -JKQTMathText::MTplainTextNode::MTplainTextNode(JKQTMathText *_parent, const QString& _text, bool addWhitespace, bool stripInnerWhitepace): - JKQTMathText::MTtextNode(_parent, _text, addWhitespace, stripInnerWhitepace) -{ - -} - -QString JKQTMathText::MTplainTextNode::getTypeName() const -{ - return QLatin1String("MTplainTextNode(")+text+")"; -} - - -QString JKQTMathText::MTplainTextNode::textTransform(const QString &_text, JKQTMathText::MTenvironment /*currentEv*/, bool /*forSize*/) -{ - return _text; -} - -void initJKQTMathTextResources() -{ - static bool initialized=false; - if (!initialized) { -#ifdef JKQTMATHTEXT_COMPILED_WITH_XITS - Q_INIT_RESOURCE(xits); -#endif - initialized=true; - } -} - -JKQTMathText::MTnodeSize::MTnodeSize(): - width(0), baselineHeight(0),overallHeight(0),strikeoutPos() -{ - -} - -JKQTMathText::FontDefinition::FontDefinition(): - fontName("Times New Roman"), fontEncoding(MTFEStandard), - symbolfontGreek("Symbol"), symbolfontGreekEncoding(MTFEwinSymbol), - symbolfontSymbol("Symbol"), symbolfontSymbolEncoding(MTFEwinSymbol) -{ - -} - -JKQTMathTextFontSpecifier::JKQTMathTextFontSpecifier(): - m_fontName(""), - m_mathFontName("") -{ - -} - -JKQTMathTextFontSpecifier::JKQTMathTextFontSpecifier(const QString &_fontName, const QString &_mathFontName): - m_fontName(_fontName), - m_mathFontName(_mathFontName) -{ - -} - -JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::fromFontSpec(const QString &fontSpec) -{ - JKQTMathTextFontSpecifier s; - s.setFontSpec(fontSpec); - return s; -} - -void JKQTMathTextFontSpecifier::setFontSpec(const QString &fontSpec) -{ - QStringList splitspec=fontSpec.split('+'); - if (splitspec.size()==0) { - m_fontName=m_mathFontName=""; - } else if (splitspec.size()==1) { - m_fontName=splitspec[0]; - m_mathFontName=""; - } else if (splitspec.size()==2) { - m_fontName=splitspec[0]; - m_mathFontName=splitspec[1]; - } else if (splitspec.size()>2) { - m_fontName=splitspec.mid(0, splitspec.size()-1).join('+'); - m_mathFontName=splitspec.last(); - } -} - -QString JKQTMathTextFontSpecifier::getFontSpec() const -{ - QString res=m_fontName; - if (m_mathFontName.size()>0) res+="+"+m_mathFontName; - return res; -} - -QString JKQTMathTextFontSpecifier::fontName() const -{ - return transformFontName(m_fontName); -} - -QString JKQTMathTextFontSpecifier::mathFontName() const -{ - return transformFontName(m_mathFontName); -} - -QString JKQTMathTextFontSpecifier::transformFontName(const QString &fontName) -{ - const QString fnt=fontName.trimmed().toLower(); - QFont testFnt; - if (fnt=="serif") { - testFnt.setStyleHint(QFont::StyleHint::Serif); - return testFnt.defaultFamily(); - } - if (fnt=="sans-serif" || fnt=="sansserif" || fnt=="sans" || fnt=="sans serif") { - testFnt.setStyleHint(QFont::StyleHint::SansSerif); - return testFnt.defaultFamily(); - } - if (fnt=="cursive") { - testFnt.setStyleHint(QFont::StyleHint::Cursive); - return testFnt.defaultFamily(); - } - if (fnt=="typewriter") { - testFnt.setStyleHint(QFont::StyleHint::TypeWriter); - return testFnt.defaultFamily(); - } - if (fnt=="monospace") { - testFnt.setStyleHint(QFont::StyleHint::Monospace); - return testFnt.defaultFamily(); - } - if (fnt=="fantasy") { - testFnt.setStyleHint(QFont::StyleHint::Fantasy); - return testFnt.defaultFamily(); - } - if (fnt=="system") { - testFnt.setStyleHint(QFont::StyleHint::System); - return testFnt.defaultFamily(); - } - if (fnt=="decorative") { - testFnt.setStyleHint(QFont::StyleHint::Decorative); - return testFnt.defaultFamily(); - } - if (fnt=="default" || fnt=="app" || fnt=="application") { - return QGuiApplication::font().family(); - } -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - if (fnt=="fixed") { - return QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont).family(); - } - if (fnt=="smallest_readable" || fnt=="smallestreadable" || fnt=="smallest readable" || fnt=="smallest") { - return QFontDatabase::systemFont(QFontDatabase::SystemFont::SmallestReadableFont).family(); - } - if (fnt=="title") { - return QFontDatabase::systemFont(QFontDatabase::SystemFont::TitleFont).family(); - } - if (fnt=="general") { - return QFontDatabase::systemFont(QFontDatabase::SystemFont::GeneralFont).family(); - } -#elif QT_VERSION >= QT_VERSION_CHECK(5,2,0) - QFontDatabase fontDB; - if (fnt=="fixed") { - return fontDB.systemFont(QFontDatabase::SystemFont::FixedFont).family(); - } - if (fnt=="smallest_readable" || fnt=="smallestreadable" || fnt=="smallest readable" || fnt=="smallest") { - return fontDB.systemFont(QFontDatabase::SystemFont::SmallestReadableFont).family(); - } - if (fnt=="title") { - return fontDB.systemFont(QFontDatabase::SystemFont::TitleFont).family(); - } - if (fnt=="general") { - return fontDB.systemFont(QFontDatabase::SystemFont::GeneralFont).family(); - } -#endif - return fontName; -} - -QString JKQTMathTextFontSpecifier::transformFontNameAndDecodeSpecialFonts(const QString &fontName) -{ - const QString fnt=fontName.toLower().trimmed(); - if (fnt=="xits") { - return getXITSFamilies().fontName(); - } else if (fnt=="asana") { - return getASANAFamilies().fontName(); - } else if (fnt=="stix") { - return getSTIXFamilies().fontName(); - } - return transformFontName(fontName); -} - -bool JKQTMathTextFontSpecifier::hasFontName() const -{ - return !m_fontName.isEmpty(); -} - -bool JKQTMathTextFontSpecifier::hasMathFontName() const -{ - return !m_mathFontName.isEmpty(); -} - -JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getXITSFamilies() -{ -#if (QT_VERSION0 && fontSpec.m_fontName.size()>0) { - break; - } - } - if (fontSpec.m_mathFontName.isEmpty() && !fontSpec.m_fontName.isEmpty()) { - fontSpec.m_mathFontName=fontSpec.m_fontName; - } else if (!fontSpec.m_mathFontName.isEmpty() && fontSpec.m_fontName.isEmpty()) { - fontSpec.m_fontName=fontSpec.m_mathFontName; - } - } - - return fontSpec; -} - -JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getASANAFamilies() -{ -#if (QT_VERSION0 && fontSpec.m_fontName.size()>0) { - break; - } - } - if (fontSpec.m_mathFontName.isEmpty() && !fontSpec.m_fontName.isEmpty()) { - fontSpec.m_mathFontName=fontSpec.m_fontName; - } else if (!fontSpec.m_mathFontName.isEmpty() && fontSpec.m_fontName.isEmpty()) { - fontSpec.m_fontName=fontSpec.m_mathFontName; - } - } - - - return fontSpec; -} - -JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getSTIXFamilies() -{ - static QStringList mathNames{"STIX Two Math", "STIX Math", "STIX Two Math Standard", "STIX Math Standard"}; - static QStringList textNames{"STIX", "STIXGeneral", "STIX General"}; - - static JKQTMathTextFontSpecifier fontSpec; - if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) { -#if (QT_VERSION0) { - break; - } - } - if (fontSpec.m_mathFontName.size()>0) { - break; - } - } - for (const QString& name:textNames) { - for (int i=0; i0) { - break; - } - } - if (fontSpec.m_fontName.size()>0) { - break; - } - } - if (fontSpec.m_mathFontName.isEmpty() && !fontSpec.m_fontName.isEmpty()) { - fontSpec.m_mathFontName=fontSpec.m_fontName; - } else if (!fontSpec.m_mathFontName.isEmpty() && fontSpec.m_fontName.isEmpty()) { - fontSpec.m_fontName=fontSpec.m_mathFontName; - } - } - return fontSpec; -} diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h index ace3500525..801249bcdd 100644 --- a/lib/jkqtmathtext/jkqtmathtext.h +++ b/lib/jkqtmathtext/jkqtmathtext.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2008-2020 Jan W. Krieger () + Copyright (c) 2008-2022 Jan W. Krieger () with contributions from: Razi Alavizadeh @@ -19,11 +19,6 @@ */ -/* - Name: jkqtmathtext.h - Copyright: (c) 2010-2019 - Author: Jan krieger , http://www.jkrieger.de/ -*/ @@ -37,87 +32,14 @@ #include #include #include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" #include #include #include -/** \brief initialized Qt-ressources necessary for JKQTMathText - * \ingroup jkqtmathtext - */ -JKQTMATHTEXT_LIB_EXPORT void initJKQTMathTextResources(); - - -/*! \brief represents a font specifier for JKQTMathText. The font consists of two parts: the actual font and the font used for math output (which may be empty) - \ingroup jkqtmathtext - - \section JKQTMathTextFontSpecifier_specialNames Special FOnt Names - This object also implements replacing special font names with actual fonts. Supported special font names are: - - \c default / \c app / \c application - the applications default font - - \c times / \c serif - a general serif font - - \c sans-serif - a general sans-serif font - - \c typewriter - a general typewrter/monospaced font - - \c cursive - - \c decorative - - \c fantasy - - \c monospace - - \c system - . - - If copiled with Qt>5.3 you can also use these: - - \c fixed - - \c smallest_readable - - \c title - - \c general - . -*/ -struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFontSpecifier { - JKQTMathTextFontSpecifier(); - JKQTMathTextFontSpecifier(const QString& fontName, const QString& mathFontName); - /** \brief construct a JKQTMathTextFontSpecifier, by parsing a \a fontSpec string with the form \c "FONT_NAME[+MATH_FONT_NAME]". */ - static JKQTMathTextFontSpecifier fromFontSpec(const QString& fontSpec); - - /** \brief initialises the object with values from parsing a \a fontSpec string with the form \c "FONT_NAME[+MATH_FONT_NAME]". */ - void setFontSpec(const QString& fontSpec); - - /** \brief returns the object's constents as a fontSpec string with the form \c "FONT_NAME[+MATH_FONT_NAME]". */ - QString getFontSpec() const; - /** \copydoc m_fontName */ - QString fontName() const; - /** \copydoc m_mathFontName */ - QString mathFontName() const; - - /** \copydoc m_fontName */ - void setFontName(const QString& name); - /** \copydoc m_mathFontName */ - void setmathFontName(const QString& name); - /** \brief finds actual fonts for some predefined special font names, as listed in \ref JKQTMathTextFontSpecifier_specialNames */ - static QString transformFontName(const QString& fontName); - /** \brief same as transformFontName(), but also finds the actual name for XITS, STIX, ASANA,... */ - static QString transformFontNameAndDecodeSpecialFonts(const QString& fontName); - /** \brief leiefert \c true, wenn ein fontName() verfügbar ist */ - bool hasFontName() const; - /** \brief leiefert \c true, wenn ein mathFontName() verfügbar ist */ - bool hasMathFontName() const; - - /** \brief initialize with the font-families from the XITS package for text and math */ - static JKQTMathTextFontSpecifier getXITSFamilies(); - - /** \brief initialize with the font-families from the XITS package for text and math */ - static JKQTMathTextFontSpecifier getASANAFamilies(); - - /** \brief initialize with the font-families from the STIX package for text and math */ - static JKQTMathTextFontSpecifier getSTIXFamilies(); -private: - /** \brief specifies the main font name */ - QString m_fontName; - /** \brief specifies the math font to use in addition to fontName */ - QString m_mathFontName; - - -}; - +class JKQTMathTextNode; // forward /*! \brief this class parses a LaTeX string and can then draw the contained text/equation onto a QPainter \ingroup jkqtmathtext @@ -329,35 +251,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { /** \brief convert LaTeX to HTML. returns \c ok=true on success and \c ok=false else. */ QString toHtml(bool* ok=nullptr, double fontPointSize=10); - /*! \brief used to specify the font encoding used for drawing - */ - enum MTfontEncoding { - MTFEwinSymbol, /*!< \brief This assumes that symbols shall be taken from a MS Windows style Symbol font */ - MTFEunicode, /*!< \brief This assumes that symbols shall be taken from a Unicode font (e.g. the STIX fonts from http://www.stixfonts.org/)*/ - MTFEunicodeLimited, /*!< \brief This assumes that the fonts used are Unicode, but only offer a limited set of symbols. Especially math symbols are missing from this encoding */ - MTFEStandard, /*!< \brief the encoding of a standard TTF font (i.e. we can only expect letters,number and not many special characters) */ - }; - - /** \brief convert MTfontEncoding to a string */ - static QString encoding2String(MTfontEncoding e); - - - /** \brief the available logical fonts (default is MTEroman) */ - enum MTenvironmentFont { - MTEroman, /*!< \brief roman font, e.g. \\rm{} */ - MTEsans, /*!< \brief sans-serif font, e.g. \\sf{} */ - MTEmathRoman, /*!< \brief math-mode roman font, e.g. \\mathrm{} */ - MTEmathSans, /*!< \brief math-mode sans-serif font, e.g. \\mathsf{} */ - MTEtypewriter, /*!< \brief typewriter font, e.g. \\tt{},\\mathtt{} */ - MTEscript, /*!< \brief script font, e.g. \\script{},\\mathscript{} */ - MTEblackboard, /*!< \brief blackboard font, e.g. \\mathbb{} */ - MTEcaligraphic, /*!< \brief caligraphic font, e.g. \\mathcal{} */ - MTEfraktur, /*!< \brief fraktur font, e.g. \\mathfrak{} */ - - MTenvironmentFontCount /*!< \brief internal enum value that allows to iterate over MTenvironmentFont \internal */ - }; - - /** \copydoc fontColor */ void setFontColor(const QColor & __value); /** \copydoc fontColor */ @@ -386,10 +279,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { * \param useFont replacement font for nonUseFont * \param useFontEncoding encoding of the replacement font */ - void addReplacementFont(const QString& nonUseFont, const QString& useFont, MTfontEncoding useFontEncoding); + void addReplacementFont(const QString& nonUseFont, const QString& useFont, JKQTMathTextFontEncoding useFontEncoding); /** \brief retrieves a replacement for the given font name \a nonUseFont, including its encoding. Returns the given default values \a defaultFont and/or \a defaultFontEncoding if one of the two is not found */ - QPair getReplacementFont(const QString &nonUseFont, const QString &defaultFont, MTfontEncoding defaultFontEncoding) const; + QPair getReplacementFont(const QString &nonUseFont, const QString &defaultFont, JKQTMathTextFontEncoding defaultFontEncoding) const; + /** \brief font subclasses, used by getFontData() */ enum class FontSubclass { Text, Default=Text, @@ -398,43 +292,43 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { }; /** \brief retrieve the font and encoding to be used for \a font, which might optionally be typeset inside a math environment, specified by in_math_environment, possibly for the given font subclass \a subclass */ - QPair getFontData(MTenvironmentFont font, bool in_math_environment=false, FontSubclass subclass=FontSubclass::Default) const; + QPair getFontData(JKQTMathTextEnvironmentFont font, bool in_math_environment=false, FontSubclass subclass=FontSubclass::Default) const; /*! \brief calls setFontRoman(), or calls useXITS() if \a __value \c =="XITS". calls useSTIX() if \a __value \c =="STIX", ... \see setFontRoman(), useXITS(), useSTIX() for more information */ - void setFontRomanOrSpecial(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontRomanOrSpecial(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /*! \brief calls setFontRoman(), or calls useXITS() if \a __value \c =="XITS". calls useSTIX() if \a __value \c =="STIX", ... \see setFontRoman(), useXITS(), useSTIX() for more information */ - void setFontRomanOrSpecial(const JKQTMathTextFontSpecifier & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontRomanOrSpecial(const JKQTMathTextFontSpecifier & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEroman */ - void setFontRoman(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontRoman(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEroman */ QString getFontRoman() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEsans */ - void setFontSans(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontSans(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEsans */ QString getFontSans() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEtypewriter */ - void setFontTypewriter(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontTypewriter(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEtypewriter */ QString getFontTypewriter() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEscript */ - void setFontScript(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontScript(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEscript */ QString getFontScript() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEfraktur */ - void setFontFraktur(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontFraktur(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEfraktur */ QString getFontFraktur() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEcaligraphic */ - void setFontCaligraphic(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontCaligraphic(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEcaligraphic */ QString getFontCaligraphic() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEblackboard */ - void setFontBlackboard(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontBlackboard(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief blackboard font is simulated by using roman with outlines only */ void setFontBlackboardSimulated(bool doSimulate); /** \brief is blackboard font simulated by using roman with outlines only */ @@ -442,50 +336,50 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { /** \brief retrieves the font to be used for text in the logical font MTEblackboard */ QString getFontBlackboard() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for greek letters in the logical font \a font */ - void setSymbolfontGreek(MTenvironmentFont font, const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setSymbolfontGreek(JKQTMathTextEnvironmentFont font, const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief set the font \a fontName and it's encoding \a encoding to be used for integrals in all logical fonts */ - void setSymbolfontGreek(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setSymbolfontGreek(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for greek letters in the logical font \a font */ - QString getSymbolfontGreek(MTenvironmentFont font) const; + QString getSymbolfontGreek(JKQTMathTextEnvironmentFont font) const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for symbols in the logical font \a font */ - void setSymbolfontSymbol(MTenvironmentFont font, const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setSymbolfontSymbol(JKQTMathTextEnvironmentFont font, const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief set the font \a fontName and it's encoding \a encoding to be used for integrals in all logical fonts */ - void setSymbolfontSymbol(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setSymbolfontSymbol(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for symbols in the logical font \a font */ - QString getSymbolfontSymbol(MTenvironmentFont font) const; + QString getSymbolfontSymbol(JKQTMathTextEnvironmentFont font) const; /** \brief retrieves the encoding used for the symbol font to be used for symbols in the logical font \a font */ - MTfontEncoding getSymbolfontEncodingSymbol(MTenvironmentFont font) const; + JKQTMathTextFontEncoding getSymbolfontEncodingSymbol(JKQTMathTextEnvironmentFont font) const; /** \brief retrieves the encoding used for the greek letter font to be used for symbols in the logical font \a font */ - MTfontEncoding getSymbolfontEncodingGreek(MTenvironmentFont font) const; + JKQTMathTextFontEncoding getSymbolfontEncodingGreek(JKQTMathTextEnvironmentFont font) const; /** \brief retrieves the encoding used for the script font */ - MTfontEncoding getFontEncodingScript() const; + JKQTMathTextFontEncoding getFontEncodingScript() const; /** \brief retrieves the encoding used for the Fraktur font */ - MTfontEncoding getFontEncodingFraktur() const; + JKQTMathTextFontEncoding getFontEncodingFraktur() const; /** \brief retrieves the encoding used for the typewriter font */ - MTfontEncoding getFontEncodingTypewriter() const; + JKQTMathTextFontEncoding getFontEncodingTypewriter() const; /** \brief retrieves the encoding used for the sans-serif font */ - MTfontEncoding getFontEncodingSans() const; + JKQTMathTextFontEncoding getFontEncodingSans() const; /** \brief retrieves the encoding used for the roman font */ - MTfontEncoding getFontEncodingRoman() const; + JKQTMathTextFontEncoding getFontEncodingRoman() const; /** \brief retrieves the encoding used for the blackboard font */ - MTfontEncoding getFontEncodingBlackboard() const; + JKQTMathTextFontEncoding getFontEncodingBlackboard() const; /** \brief retrieves the encoding used for the caligraphic font */ - JKQTMathText::MTfontEncoding getFontEncodingCaligraphic() const; + JKQTMathTextFontEncoding getFontEncodingCaligraphic() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEmathRoman */ - void setFontMathRoman(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontMathRoman(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEroman */ QString getFontMathRoman() const; /** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEmathSans */ - void setFontMathSans(const QString & fontName, MTfontEncoding encoding=MTfontEncoding::MTFEStandard); + void setFontMathSans(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); /** \brief retrieves the font to be used for text in the logical font MTEsans */ QString getFontMathSans() const; /** \brief retrieves the encoding used for the math-mode sans-serif font */ - MTfontEncoding getFontEncodingMathSans() const; + JKQTMathTextFontEncoding getFontEncodingMathSans() const; /** \brief retrieves the encoding used for the math-mode roman font */ - MTfontEncoding getFontEncodingMathRoman() const; + JKQTMathTextFontEncoding getFontEncodingMathRoman() const; /** \brief configures the class to use the STIX fonts in mathmode * @@ -528,7 +422,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { * setAnyUnicode("Comic Sans MS", "Comic Sans MS"):
    \image html jkqtmathparser_comicsans.png

    * */ - void useAnyUnicode(QString timesFont=QString(""), const QString& sansFont=QString(""), MTfontEncoding encodingTimes=MTfontEncoding::MTFEunicode, MTfontEncoding encodingSans=MTfontEncoding::MTFEunicode); + void useAnyUnicode(QString timesFont=QString(""), const QString& sansFont=QString(""), JKQTMathTextFontEncoding encodingTimes=JKQTMathTextFontEncoding::MTFEunicode, JKQTMathTextFontEncoding encodingSans=JKQTMathTextFontEncoding::MTFEunicode); @@ -601,567 +495,19 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { void setUseUnparsed(bool __value); /** \copydoc useUnparsed */ bool isUsingUnparsed() const; - /** \copydoc error_list */ + /** \copydoc error_list */ QStringList getErrorList() const; - - protected: - - /** \brief describes the current drawing environment (base fontname ...) */ - struct MTenvironment { - MTenvironment(); - /** \brief current font color */ - QColor color; - /** \brief current font */ - MTenvironmentFont font; - /** \brief current font size [pt] */ - double fontSize; - /** \brief is the text currently bold? */ - bool bold; - /** \brief is the text currently italic? */ - bool italic; - /** \brief is the text currently in small caps? */ - bool smallCaps; - /** \brief is the text currently underlined? */ - bool underlined; - /** \brief is the text currently overlined? */ - bool overline; - /** \brief is the text currently stroke through? */ - bool strike; - /** \brief is the text currently are we inside a math environment? */ - bool insideMath; + /** \copydoc error_list */ + void addToErrorList(const QString& error); - /** \brief build a QFont object from the settings in this object */ - QFont getFont(JKQTMathText* parent) const; - /** \brief generate a HTML prefix that formats the text after it according to the settings in this object - * - * \param defaultEv environment before applying the current object (to detect changes) - * \see toHtmlAfter() - */ - QString toHtmlStart(MTenvironment defaultEv) const; - /** \brief generate a HTML postfix that formats the text in front of it according to the settings in this object - * - * \param defaultEv environment before applying the current object (to detect changes) - * \see toHtmlAfter() - */ - QString toHtmlAfter(MTenvironment defaultEv) const; - }; - - /** \brief beschreibt die Größe eines Knotens */ - struct JKQTMATHTEXT_LIB_EXPORT MTnodeSize { - MTnodeSize(); - double width; - double baselineHeight; - double overallHeight; - double strikeoutPos; - }; - - - public: - /** \brief subclass representing one node in the syntax tree - * \ingroup jkqtmathtext_items - * - * \image html jkqtmathtext_node_geo.png - */ - class JKQTMATHTEXT_LIB_EXPORT MTnode { - public: - explicit MTnode(JKQTMathText* parent); - MTnode(const MTnode&)=delete; - MTnode& operator=(const MTnode&)=delete; - virtual ~MTnode(); - /** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal() - * - * \param painter painter to use for determining the size - * \param currentEv current environment object - * \param[out] width width of the block/node - * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline - * \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight - * \param[out] strikeoutPos position of the strikeout-line - * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) - * - */ - void getSize(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr); - /** \brief calculates the x-size-difference between the given (probably) italic (width externally calculated: \A width_potentiallyitalic, \a ev_potentiallyitalic) and the non-italic version of \a child */ - double getNonItalicXCorretion(QPainter &painter, double width_potentiallyitalic, const MTenvironment &ev_potentiallyitalic, JKQTMathText::MTnode* child) const; - /** \brief draw the contents at the designated position - * - * \param painter QPainter to use - * \param x x-position, where the drawing starts [Pixel] - * \param y Y-position of the baseline, where the drawing starts [Pixel] - * \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings - * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) - * \return the x position which to use for the next part of the text - */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr)=0; - /** \brief convert node to HTML and returns \c true on success - * \param[out] html new HTML code is APPENDED to this string - * \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings - * \param defaultEv JKQTMathText::MTenvironment object describing the default drawing environment/settings when starting to interpret a node tree - * \return \c true on success - */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); - - /** \brief returns the drawing of colored boxes (for DEBUGGING) around the actual output of the node is enabled */ - bool getDrawBoxes() const; - /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ - virtual void setDrawBoxes(bool draw); - /** \brief return the name of this class as a string */ - virtual QString getTypeName() const; - protected: - /** \brief determine the size of the node, overwrite this function in derived classes - * - * \param painter painter to use for determining the size - * \param currentEv current environment object - * \param[out] width width of the block/node - * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline - * \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight - * \param[out] strikeoutPos position of the strikeout-line - * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) - * - */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr)=0; - - /** \brief parent JKQTMathText object (required for several drawing operations */ - JKQTMathText* parent; - /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ - bool drawBoxes; - /** \brief draws colored boxes (for DEBUGGING) around the actual output of the node - * - * \param painter QPainter to use - * \param x x-position, where the drawing starts [Pixel] - * \param y Y-position of the baseline, where the drawing starts [Pixel] - * \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings - */ - void doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv); - }; - - /** \brief subclass representing one text node in the syntax tree - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTtextNode: public MTnode { - public: - explicit MTtextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); - virtual ~MTtextNode() override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc text */ - QString getText() const; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override ; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - /** \brief text-contents of the node */ - QString text; - /** \brief transforms the text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */ - virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false); - }; - - /** \brief subclass representing one text node in the syntax tree - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTplainTextNode: public MTtextNode { - public: - explicit MTplainTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - protected: - /** \copydoc MTtextNode::textTransform() */ - virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false) override; - }; - /** \brief subclass representing one whitepsace node in the syntax tree - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTwhitespaceNode: public MTtextNode { - public: - explicit MTwhitespaceNode(JKQTMathText* parent); - virtual ~MTwhitespaceNode() override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - }; - - /** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTsymbolNode: public MTnode { - public: - explicit MTsymbolNode(JKQTMathText* parent, const QString& name, bool addWhitespace); - virtual ~MTsymbolNode() override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc symbolName */ - QString getSymbolName() const; - /** \brief get font name of the symbol */ - QString getSymbolfontName() const; - /** \copydoc addWhitespace */ - bool getAddWhitespace() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - - /** \brief this string will be sent to the drawText method with properly set fonts */ - QString symbolName; - /** \brief add a whitespace to the symbol? */ - bool addWhitespace; - struct SymbolProps { - /** \brief the symbol name supplied to the constructor */ - QString symbol; - /** \brief font to use for output */ - QString font; - /** \brief magnification factor for the font size */ - double fontFactor; - /** \brief 0: leave italic setting as is, >0: set italic, <0 set italic to false */ - char italic; - /** \brief 0: leave bold setting as is, >0: set bold, <0 set bold to false */ - char bold; - /** \brief this corrects the y position of a symbol: draws at y <- y+ height*yfactor) */ - double yfactor; - /** \brief indicates whether to draw a bar (like for \c \\hbar ) */ - bool drawBar; - bool heightIsAscent; - bool exactAscent; - bool extendWidthInMathmode; - }; - /** \brief retrieve the properties to render the given symbol \a symName in the current environment \a currentEv */ - SymbolProps getSymbolProp(const QString& symName, const MTenvironment& currentEv) const; - /** \brief fill \a props for the symbol named \a n in the given environment \a currentEv and with the given \a mathFontFactor , returns \c true if the symbol can be drawn using Unicode font (or WinSymbol as Fallback)*/ - bool getSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps &props, const QString &n, const MTenvironment ¤tEv, double mathFontFactor) const; - /** \brief fill \a props for the greek letter symbol named \a n in the given environment \a currentEv and with the given \a mathFontFactor , returns \c true if the symbol can be drawn using Unicode font (or WinSymbol as Fallback) */ - bool getGreekSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps &props, const QString &n, const MTenvironment ¤tEv, double mathFontFactor) const; - /** \brief fill \a props for the symbol named \a n in the given environment \a currentEv and with the given \a mathFontFactor , returns \c true if the symbol can be drawn using WinSymbol font */ - bool getWinSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps &props, const QString &n, const MTenvironment ¤tEv, double mathFontFactor) const; - /** \brief fill \a props for the symbol named \a n , returns \c true if the symbol can be drawn using any font, does not alter the font name!!! */ - bool getStandardTextSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps &props, const QString &n) const; - /** \brief fill \a props for the symbol named \a n , returns \c true if the symbol can be drawn using any unicode font, does not alter the font name!!! */ - bool getUnicodeBaseSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps &props, const QString &n) const; - /** \brief fill \a props for the symbol named \a n , returns \c true if the symbol can be drawn using a full unicode font, does not alter the font name!!! */ - bool getUnicodeFullSymbolProp(JKQTMathText::MTsymbolNode::SymbolProps &props, const QString &n, double mathFontFactor) const; - }; - - /** \brief subclass representing a list of nodes in the syntax tree - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTlistNode: public MTnode { - public: - explicit MTlistNode(JKQTMathText* parent); - virtual ~MTlistNode() override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \brief add a child node */ - void addNode(MTnode* n) { nodes.append(n); } - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - /** \copydoc nodes */ - QList getNodes() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - QList nodes; - QSet subsupOperations; - }; - - /** \brief subclass representing an instruction node with exactly one argument in the syntax tree - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTinstruction1Node: public MTnode { - public: - explicit MTinstruction1Node(JKQTMathText* parent, const QString& name, MTnode* child, const QStringList& parameters=QStringList()); - virtual ~MTinstruction1Node() override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \brief convert node to HTML and returns \c true on success */ - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - /** \brief returns the child node */ - MTnode* getChild() const; - /** \copydoc name */ - QString getName() const; - /** \copydoc parameters */ - QStringList getParameters() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - bool setupMTenvironment(JKQTMathText::MTenvironment &ev); - - MTnode* child; - QString name; - QStringList parameters; - }; - - - - /** \brief subclass representing an subscript node with exactly one argument in the syntax tree - * \ingroup jkqtmathtext_items - * - * \image html jkqtmathtext_subscriptnode_getSizeInternal.png - */ - class JKQTMATHTEXT_LIB_EXPORT MTsubscriptNode: public MTnode { - public: - explicit MTsubscriptNode(JKQTMathText* parent, MTnode* child); - virtual ~MTsubscriptNode() override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; /** \brief returns the child node */ - /** \brief returns the child node */ - MTnode *getChild() const; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - MTnode* child; - }; - - /** \brief subclass representing an superscript node with exactly one argument in the syntax tree - * \ingroup jkqtmathtext_items - * - * \image html jkqtmathtext_subscriptnode_getSizeInternal.png - * - * \note a MTlistNode might modify the positioning slightly for special cases (e.g. \c \\int , \c \\sum ... or after braces) - */ - class JKQTMATHTEXT_LIB_EXPORT MTsuperscriptNode: public MTnode { - public: - explicit MTsuperscriptNode(JKQTMathText* parent, MTnode* child); - virtual ~MTsuperscriptNode() override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \brief returns the child node */ - MTnode* getChild() const; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - MTnode* child; - }; - - /** \brief subclass representing a brace node - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTbraceNode: public MTnode { - public: - MTbraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, MTnode* child, bool showRightBrace=true); - virtual ~MTbraceNode() override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \brief returns the child node */ - inline MTnode* getChild() const { - return this->child; - } - /** \copydoc openbrace */ - inline QString getOpenbrace() const { - return this->openbrace; - } - /** \copydoc closebrace */ - inline QString getClosebrace() const { - return this->closebrace; - } - /** \copydoc showRightBrace */ - inline bool getShowRightBrace() const { - return this->showRightBrace; - } - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - MTnode* child; - QString openbrace; - QString closebrace; - bool showRightBrace; - - void getBraceWidth(QPainter& painter, MTenvironment currentEv, double baselineHeight, double overallHeight, double& bracewidth, double& braceheight); - }; - - - /** \brief subclass representing a sqrt node - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTsqrtNode: public MTnode { - public: - MTsqrtNode(JKQTMathText* parent, MTnode* child, int degree=2); - virtual ~MTsqrtNode() override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override ; - /** \brief returns the child node */ - MTnode *getChild() const; - /** \copydoc degree */ - int getDegree() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - MTnode* child; - int degree; - }; - - enum MTfracMode { - MTFMfrac, /*!< \brief normal fraction \image html mathparser/MTFMfrac.png */ - MTFMdfrac, /*!< \brief normal fraction, without scaling of under/over text \image html mathparser/MTFMdfrac.png */ - MTFMtfrac, /*!< \brief text fraction (smaller than MTFMfrac) \image html mathparser/MTFMtfrac.png */ - MTFMsfrac, /*!< \brief slanted fraction \image html mathparser/MTFMsfrac.png */ - MTFMstfrac, /*!< \brief slanted text fraction \image html mathparser/MTFMstfrac.png */ - MTFMunderbrace, /*!< \brief curly underbrace \image html mathparser/MTFMunderbrace.png */ - MTFMoverbrace, /*!< \brief curly overbrace \image html mathparser/MTFMoverbrace.png */ - MTFMstackrel, /*!< \brief binom/fraction without line \image html mathparser/MTFMstackrel.png */ - MTFMunderset, /*!< \brief underset text \image html mathparser/MTFMunderset.png */ - MTFMoverset /*!< \brief overset text \image html mathparser/MTFMoverset.png */ - }; - - static QString fracModeToString(MTfracMode mode); - - /** \brief subclass representing a \\frac node - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTfracNode: public MTnode { - public: - MTfracNode(JKQTMathText* parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode); - virtual ~MTfracNode() override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - /** \brief returns the 1st child node */ - MTnode* getChild1() const; - /** \brief returns the 2nd child node */ - MTnode* getChild2() const; - /** \copydoc mode */ - MTfracMode getMode() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - MTnode* child1; - MTnode* child2; - MTfracMode mode; - }; - - /** \brief subclass representing a \\begin{matrix} node - * \ingroup jkqtmathtext_items - */ - class JKQTMATHTEXT_LIB_EXPORT MTmatrixNode: public MTnode { - public: - MTmatrixNode(JKQTMathText* parent, QVector > children); - virtual ~MTmatrixNode() override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override; - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \brief returns the child nodes */ - QVector > getChildren() const; - /** \copydoc columns */ - int getColumns() const; - /** \copydoc lines */ - int getLines() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - QVector > children; - int columns; - int lines; - }; - - /** \brief types of decoration available in a MTdecoratedNode */ - enum MTdecoration { - MTDvec, /*!< \brief vector arrow over block \image html mathparser/MTDvec.png */ - MTDhat, /*!< \brief small hat over block \image html mathparser/MTDhat.png */ - MTDwidehat, /*!< \brief full-width hat over block \image html mathparser/MTDwidehat.png */ - MTDcheck, /*!< \brief small v over block \image html mathparser/MTDcheck.png */ - MTDwidecheck, /*!< \brief full-width v over block \image html mathparser/MTDwidecheck.png */ - MTDbreve, /*!< \brief small tilde over block \image html mathparser/MTDbreve.png */ - MTDocirc, /*!< \brief single circle over block \image html mathparser/MTDocirc.png */ - MTDdot, /*!< \brief single dot over block \image html mathparser/MTDvec.png */ - MTDddot, /*!< \brief double dot over block \image html mathparser/MTDddot.png */ - MTDbar, /*!< \brief bar over block \image html mathparser/MTDbar.png */ - MTDarrow, /*!< \brief arrow over block \image html mathparser/MTDarrow.png */ - MTDoverline, /*!< \brief overline over block \image html mathparser/MTDoverline.png */ - MTDdoubleoverline, /*!< \brief double overline over block \image html mathparser/MTDdoubleoverline.png */ - MTDunderline, /*!< \brief underline under block \image html mathparser/MTDunderline.png */ - MTDdoubleunderline, /*!< \brief double underline under block \image html mathparser/MTDdoubleunderline.png */ - MTDtilde, /*!< \brief small tilde over block \image html mathparser/MTDtilde.png */ - MTDwidetilde, /*!< \brief full width tilde over block \image html mathparser/MTDwidetilde.png */ - MTDcancel, /*!< \brief cancel text with sloped line \image html mathparser/MTDcancel.png */ - MTDbcancel, /*!< \brief cancel text with backward sloped line \image html mathparser/MTDbcancel.png */ - MTDxcancel, /*!< \brief cancel text with X \image html mathparser/MTDxcancel.png */ - MTDstrike /*!< \brief strikethrough text \image html mathparser/MTDstrike.png */ - }; - /** \brief convert a MTdecoration into a string */ - static QString decorationToString(MTdecoration mode); - - /** \brief subclass representing a decorated text m (e.g. \c \\vec \c \\hat ...) node - * \ingroup jkqtmathtext_items - * - * \image html mathparser/decoration_sizing.png - * - */ - class JKQTMATHTEXT_LIB_EXPORT MTdecoratedNode: public MTnode { - public: - MTdecoratedNode(JKQTMathText* parent, MTdecoration decoration, MTnode* child); - virtual ~MTdecoratedNode() override; - /** \copydoc MTnode::draw() */ - virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; - /** \copydoc MTnode::toHtml() */ - virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; - /** \copydoc MTnode::setDrawBoxes() */ - virtual void setDrawBoxes(bool draw) override; - /** \copydoc MTnode::getTypeName() */ - virtual QString getTypeName() const override ; - /** \brief returns the child node */ - MTnode* getChild() const; - /** \copydoc decoration */ - MTdecoration getDecoration() const; - protected: - /** \copydoc MTnode::getSizeInternal() */ - virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; - /** \brief child node that is decorated by this node */ - MTnode* child; - /** \brief type of decoration that is added to the child node */ - MTdecoration decoration; - }; protected: /** \brief table with font replacements to use (e.g. if it is known that a certain font is not good for rendering, you can add * an alternative using addReplacementFont(). These are automatically applied, when setting a new font name! */ QMap fontReplacements; /** \brief acompanies fontReplacements and collects the encodings of the replacement fonts, if no entry is present, the default encoding is used, as given to the setter! */ - QMap fontEncodingReplacements; + QMap fontEncodingReplacements; /** \brief font color */ QColor fontColor; @@ -1169,27 +515,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { double fontSize; - /*! \brief summarizes all information available on a font for a specific MTenvironmentFont - \see fontDefinitions */ - struct FontDefinition { - FontDefinition(); - /** \brief name of the font */ - QString fontName; - /** \brief specifies the encoding of the font (default is \c MTFEwinSymbol ) */ - MTfontEncoding fontEncoding; - - /** \brief symbol font used for greek symbols, or empty when \a fontName shall be used */ - QString symbolfontGreek; - /** \brief specifies the encoding of symbolfontGreek */ - MTfontEncoding symbolfontGreekEncoding; - /** \brief symbol font, used for math symbols, or empty when \a fontName shall be used */ - QString symbolfontSymbol; - /** \brief specifies the encoding of symbolfontSymbol */ - MTfontEncoding symbolfontSymbolEncoding; - }; - /** \brief stores information about the different fonts used by LaTeX markup */ - QHash fontDefinitions; + QHash fontDefinitions; /** \brief if enabled, the blackboard-characters are simulated by using font outlines only */ bool blackboardSimulated; @@ -1242,13 +569,13 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { bool showRightBrace; /** \brief the result of parsing the last string supplied to the object via parse() */ - MTnode* parsedNode; + JKQTMathTextNode* parsedNode; /** \brief a tree containing the unparsed text as a single node */ - MTnode* unparsedNode; + JKQTMathTextNode* unparsedNode; /** \brief if true, the unparsedNode is drawn */ bool useUnparsed; - MTnode* getTree() const; + JKQTMathTextNode* getTree() const; /** \brief the token types that may arrise in the string */ enum tokenType { @@ -1267,9 +594,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { /** \brief tokenizer for the LaTeX parser */ tokenType getToken(); /** \brief parse a LaTeX string */ - MTnode* parseLatexString(bool get, const QString& quitOnClosingBrace=QString(""), const QString& quitOnEnvironmentEnd=QString("")); + JKQTMathTextNode* parseLatexString(bool get, const QString& quitOnClosingBrace=QString(""), const QString& quitOnEnvironmentEnd=QString("")); /** \brief parse a LaTeX math environment */ - MTnode* parseMath(bool get); + JKQTMathTextNode* parseMath(bool get); /** \brief used by the tokenizer. type of the current token */ tokenType currentToken; @@ -1285,71 +612,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { public: /** \copydoc parsedNode */ - MTnode *getParsedNode() const; + JKQTMathTextNode *getParsedNode() const; - struct JKQTMATHTEXT_LIB_EXPORT tbrData { - explicit tbrData(const QFont& f, const QString& text, QPaintDevice *pd); - QFontMetricsF fm; - QString text; - QRectF tbr; - QFont f; - int ldpiX, ldpiY, pdpiX, pdpiY; - //QPaintDevice *pd; - - bool operator==(const tbrData& other) const; - }; - struct JKQTMATHTEXT_LIB_EXPORT tbrDataH { - explicit tbrDataH(const QFont& f, const QString& text, QPaintDevice *pd); - QString text; - QFont f; - int ldpiX, ldpiY, pdpiX, pdpiY; - - bool operator==(const tbrDataH& other) const; - }; - static QList tbrs; - static QHash tbrh; - static QRectF getTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd); - /** \brief returns a copy of \a f, but with the italic-property set to \c false */ - static QFont getNonItalic(const QFont& f); -}; - - -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) -inline size_t qHash(const JKQTMathText::tbrDataH& data, size_t /*seed=0*/) { -#else -inline uint qHash(const JKQTMathText::tbrDataH& data) { -#endif - return qHash(data.f.family())+qHash(data.text); -} - - - -/*! \brief A QLabel-derived class that draws an equation with LaTeX markup using JKQTMathText - \ingroup jkqtmathtext - - \see JKQTMathText -*/ -class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextLabel: public QLabel { - Q_OBJECT - public: - explicit JKQTMathTextLabel(QWidget* parent=nullptr); - virtual ~JKQTMathTextLabel(); - - /** \brief returns the internal JKQTMathText instance used for drawing - * - * Use this function to set the font, font size and other properties of the used renderer. - */ - JKQTMathText* getMathText() const; - /** \brief set the equation to draw */ - void setMath(const QString& text, bool doRepaint=true); - protected: - JKQTMathText* m_mathText; - QString lastText; - QPixmap buffer; - bool repaintDo; - void internalPaint(); - - void paintEvent(QPaintEvent * event); }; diff --git a/lib/jkqtmathtext/jkqtmathtext_imexport.h b/lib/jkqtmathtext/jkqtmathtext_imexport.h index 5bd6b318b2..685ed90010 100644 --- a/lib/jkqtmathtext/jkqtmathtext_imexport.h +++ b/lib/jkqtmathtext/jkqtmathtext_imexport.h @@ -3,7 +3,7 @@ /* - Copyright (c) 2008-2020 Jan W. Krieger () + Copyright (c) 2008-2022 Jan W. Krieger () last modification: $LastChangedDate: 2015-04-02 13:55:22 +0200 (Do, 02 Apr 2015) $ (revision $Rev: 3902 $) diff --git a/lib/jkqtmathtext/jkqtmathtextlabel.cpp b/lib/jkqtmathtext/jkqtmathtextlabel.cpp new file mode 100644 index 0000000000..e5626f975e --- /dev/null +++ b/lib/jkqtmathtext/jkqtmathtextlabel.cpp @@ -0,0 +1,114 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/jkqtmathtextlabel.h" +#include +#include + +JKQTMathTextLabel::JKQTMathTextLabel(QWidget *parent): + QLabel(parent) +{ + m_mathText=new JKQTMathText(this); + m_mathText->useXITS(); + m_mathText->setFontSize(font().pointSizeF()*1.3); + lastText=""; + repaintDo=true; + buffer=QPixmap(); +} + +JKQTMathTextLabel::~JKQTMathTextLabel() += default; + +JKQTMathText *JKQTMathTextLabel::getMathText() const +{ + return m_mathText; +} + +void JKQTMathTextLabel::setMath(const QString &text, bool doRepaint) +{ + if (text!=lastText || doRepaint){ + lastText=text; + repaintDo=true; + internalPaint(); + update(); + } +} + + +void JKQTMathTextLabel::internalPaint() +{ + //return; + //qDebug()<<"internalPaint "<parse(lastText)<<"\n "<getErrorList().join("\n")<<"\n\n"; + if (!m_mathText->parse(lastText)) { + //qDebug()<<"JKQTMathTextLabel::internalPaint(): parse '"<parse(lastText)<<"\n "<getErrorList().join("\n")<<"\n\n"; + } + if (buffer.width()<=0 || buffer.height()<=0) { + const qreal dpr = devicePixelRatioF(); + buffer=QPixmap(1000*dpr,100*dpr); + buffer.setDevicePixelRatio(dpr); + } + //qDebug()<<"internalPaint(): buffer "<getSize(p); + p.end(); + } + const qreal dpr = devicePixelRatioF(); + buffer=QPixmap(static_cast(qMax(32.0,size.width()*1.2))*dpr, static_cast(qMax(10.0,size.height()*1.1))*dpr); + buffer.setDevicePixelRatio(dpr); + buffer.fill(Qt::transparent); + { + qDebug()<<"internalPaint(): buffer.size()="<draw(p,alignment(), QRectF(QPointF(0,0), size)); + p.end(); + } + setPixmap(buffer); + //} + //qDebug()<<"internalPaint(): setPixmap"; + QApplication::processEvents(); + //qDebug()<<"internalPaint(): DONE"; +} + +void JKQTMathTextLabel::paintEvent(QPaintEvent *event) +{ + QLabel::paintEvent(event); +} + + diff --git a/lib/jkqtmathtext/jkqtmathtextlabel.h b/lib/jkqtmathtext/jkqtmathtextlabel.h new file mode 100644 index 0000000000..bc8dbfd69c --- /dev/null +++ b/lib/jkqtmathtext/jkqtmathtextlabel.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#ifndef JKQTMATHTEXTLABEL_H +#define JKQTMATHTEXTLABEL_H + +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include +#include + + + +/*! \brief A QLabel-derived class that draws an equation with LaTeX markup using JKQTMathText + \ingroup jkqtmathtext + + \see JKQTMathText +*/ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextLabel: public QLabel { + Q_OBJECT + public: + explicit JKQTMathTextLabel(QWidget* parent=nullptr); + virtual ~JKQTMathTextLabel(); + + /** \brief returns the internal JKQTMathText instance used for drawing + * + * Use this function to set the font, font size and other properties of the used renderer. + */ + JKQTMathText* getMathText() const; + /** \brief set the equation to draw */ + void setMath(const QString& text, bool doRepaint=true); + protected: + JKQTMathText* m_mathText; + QString lastText; + QPixmap buffer; + bool repaintDo; + void internalPaint(); + + void paintEvent(QPaintEvent * event); +}; + + +#endif // JKQTMATHTEXTLABEL_H + diff --git a/lib/jkqtmathtext/jkqtmathtexttools.cpp b/lib/jkqtmathtext/jkqtmathtexttools.cpp new file mode 100644 index 0000000000..68a96479e2 --- /dev/null +++ b/lib/jkqtmathtext/jkqtmathtexttools.cpp @@ -0,0 +1,655 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + +void initJKQTMathTextResources() +{ + static bool initialized=false; + if (!initialized) { +#ifdef JKQTMATHTEXT_COMPILED_WITH_XITS + Q_INIT_RESOURCE(xits); +#endif + initialized=true; + } +} + +JKQTMathTextFontSpecifier::JKQTMathTextFontSpecifier(): + m_fontName(""), + m_mathFontName("") +{ + +} + +JKQTMathTextFontSpecifier::JKQTMathTextFontSpecifier(const QString &_fontName, const QString &_mathFontName): + m_fontName(_fontName), + m_mathFontName(_mathFontName) +{ + +} + +JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::fromFontSpec(const QString &fontSpec) +{ + JKQTMathTextFontSpecifier s; + s.setFontSpec(fontSpec); + return s; +} + +void JKQTMathTextFontSpecifier::setFontSpec(const QString &fontSpec) +{ + QStringList splitspec=fontSpec.split('+'); + if (splitspec.size()==0) { + m_fontName=m_mathFontName=""; + } else if (splitspec.size()==1) { + m_fontName=splitspec[0]; + m_mathFontName=""; + } else if (splitspec.size()==2) { + m_fontName=splitspec[0]; + m_mathFontName=splitspec[1]; + } else if (splitspec.size()>2) { + m_fontName=splitspec.mid(0, splitspec.size()-1).join('+'); + m_mathFontName=splitspec.last(); + } +} + +QString JKQTMathTextFontSpecifier::getFontSpec() const +{ + QString res=m_fontName; + if (m_mathFontName.size()>0) res+="+"+m_mathFontName; + return res; +} + +QString JKQTMathTextFontSpecifier::fontName() const +{ + return transformFontName(m_fontName); +} + +QString JKQTMathTextFontSpecifier::mathFontName() const +{ + return transformFontName(m_mathFontName); +} + +QString JKQTMathTextFontSpecifier::transformFontName(const QString &fontName) +{ + const QString fnt=fontName.trimmed().toLower(); + QFont testFnt; + if (fnt=="serif") { + testFnt.setStyleHint(QFont::StyleHint::Serif); + return testFnt.defaultFamily(); + } + if (fnt=="sans-serif" || fnt=="sansserif" || fnt=="sans" || fnt=="sans serif") { + testFnt.setStyleHint(QFont::StyleHint::SansSerif); + return testFnt.defaultFamily(); + } + if (fnt=="cursive") { + testFnt.setStyleHint(QFont::StyleHint::Cursive); + return testFnt.defaultFamily(); + } + if (fnt=="typewriter") { + testFnt.setStyleHint(QFont::StyleHint::TypeWriter); + return testFnt.defaultFamily(); + } + if (fnt=="monospace") { + testFnt.setStyleHint(QFont::StyleHint::Monospace); + return testFnt.defaultFamily(); + } + if (fnt=="fantasy") { + testFnt.setStyleHint(QFont::StyleHint::Fantasy); + return testFnt.defaultFamily(); + } + if (fnt=="system") { + testFnt.setStyleHint(QFont::StyleHint::System); + return testFnt.defaultFamily(); + } + if (fnt=="decorative") { + testFnt.setStyleHint(QFont::StyleHint::Decorative); + return testFnt.defaultFamily(); + } + if (fnt=="default" || fnt=="app" || fnt=="application") { + return QGuiApplication::font().family(); + } +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + if (fnt=="fixed") { + return QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont).family(); + } + if (fnt=="smallest_readable" || fnt=="smallestreadable" || fnt=="smallest readable" || fnt=="smallest") { + return QFontDatabase::systemFont(QFontDatabase::SystemFont::SmallestReadableFont).family(); + } + if (fnt=="title") { + return QFontDatabase::systemFont(QFontDatabase::SystemFont::TitleFont).family(); + } + if (fnt=="general") { + return QFontDatabase::systemFont(QFontDatabase::SystemFont::GeneralFont).family(); + } +#elif QT_VERSION >= QT_VERSION_CHECK(5,2,0) + QFontDatabase fontDB; + if (fnt=="fixed") { + return fontDB.systemFont(QFontDatabase::SystemFont::FixedFont).family(); + } + if (fnt=="smallest_readable" || fnt=="smallestreadable" || fnt=="smallest readable" || fnt=="smallest") { + return fontDB.systemFont(QFontDatabase::SystemFont::SmallestReadableFont).family(); + } + if (fnt=="title") { + return fontDB.systemFont(QFontDatabase::SystemFont::TitleFont).family(); + } + if (fnt=="general") { + return fontDB.systemFont(QFontDatabase::SystemFont::GeneralFont).family(); + } +#endif + return fontName; +} + +QString JKQTMathTextFontSpecifier::transformFontNameAndDecodeSpecialFonts(const QString &fontName) +{ + const QString fnt=fontName.toLower().trimmed(); + if (fnt=="xits") { + return getXITSFamilies().fontName(); + } else if (fnt=="asana") { + return getASANAFamilies().fontName(); + } else if (fnt=="stix") { + return getSTIXFamilies().fontName(); + } + return transformFontName(fontName); +} + +bool JKQTMathTextFontSpecifier::hasFontName() const +{ + return !m_fontName.isEmpty(); +} + +bool JKQTMathTextFontSpecifier::hasMathFontName() const +{ + return !m_mathFontName.isEmpty(); +} + +JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getXITSFamilies() +{ +#if (QT_VERSION0 && fontSpec.m_fontName.size()>0) { + break; + } + } + if (fontSpec.m_mathFontName.isEmpty() && !fontSpec.m_fontName.isEmpty()) { + fontSpec.m_mathFontName=fontSpec.m_fontName; + } else if (!fontSpec.m_mathFontName.isEmpty() && fontSpec.m_fontName.isEmpty()) { + fontSpec.m_fontName=fontSpec.m_mathFontName; + } + } + + return fontSpec; +} + +JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getASANAFamilies() +{ +#if (QT_VERSION0 && fontSpec.m_fontName.size()>0) { + break; + } + } + if (fontSpec.m_mathFontName.isEmpty() && !fontSpec.m_fontName.isEmpty()) { + fontSpec.m_mathFontName=fontSpec.m_fontName; + } else if (!fontSpec.m_mathFontName.isEmpty() && fontSpec.m_fontName.isEmpty()) { + fontSpec.m_fontName=fontSpec.m_mathFontName; + } + } + + + return fontSpec; +} + +JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getSTIXFamilies() +{ + static QStringList mathNames{"STIX Two Math", "STIX Math", "STIX Two Math Standard", "STIX Math Standard"}; + static QStringList textNames{"STIX", "STIXGeneral", "STIX General"}; + + static JKQTMathTextFontSpecifier fontSpec; + if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) { +#if (QT_VERSION0) { + break; + } + } + if (fontSpec.m_mathFontName.size()>0) { + break; + } + } + for (const QString& name:textNames) { + for (int i=0; i0) { + break; + } + } + if (fontSpec.m_fontName.size()>0) { + break; + } + } + if (fontSpec.m_mathFontName.isEmpty() && !fontSpec.m_fontName.isEmpty()) { + fontSpec.m_mathFontName=fontSpec.m_fontName; + } else if (!fontSpec.m_mathFontName.isEmpty() && fontSpec.m_fontName.isEmpty()) { + fontSpec.m_fontName=fontSpec.m_mathFontName; + } + } + return fontSpec; +} + +QString JKQTMathTextFontEncoding2String(JKQTMathTextFontEncoding e) +{ + switch(e) { + case MTFEunicode: return "MTFEunicode"; + case MTFEStandard: return "MTFEStandard"; + case MTFEunicodeLimited: return "MTFEunicodeLimited"; + case MTFEwinSymbol: return "MTFEwinSymbol"; + } + return "???"; +} + +JKQTMathTextEnvironment::JKQTMathTextEnvironment() { + color=QColor("black"); + font=MTEroman; + fontSize=10; + bold=false; + italic=false; + smallCaps=false; + underlined=false; + overline=false; + strike=false; + insideMath=false; +} + +QFont JKQTMathTextEnvironment::getFont(JKQTMathText* parent) const { + QFont f; + switch (font) { + case MTEsans: if (insideMath) { + f.setFamily(parent->getFontMathSans()); + } else { + f.setFamily(parent->getFontSans()); + } + break; + case MTEmathSans: f.setFamily(parent->getFontMathSans()); break; + case MTEtypewriter: f.setFamily(parent->getFontTypewriter()); break; + case MTEscript: f.setFamily(parent->getFontScript()); break; + case MTEcaligraphic: f.setFamily(parent->getFontCaligraphic()); break; + case MTEblackboard: f.setFamily(parent->getFontBlackboard()); break; + case MTEfraktur: f.setFamily(parent->getFontFraktur()); break; + case MTEmathRoman: f.setFamily(parent->getFontMathRoman()); break; + default: + case MTEroman: if (insideMath) { + f.setFamily(parent->getFontMathRoman()); + } else { + f.setFamily(parent->getFontRoman()); + } + break; + } + f.setBold(bold); + f.setItalic(italic); + f.setUnderline(underlined); + f.setOverline(overline); + f.setStrikeOut(strike); + f.setCapitalization(QFont::MixedCase); + if (smallCaps) f.setCapitalization(QFont::SmallCaps); + f.setPointSizeF(fontSize); + f.setStyleStrategy(QFont::NoFontMerging); + return f; +} + +QString JKQTMathTextEnvironment::toHtmlStart(JKQTMathTextEnvironment defaultEv) const { + QString s; + s=s+"font-size: "+QLocale::c().toString(fontSize)+"pt; "; + if (insideMath) { + if (defaultEv.italic) { + if (!italic) s=s+"font-style: italic; "; + if (italic) s=s+"font-style: normal; "; + } else { + if (!italic) s=s+"font-style: italic; "; + } + } else { + if (!defaultEv.italic && italic) s=s+"font-style: italic; "; + } + if (bold && !defaultEv.bold) s=s+"font-weight: bold"; + + QStringList td; + if (underlined && !defaultEv.underlined) td<<"underline"; + if (overline && !defaultEv.overline) td<<"overline"; + if (strike && !defaultEv.strike) td<<"line-through"; + if (td.size()>0) s=s+"text-decoration: "+td.join(", "); + return ""; +} + +QString JKQTMathTextEnvironment::toHtmlAfter(JKQTMathTextEnvironment /*defaultEv*/) const { + return ""; +} + +JKQTMathTextNodeSize::JKQTMathTextNodeSize(): + width(0), + baselineHeight(0), + overallHeight(0), + strikeoutPos() +{ + +} + + +JKQTMathTextFontDefinition::JKQTMathTextFontDefinition(): + fontName("Times New Roman"), fontEncoding(MTFEStandard), + symbolfontGreek("Symbol"), symbolfontGreekEncoding(MTFEwinSymbol), + symbolfontSymbol("Symbol"), symbolfontSymbolEncoding(MTFEwinSymbol) +{ + +} + + + +QString JKQTMathTextFracModeToString(JKQTMathTextFracMode mode) +{ + switch(mode) { + case MTFMfrac: + return "frac"; + case MTFMdfrac: + return "dfrac"; + case MTFMsfrac: + return "sfrac"; + case MTFMstfrac: + return "stfrac"; + case MTFMtfrac: + return "tfrac"; + case MTFMunderbrace: + return "underbrace"; + case MTFMoverbrace: + return "overbrace"; + case MTFMunderset: + return "underset"; + case MTFMoverset: + return "overset"; + case MTFMstackrel: + return "stackrel"; + } + return "unknown"; +} + + +QString JKQTMathTextDecorationToString(JKQTMathTextDecoration mode) +{ + switch(mode) { + case MTDvec: + return "vec"; + case MTDtilde: + return "tilde"; + case MTDbreve: + return "breve"; + case MTDwidetilde: + return "widetilde"; + case MTDhat: + return "hat"; + case MTDwidehat: + return "widehat"; + case MTDcheck: + return "check"; + case MTDwidecheck: + return "widecheck"; + case MTDocirc: + return "ocirc"; + case MTDdot: + return "dot"; + case MTDddot: + return "ddot"; + case MTDbar: + return "bar"; + case MTDarrow: + return "arrow"; + case MTDoverline: + return "overline"; + case MTDdoubleoverline: + return "double overline"; + case MTDunderline: + return "underline"; + case MTDdoubleunderline: + return "double underline"; + case MTDcancel: + return "cancel"; + case MTDbcancel: + return "bcancel"; + case MTDxcancel: + return "xcancel"; + case MTDstrike: + return "strike"; + } + return "unknown"; +} + +QPainterPath JKQTMathTextMakeDArrow(double x, double y, double width, double arrowW, bool left, bool right) { + double x1=x; + double x2=x+width; + double dx=arrowW/4.0; + double y1=y-dx; + double y2=y+dx; + double x3=x2-arrowW/2.0; + double y3u=y-arrowW/2.0; + double y3d=y+arrowW/2.0; + double x3l=x+arrowW/2.0; + + QPainterPath path; + path.moveTo(x1+dx, y1); + path.lineTo(x2-dx, y1); + path.moveTo(x1+dx, y2); + path.lineTo(x2-dx, y2); + if (right) { + path.moveTo(x3, y3u); + path.lineTo(x2, y); + path.lineTo(x3, y3d); + } + if (left) { + path.moveTo(x3l, y3u); + path.lineTo(x1, y); + path.lineTo(x3l, y3d); + } + return path; +} + +QPainterPath JKQTMathTextMakeArrow(double x, double y, double width, double arrowW, bool left, bool right) { + double x1=x; + double x2=x+width; + double x3=x2-arrowW/2.0; + double y3u=y-arrowW/2.0; + double y3d=y+arrowW/2.0; + double x3l=x+arrowW/2.0; + + QPainterPath path; + path.moveTo(x1, y); + path.lineTo(x2, y); + if (right) { + path.moveTo(x3, y3u); + path.lineTo(x2, y); + path.lineTo(x3, y3d); + } + if (left) { + path.moveTo(x3l, y3u); + path.lineTo(x1, y); + path.lineTo(x3l, y3d); + } + return path; +} + +QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double cubicshrink, double cubiccontrolfac) { + double xl1=x-(width)*cubicshrink+bw*cubicshrink; + double xr2=x+(width)*cubicshrink-bw*cubicshrink; + double xl2=x-bw*cubicshrink; + double xr1=x+bw*cubicshrink; + + QPainterPath path; + path.moveTo(xl1-bw*cubicshrink, ybrace-bw*cubicshrink); + path.cubicTo(xl1-bw*cubicshrink, ybrace-bw*cubicshrink+bw*cubiccontrolfac, xl1-bw*cubiccontrolfac, ybrace, xl1, ybrace); + path.lineTo(xl2, ybrace); + path.cubicTo(xl2+bw*cubiccontrolfac, ybrace, (xl2+xr1)/2.0, ybrace+bw*cubicshrink-bw*cubiccontrolfac, (xl2+xr1)/2.0, ybrace+bw*cubicshrink); + path.cubicTo((xl2+xr1)/2.0, ybrace+bw*cubicshrink-bw*cubiccontrolfac, xr1-bw*cubiccontrolfac, ybrace, xr1, ybrace); + path.lineTo(xr2, ybrace); + path.cubicTo(xr2+bw*cubiccontrolfac, ybrace, xr2+bw*cubicshrink, ybrace-bw*cubicshrink+bw*cubiccontrolfac, xr2+bw*cubicshrink, ybrace-bw*cubicshrink); + return path; +} + + +JKQTMathTextTBRData::JKQTMathTextTBRData(const QFont &f, const QString &text, QPaintDevice *pd): + fm(f, pd) +{ + this->text=text; + this->tbr=this->fm.tightBoundingRect(text); + this->f=f; + //this->pd=pd; + if (pd) { + ldpiX=pd->logicalDpiX(); + ldpiY=pd->logicalDpiY(); + pdpiX=pd->physicalDpiX(); + pdpiY=pd->physicalDpiY(); + } else { + ldpiX=0; + ldpiY=0; + pdpiX=0; + pdpiY=0; + } +} + +bool JKQTMathTextTBRData::operator==(const JKQTMathTextTBRData &other) const +{ + return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f; +} + + + +JKQTMathTextTBRDataH::JKQTMathTextTBRDataH(const QFont &f, const QString &text, QPaintDevice *pd) +{ + this->text=text; + this->f=f; + if (pd) { + ldpiX=pd->logicalDpiX(); + ldpiY=pd->logicalDpiY(); + pdpiX=pd->physicalDpiX(); + pdpiY=pd->physicalDpiY(); + } else { + ldpiX=0; + ldpiY=0; + pdpiX=0; + pdpiY=0; + } +} + +bool JKQTMathTextTBRDataH::operator==(const JKQTMathTextTBRDataH &other) const +{ + return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f; + +} + + + +QRectF JKQTMathTextGetTightBoundingRect(const QFont &fm, const QString &text, QPaintDevice *pd) +{ + static QList JKQTMathText_tbrs=QList(); + static QHash JKQTMathText_tbrh=QHash(); + + JKQTMathTextTBRDataH dh(fm, text, pd); + if (pd) { + if (JKQTMathText_tbrh.contains(dh)) return JKQTMathText_tbrh[dh]; + /*for (int i=0; ilogicalDpiX() && tbrs[i].ldpiY==pd->logicalDpiY() && tbrs[i].pdpiX==pd->physicalDpiX() && tbrs[i].pdpiY==pd->physicalDpiY())) { + //qDebug()<<" ### "<) + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + +/* + Name: jkqtmathtext.h + Copyright: (c) 2010-2019 + Author: Jan krieger , http://www.jkrieger.de/ +*/ + + + +#ifndef JKQTMATHTEXTTOOLS_H +#define JKQTMATHTEXTTOOLS_H + +#include +#include +#include +#include +#include +#include +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include +#include +#include +#include + +class JKQTMathText; // forward + + + +/** \brief initialized Qt-ressources necessary for JKQTMathText + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT void initJKQTMathTextResources(); + + +/*! \brief represents a font specifier for JKQTMathText. The font consists of two parts: the actual font and the font used for math output (which may be empty) + \ingroup jkqtmathtext + + \section JKQTMathTextFontSpecifier_specialNames Special FOnt Names + This object also implements replacing special font names with actual fonts. Supported special font names are: + - \c default / \c app / \c application - the applications default font + - \c times / \c serif - a general serif font + - \c sans-serif - a general sans-serif font + - \c typewriter - a general typewrter/monospaced font + - \c cursive + - \c decorative + - \c fantasy + - \c monospace + - \c system + . + + If copiled with Qt>5.3 you can also use these: + - \c fixed + - \c smallest_readable + - \c title + - \c general + . +*/ +struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFontSpecifier { + JKQTMathTextFontSpecifier(); + JKQTMathTextFontSpecifier(const QString& fontName, const QString& mathFontName); + /** \brief construct a JKQTMathTextFontSpecifier, by parsing a \a fontSpec string with the form \c "FONT_NAME[+MATH_FONT_NAME]". */ + static JKQTMathTextFontSpecifier fromFontSpec(const QString& fontSpec); + + /** \brief initialises the object with values from parsing a \a fontSpec string with the form \c "FONT_NAME[+MATH_FONT_NAME]". */ + void setFontSpec(const QString& fontSpec); + + /** \brief returns the object's constents as a fontSpec string with the form \c "FONT_NAME[+MATH_FONT_NAME]". */ + QString getFontSpec() const; + /** \copydoc m_fontName */ + QString fontName() const; + /** \copydoc m_mathFontName */ + QString mathFontName() const; + + /** \copydoc m_fontName */ + void setFontName(const QString& name); + /** \copydoc m_mathFontName */ + void setmathFontName(const QString& name); + /** \brief finds actual fonts for some predefined special font names, as listed in \ref JKQTMathTextFontSpecifier_specialNames */ + static QString transformFontName(const QString& fontName); + /** \brief same as transformFontName(), but also finds the actual name for XITS, STIX, ASANA,... */ + static QString transformFontNameAndDecodeSpecialFonts(const QString& fontName); + /** \brief leiefert \c true, wenn ein fontName() verfügbar ist */ + bool hasFontName() const; + /** \brief leiefert \c true, wenn ein mathFontName() verfügbar ist */ + bool hasMathFontName() const; + + /** \brief initialize with the font-families from the XITS package for text and math */ + static JKQTMathTextFontSpecifier getXITSFamilies(); + + /** \brief initialize with the font-families from the XITS package for text and math */ + static JKQTMathTextFontSpecifier getASANAFamilies(); + + /** \brief initialize with the font-families from the STIX package for text and math */ + static JKQTMathTextFontSpecifier getSTIXFamilies(); +private: + /** \brief specifies the main font name */ + QString m_fontName; + /** \brief specifies the math font to use in addition to fontName */ + QString m_mathFontName; + + +}; + + +/** \brief used to specify the font encoding used for drawing + * \ingroup jkqtmathtext +*/ +enum JKQTMathTextFontEncoding { + MTFEwinSymbol, /*!< \brief This assumes that symbols shall be taken from a MS Windows style Symbol font */ + MTFEunicode, /*!< \brief This assumes that symbols shall be taken from a Unicode font (e.g. the STIX fonts from http://www.stixfonts.org/)*/ + MTFEunicodeLimited, /*!< \brief This assumes that the fonts used are Unicode, but only offer a limited set of symbols. Especially math symbols are missing from this encoding */ + MTFEStandard, /*!< \brief the encoding of a standard TTF font (i.e. we can only expect letters,number and not many special characters) */ +}; + +/** \brief convert MTfontEncoding to a string + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextFontEncoding2String(JKQTMathTextFontEncoding e); + + +/** \brief the available logical fonts (default is MTEroman) + * \ingroup jkqtmathtext + */ +enum JKQTMathTextEnvironmentFont { + MTEroman, /*!< \brief roman font, e.g. \\rm{} */ + MTEsans, /*!< \brief sans-serif font, e.g. \\sf{} */ + MTEmathRoman, /*!< \brief math-mode roman font, e.g. \\mathrm{} */ + MTEmathSans, /*!< \brief math-mode sans-serif font, e.g. \\mathsf{} */ + MTEtypewriter, /*!< \brief typewriter font, e.g. \\tt{},\\mathtt{} */ + MTEscript, /*!< \brief script font, e.g. \\script{},\\mathscript{} */ + MTEblackboard, /*!< \brief blackboard font, e.g. \\mathbb{} */ + MTEcaligraphic, /*!< \brief caligraphic font, e.g. \\mathcal{} */ + MTEfraktur, /*!< \brief fraktur font, e.g. \\mathfrak{} */ + + MTenvironmentFontCount /*!< \brief internal enum value that allows to iterate over MTenvironmentFont \internal */ +}; + + + +/** \brief describes the current drawing environment (base fontname ...) + * \ingroup jkqtmathtext + */ +struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextEnvironment { + JKQTMathTextEnvironment(); + /** \brief current font color */ + QColor color; + /** \brief current font */ + JKQTMathTextEnvironmentFont font; + /** \brief current font size [pt] */ + double fontSize; + /** \brief is the text currently bold? */ + bool bold; + /** \brief is the text currently italic? */ + bool italic; + /** \brief is the text currently in small caps? */ + bool smallCaps; + /** \brief is the text currently underlined? */ + bool underlined; + /** \brief is the text currently overlined? */ + bool overline; + /** \brief is the text currently stroke through? */ + bool strike; + /** \brief is the text currently are we inside a math environment? */ + bool insideMath; + + + /** \brief build a QFont object from the settings in this object */ + QFont getFont(JKQTMathText* parent) const; + /** \brief generate a HTML prefix that formats the text after it according to the settings in this object + * + * \param defaultEv environment before applying the current object (to detect changes) + * \see toHtmlAfter() + */ + QString toHtmlStart(JKQTMathTextEnvironment defaultEv) const; + /** \brief generate a HTML postfix that formats the text in front of it according to the settings in this object + * + * \param defaultEv environment before applying the current object (to detect changes) + * \see toHtmlAfter() + */ + QString toHtmlAfter(JKQTMathTextEnvironment defaultEv) const; +}; + +/** \brief beschreibt die Größe eines Knotens + * \ingroup jkqtmathtext + */ +struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNodeSize { + JKQTMathTextNodeSize(); + double width; + double baselineHeight; + double overallHeight; + double strikeoutPos; +}; + +/** \brief summarizes all information available on a font for a specific MTenvironmentFont + * \ingroup jkqtmathtext + * \see fontDefinitions + */ +struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFontDefinition { + JKQTMathTextFontDefinition(); + /** \brief name of the font */ + QString fontName; + /** \brief specifies the encoding of the font (default is \c MTFEwinSymbol ) */ + JKQTMathTextFontEncoding fontEncoding; + + /** \brief symbol font used for greek symbols, or empty when \a fontName shall be used */ + QString symbolfontGreek; + /** \brief specifies the encoding of symbolfontGreek */ + JKQTMathTextFontEncoding symbolfontGreekEncoding; + /** \brief symbol font, used for math symbols, or empty when \a fontName shall be used */ + QString symbolfontSymbol; + /** \brief specifies the encoding of symbolfontSymbol */ + JKQTMathTextFontEncoding symbolfontSymbolEncoding; +}; + +/** \brief type of ffractions represented by JKQTMathTextFracNode + * \ingroup jkqtmathtext + * \see JKQTMathTextFracNode, JKQTMathTextFracModeToString() + */ +enum JKQTMathTextFracMode { + MTFMfrac, /*!< \brief normal fraction \image html mathparser/MTFMfrac.png */ + MTFMdfrac, /*!< \brief normal fraction, without scaling of under/over text \image html mathparser/MTFMdfrac.png */ + MTFMtfrac, /*!< \brief text fraction (smaller than MTFMfrac) \image html mathparser/MTFMtfrac.png */ + MTFMsfrac, /*!< \brief slanted fraction \image html mathparser/MTFMsfrac.png */ + MTFMstfrac, /*!< \brief slanted text fraction \image html mathparser/MTFMstfrac.png */ + MTFMunderbrace, /*!< \brief curly underbrace \image html mathparser/MTFMunderbrace.png */ + MTFMoverbrace, /*!< \brief curly overbrace \image html mathparser/MTFMoverbrace.png */ + MTFMstackrel, /*!< \brief binom/fraction without line \image html mathparser/MTFMstackrel.png */ + MTFMunderset, /*!< \brief underset text \image html mathparser/MTFMunderset.png */ + MTFMoverset /*!< \brief overset text \image html mathparser/MTFMoverset.png */ +}; + +/** \brief convert a JKQTMathTextFracMode into a QString + * \ingroup jkqtmathtext + * \see JKQTMathTextFracMode + */ +JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextFracModeToString(JKQTMathTextFracMode mode); + + +/** \brief types of decoration available in a JKQTMathTextDecoratedNode + * \ingroup jkqtmathtext + */ +enum JKQTMathTextDecoration { + MTDvec, /*!< \brief vector arrow over block \image html mathparser/MTDvec.png */ + MTDhat, /*!< \brief small hat over block \image html mathparser/MTDhat.png */ + MTDwidehat, /*!< \brief full-width hat over block \image html mathparser/MTDwidehat.png */ + MTDcheck, /*!< \brief small v over block \image html mathparser/MTDcheck.png */ + MTDwidecheck, /*!< \brief full-width v over block \image html mathparser/MTDwidecheck.png */ + MTDbreve, /*!< \brief small tilde over block \image html mathparser/MTDbreve.png */ + MTDocirc, /*!< \brief single circle over block \image html mathparser/MTDocirc.png */ + MTDdot, /*!< \brief single dot over block \image html mathparser/MTDvec.png */ + MTDddot, /*!< \brief double dot over block \image html mathparser/MTDddot.png */ + MTDbar, /*!< \brief bar over block \image html mathparser/MTDbar.png */ + MTDarrow, /*!< \brief arrow over block \image html mathparser/MTDarrow.png */ + MTDoverline, /*!< \brief overline over block \image html mathparser/MTDoverline.png */ + MTDdoubleoverline, /*!< \brief double overline over block \image html mathparser/MTDdoubleoverline.png */ + MTDunderline, /*!< \brief underline under block \image html mathparser/MTDunderline.png */ + MTDdoubleunderline, /*!< \brief double underline under block \image html mathparser/MTDdoubleunderline.png */ + MTDtilde, /*!< \brief small tilde over block \image html mathparser/MTDtilde.png */ + MTDwidetilde, /*!< \brief full width tilde over block \image html mathparser/MTDwidetilde.png */ + MTDcancel, /*!< \brief cancel text with sloped line \image html mathparser/MTDcancel.png */ + MTDbcancel, /*!< \brief cancel text with backward sloped line \image html mathparser/MTDbcancel.png */ + MTDxcancel, /*!< \brief cancel text with X \image html mathparser/MTDxcancel.png */ + MTDstrike /*!< \brief strikethrough text \image html mathparser/MTDstrike.png */ +}; +/** \brief convert a JKQTMathTextDecoration into a string + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextDecorationToString(JKQTMathTextDecoration mode); + + +/** \brief create a QPainterPath for drawing horizontal braces + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double cubicshrink=0.5, double cubiccontrolfac=0.3); + + +/** \brief create a QPainterPath for drawing horizontal arrows + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true); + + +/** \brief create a QPainterPath for drawing horizontal double arrows + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeDArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true); + + +struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRData { + explicit JKQTMathTextTBRData(const QFont& f, const QString& text, QPaintDevice *pd); + QFontMetricsF fm; + QString text; + QRectF tbr; + QFont f; + int ldpiX, ldpiY, pdpiX, pdpiY; + //QPaintDevice *pd; + + bool operator==(const JKQTMathTextTBRData& other) const; +}; +struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRDataH { + explicit JKQTMathTextTBRDataH(const QFont& f, const QString& text, QPaintDevice *pd); + QString text; + QFont f; + int ldpiX, ldpiY, pdpiX, pdpiY; + + bool operator==(const JKQTMathTextTBRDataH& other) const; +}; + + +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +inline size_t qHash(const JKQTMathTextTBRDataH& data, size_t /*seed=0*/) { +#else +inline uint qHash(const JKQTMathTextTBRDataH& data) { +#endif + return qHash(data.f.family())+qHash(data.text); +} + + +/** \brief calculates the tight bounding rectangle around \a text, uses internal hashing to not redo a calculation that has already been performed + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QRectF JKQTMathTextGetTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd); +/** \brief returns a copy of \a f, but with the italic-property set to \c false + * \ingroup jkqtmathtext + */ +JKQTMATHTEXT_LIB_EXPORT QFont JKQTMathTextGetNonItalic(const QFont& f); + + +#endif // JKQTMATHTEXTTOOLS_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp new file mode 100644 index 0000000000..a52bcab1b0 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp @@ -0,0 +1,297 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include +#include + + + + +JKQTMathTextBraceNode::JKQTMathTextBraceNode(JKQTMathText* _parent, const QString& openbrace, const QString& closebrace, JKQTMathTextNode* child, bool showRightBrace): + JKQTMathTextNode(_parent) +{ + this->child=child; + this->openbrace=openbrace; + this->closebrace=closebrace; + this->showRightBrace=showRightBrace; +} + +JKQTMathTextBraceNode::~JKQTMathTextBraceNode() { + if (child!=nullptr) delete child; +} + +void JKQTMathTextBraceNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + + JKQTMathTextEnvironment ev=currentEv; + child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); + + double bracewidth=0, braceheight=0; + getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight); + + bracewidth=bracewidth/parent->getBraceShrinkFactor(); + + baselineHeight=/*qMin(baselineHeight, braceheight)*/ baselineHeight*parent->getBraceFactor(); + overallHeight=qMax(overallHeight, braceheight)*parent->getBraceFactor(); //fm.height(); + + width=width+bracewidth*2.0; + + +} + +double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + //std::cout<<"drawing brace-node: '"<getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); + + double bracewidth=0, braceheight=0; + getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight); + + double cWidth=0; + double cBaselineHeight=0; + double cOverallHeight=0, cstrikeoutPos=0; + + getSize(painter, currentEv, cWidth, cBaselineHeight, cOverallHeight, cstrikeoutPos); + + double lw=qMax(0.25,ceil(currentEv.fontSize/16.0));//fm.lineWidth(); + + double xnew=x+lw; + + QPen pold=painter.pen(); + QPen p=pold; + p.setWidthF(lw); + p.setColor(currentEv.color); + painter.setPen(p); + double brace_fraction=0.85; + if (openbrace=="(") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+brace_fraction*bracewidth, y1); + path.cubicTo(xnew, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+brace_fraction*bracewidth, y2); + painter.drawPath(path); + } else if (openbrace=="[") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+brace_fraction*bracewidth, y1); + path.lineTo(xnew+lw/2.0, y1); + path.lineTo(xnew+lw/2.0, y2); + path.lineTo(xnew+brace_fraction*bracewidth, y2); + painter.drawPath(path); + } else if (openbrace=="{") { + QPainterPath path=JKQTMathTextMakeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(xnew+bracewidth*(1.0-brace_fraction), y-cBaselineHeight+cOverallHeight/2.0); + painter.rotate(90); + painter.drawPath(path); + + } else if (openbrace=="_") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+brace_fraction*bracewidth, y1); + path.lineTo(xnew, y1); + path.lineTo(xnew, y2); + painter.drawPath(path); + } else if (openbrace=="~") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew, y1); + path.lineTo(xnew, y2); + path.lineTo(xnew+brace_fraction*bracewidth, y2); + painter.drawPath(path); + } else if (openbrace=="|") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); + if (l.length()>0) painter.drawLine(l); + painter.drawPath(path); + } else if (openbrace=="#" || openbrace=="||") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); + if (l.length()>0) painter.drawLine(l); + l=QLineF(xnew+brace_fraction*bracewidth-1.5*lw, y1, xnew+brace_fraction*bracewidth-1.5*lw, y2); + if (l.length()>0) painter.drawLine(l); + } else if (openbrace=="<") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+brace_fraction*bracewidth, y1); + path.lineTo(xnew, (y2+y1)/2.0); + path.lineTo(xnew+brace_fraction*bracewidth, y2); + painter.drawPath(path); + } + + painter.setPen(pold); + + xnew= child->draw(painter, xnew+bracewidth/parent->getBraceShrinkFactor()-lw, y, currentEv)+lw; + + if (showRightBrace) { + painter.setPen(p); + if (closebrace==")") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); + path.cubicTo(xnew+bracewidth, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew+bracewidth, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+(1.0-brace_fraction)*bracewidth, y2); + painter.drawPath(path); + } else if (closebrace=="]") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); + path.lineTo(xnew+bracewidth-lw/2.0, y1); + path.lineTo(xnew+bracewidth-lw/2.0, y2); + path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); + painter.drawPath(path); + } else if (closebrace=="}") { + QPainterPath path=JKQTMathTextMakeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(xnew+bracewidth*brace_fraction, y-cBaselineHeight+cOverallHeight/2.0); + painter.rotate(270); + painter.drawPath(path); + + } else if (closebrace=="_") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); + path.lineTo(xnew+bracewidth, y1); + path.lineTo(xnew+bracewidth, y2); + painter.drawPath(path); + } else if (closebrace=="~") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+bracewidth, y1); + path.lineTo(xnew+bracewidth, y2); + path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); + painter.drawPath(path); + } else if (closebrace=="|") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); + if (l.length()>0) painter.drawLine(l); + painter.drawPath(path); + } else if (closebrace=="#" || closebrace=="||") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); + if (l.length()>0) painter.drawLine(l); + l=QLineF(xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y1, xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y2); + if (l.length()>0) painter.drawLine(l); + } else if (closebrace==">") { + QPainterPath path; + double y1=y+(cOverallHeight-cBaselineHeight); + double y2=y-cBaselineHeight; + path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); + path.lineTo(xnew+bracewidth, (y2+y1)/2.0); + path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); + painter.drawPath(path); + } + painter.setPen(pold); + } + + //qDebug()<<" ==> "<getBraceShrinkFactor()-lw; +} + +bool JKQTMathTextBraceNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + QString ob=openbrace; + QString cb=closebrace; + if (ob=="<") ob="⟨"; + else if (ob=="_") ob="⌊"; + else if (ob=="~") ob="⌈"; + else if (ob=="||" || ob=="#") ob="||"; + if (cb=="<") cb="⟩"; + else if (cb=="_") cb="⌋"; + else if (cb=="~") cb="⌉"; + else if (cb=="||" || cb=="#") cb="||"; + + + html=html+ob; + + bool ok=child->toHtml(html, currentEv, defaultEv); + + html=html+cb; + + return ok; +} + +void JKQTMathTextBraceNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + child->setDrawBoxes(draw); + +} + +QString JKQTMathTextBraceNode::getTypeName() const +{ + return QLatin1String("MTbraceNode(")+openbrace+" "+closebrace+")"; +} + +void JKQTMathTextBraceNode::getBraceWidth(QPainter &/*painter*/, JKQTMathTextEnvironment ev, double /*baselineHeight*/, double overallHeight, double &bracewidth, double &braceheight) +{ + /*QFont evf=ev.getFont(parent); + if (ev.insideMath) evf.setItalic(false); + ev.italic=false; + while (ev.fontSize<10*parent->getFontSize()) { + const QFontMetricsF fme(evf, painter.device()); + if (fme.ascent()>overallHeight) break; + ev.fontSize+=0.5; + evf.setPointSizeF(ev.fontSize); + } + ev.fontSize=ev.fontSize*parent->getBraceFactor(); + evf.setPointSizeF(ev.fontSize); + QFontMetricsF fm(evf, painter.device()); + QString bc="_X"; + bracewidth=fm.width("I")*parent->getBraceShrinkFactor(); + braceheight=parent->getTBR(evf, bc, painter.device()).height();*/ + double lw=qMax(0.25,ceil(ev.fontSize/12.0)); + braceheight=overallHeight*parent->getBraceFactor(); + bracewidth=0.6*pow(braceheight, 0.6); + if (openbrace=="{" || closebrace=="}") bracewidth=qMax(bracewidth, lw*3.5); + +} + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h new file mode 100644 index 0000000000..ea1c60d609 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h @@ -0,0 +1,86 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTBRACENODE_H +#define JKQTMATHTEXTBRACENODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing a brace node + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextNode { + public: + JKQTMathTextBraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, JKQTMathTextNode* child, bool showRightBrace=true); + virtual ~JKQTMathTextBraceNode() override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \brief returns the child node */ + inline JKQTMathTextNode* getChild() const { + return this->child; + } + /** \copydoc openbrace */ + inline QString getOpenbrace() const { + return this->openbrace; + } + /** \copydoc closebrace */ + inline QString getClosebrace() const { + return this->closebrace; + } + /** \copydoc showRightBrace */ + inline bool getShowRightBrace() const { + return this->showRightBrace; + } + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + JKQTMathTextNode* child; + QString openbrace; + QString closebrace; + bool showRightBrace; + + void getBraceWidth(QPainter& painter, JKQTMathTextEnvironment currentEv, double baselineHeight, double overallHeight, double& bracewidth, double& braceheight); +}; + +#endif // JKQTMATHTEXTBRACENODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextdecoratednode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextdecoratednode.cpp new file mode 100644 index 0000000000..1865d1c7cb --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextdecoratednode.cpp @@ -0,0 +1,302 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + + + + +JKQTMathTextDecoratedNode::JKQTMathTextDecoratedNode(JKQTMathText* _parent, JKQTMathTextDecoration decoration, JKQTMathTextNode* child): + JKQTMathTextNode(_parent) +{ + this->child=child; + this->decoration=decoration; +} + +JKQTMathTextDecoratedNode::~JKQTMathTextDecoratedNode() { + if (child!=nullptr) delete child; +} + +void JKQTMathTextDecoratedNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + const QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + + child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); + + const double italic_xcorrection=getNonItalicXCorretion(painter, width, currentEv, child); + const double decoheightfactor=parent->getDecorationHeightFactor(); + const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection; + + const double decoAboveAscent_yposdelta=fm.ascent()*(1.0+2.0*decoheightfactor); + const double decoAboveBaselineheight_yposdelta=baselineHeight*(1.0+decoheightfactor); + + + const double descent=overallHeight-baselineHeight; + baselineHeight=decoAboveBaselineheight_yposdelta; + if (decoration==MTDbar) { + baselineHeight=std::max(baselineHeight, decoAboveAscent_yposdelta); + } + overallHeight=baselineHeight+descent; + width=std::max(deco_miniwidth,width); +} + +double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + doDrawBoxes(painter, x, y, currentEv); + JKQTMathTextEnvironment ev=currentEv; + double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; + child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + const QFont font=ev.getFont(parent); + const QFontMetricsF fm(font, painter.device()); + const double width_X=fm.boundingRect("X").width(); + const double width_x=fm.boundingRect("x").width(); + const double width_dot=fm.boundingRect(".").width()/2.0; + const double decoheightfactor=parent->getDecorationHeightFactor(); + const double deco_ypos=y-baselineHeight*(1.0+decoheightfactor); + const double decoAboveAscent_ypos=y-fm.ascent()*(1.0+decoheightfactor); + const double strike_ypos=y-baselineHeight/2.0; + const double decobelow_ypos=y+qMax((overallHeight-baselineHeight)*(1.0+decoheightfactor), fm.xHeight()*decoheightfactor); + const double deco_height=decoheightfactor*baselineHeight; + const double italic_xcorrection=getNonItalicXCorretion(painter, width, ev, child); + const double deco_xoffset=parent->getDecorationWidthReductionXFactor()*width_X/2.0; + const double deco_width=std::max(width_x*0.5,width-2.0*deco_xoffset-italic_xcorrection); + const double deco_vecwidth=width_x*0.33; + const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection; + const double decotop_xcenter=x+italic_xcorrection+(width-italic_xcorrection)/2.0; + const double decotop_xstart=decotop_xcenter-deco_width/2.0; + const double decotop_xend=decotop_xcenter+deco_width/2.0; + const double decobot_xstart=x; + const double decobot_xend=x+width-italic_xcorrection; + const double decobot_xcenter=(decobot_xstart+decobot_xend)/2.0; + + + + QPen pold=painter.pen(); + QPen p=pold; + p.setColor(ev.color); + p.setWidthF(qMax(parent->ABS_MIN_LINEWIDTH, fm.lineWidth()));//ceil(currentEv.fontSize/16.0)); + + double xnew=child->draw(painter, x, y, ev); + + if (decoration==MTDvec) { + painter.setPen(p); + QPolygonF poly; + poly<0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDbar) { + painter.setPen(p); + const QLineF l(decotop_xstart, decoAboveAscent_ypos, decotop_xend, decoAboveAscent_ypos); + if (l.length()>0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDdoubleoverline) { + painter.setPen(p); + const QLineF l(decotop_xstart, deco_ypos, decotop_xend, deco_ypos); + if (l.length()>0) painter.drawLine(l); + const QLineF l2(decotop_xstart, deco_ypos-2.0*p.widthF(), decotop_xend, deco_ypos-2.0*p.widthF()); + if (l2.length()>0) painter.drawLine(l2); + painter.setPen(pold); + } else if (decoration==MTDunderline) { + painter.setPen(p); + const QLineF l(decobot_xstart, decobelow_ypos, decobot_xend, decobelow_ypos); + if (l.length()>0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDdoubleunderline) { + painter.setPen(p); + const QLineF l(decobot_xstart, decobelow_ypos, decobot_xend, decobelow_ypos); + if (l.length()>0) painter.drawLine(l); + QLineF l2(decobot_xstart, decobelow_ypos+2.0*p.widthF(), decobot_xend, decobelow_ypos+2.0*p.widthF()); + if (l2.length()>0) painter.drawLine(l2); + painter.setPen(pold); + } else if (decoration==MTDarrow) { + painter.setPen(p); + const QLineF l(decotop_xstart, deco_ypos+deco_height/2.0, decotop_xend, deco_ypos+deco_height/2.0); + if (l.length()>0) painter.drawLine(l); + QPolygonF poly; + poly<0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDcancel) { + painter.setPen(p); + const QLineF l(decobot_xstart, decobelow_ypos, decotop_xend, deco_ypos); + if (l.length()>0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDbcancel) { + painter.setPen(p); + const QLineF l(decobot_xstart, deco_ypos, decotop_xend, decobelow_ypos); + if (l.length()>0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDxcancel) { + painter.setPen(p); + const QLineF l(decobot_xstart, deco_ypos, decotop_xend, decobelow_ypos); + if (l.length()>0) painter.drawLine(l); + const QLineF l1(decobot_xstart, decobelow_ypos, decotop_xend, deco_ypos); + if (l1.length()>0) painter.drawLine(l1); + painter.setPen(pold); + } + + /*painter.setPen(QPen(Qt::red, 1.5)); + painter.drawLine(QLineF(x, deco_ypos, xnew, deco_ypos)); + painter.setPen(QPen(Qt::green, 1.5)); + painter.drawLine(QLineF(deco_xstart, deco_ypos+2, deco_xend, deco_ypos+2)); + painter.drawEllipse(QPointF(deco_xpos_center, deco_ypos+2), 5, 5); + painter.setPen(pold);*/ + return xnew; +} + +bool JKQTMathTextDecoratedNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/) { + //QString f; + //JKQTMathTextEnvironment ev=currentEv; + + //bool ok=child->toHtml(html, ev, defaultEv); + + return false; +} + +void JKQTMathTextDecoratedNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + child->setDrawBoxes(draw); + +} + +QString JKQTMathTextDecoratedNode::getTypeName() const +{ + return "MTdecoratedNode"; +} + +JKQTMathTextNode *JKQTMathTextDecoratedNode::getChild() const { + return this->child; +} + +JKQTMathTextDecoration JKQTMathTextDecoratedNode::getDecoration() const { + return this->decoration; +} + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextdecoratednode.h b/lib/jkqtmathtext/nodes/jkqtmathtextdecoratednode.h new file mode 100644 index 0000000000..0f4d7dd61c --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextdecoratednode.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTDECORATEDNODE_H +#define JKQTMATHTEXTDECORATEDNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing a decorated text m (e.g. \c \\vec \c \\hat ...) node + * \ingroup jkqtmathtext_items + * + * \image html mathparser/decoration_sizing.png + * + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDecoratedNode: public JKQTMathTextNode { + public: + JKQTMathTextDecoratedNode(JKQTMathText* parent, JKQTMathTextDecoration decoration, JKQTMathTextNode* child); + virtual ~JKQTMathTextDecoratedNode() override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override ; + /** \brief returns the child node */ + JKQTMathTextNode* getChild() const; + /** \copydoc decoration */ + JKQTMathTextDecoration getDecoration() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \brief child node that is decorated by this node */ + JKQTMathTextNode* child; + /** \brief type of decoration that is added to the child node */ + JKQTMathTextDecoration decoration; +}; +#endif // JKQTMATHTEXTDECORATEDNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp new file mode 100644 index 0000000000..1c28b15242 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp @@ -0,0 +1,262 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextfracnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + + + + +JKQTMathTextFracNode::JKQTMathTextFracNode(JKQTMathText* _parent, JKQTMathTextNode* child_top, JKQTMathTextNode* child_bottom, JKQTMathTextFracMode mode): + JKQTMathTextNode(_parent) +{ + this->child1=child_top; + this->child2=child_bottom; + this->mode=mode; +} + +JKQTMathTextFracNode::~JKQTMathTextFracNode() { + if (child1!=nullptr) delete child1; + if (child2!=nullptr) delete child2; +} + +QString JKQTMathTextFracNode::getTypeName() const +{ + return "MTfracNode"; +} + +void JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + JKQTMathTextEnvironment ev1=currentEv; + JKQTMathTextEnvironment ev2=currentEv; + + double xh=fm.xHeight(); //tightBoundingRect("x").height(); + double sp=xh; + double Ah=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()).height();//fm.ascent(); + double xw=fm.boundingRect("x").width(); + + if (mode==MTFMunderbrace || mode==MTFMoverbrace) { + ev2.fontSize=ev2.fontSize*parent->getUnderbraceFactor(); + } else if (mode==MTFMunderset || mode==MTFMoverset) { + ev2.fontSize=ev2.fontSize*parent->getUndersetFactor(); + } else if (mode==MTFMfrac || mode==MTFMsfrac) { + ev1.fontSize=ev1.fontSize*parent->getFracFactor(); + ev2.fontSize=ev2.fontSize*parent->getFracFactor(); + } else if (mode==MTFMtfrac || mode==MTFMstfrac) { + ev1.fontSize=ev1.fontSize*parent->getFracFactor()*0.7; + ev2.fontSize=ev2.fontSize*parent->getFracFactor()*0.7; + } + + + double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos1=0; + double width2=0, baselineHeight2=0, overallHeight2=0, strikeoutPos2=0; + child1->getSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos1); + child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos2); + + overallHeight=0; + baselineHeight=0; + width=0; + if (mode==MTFMfrac || mode==MTFMdfrac || mode==MTFMtfrac) { + //std::cout<<"\nxh="< baselineHeight="<getUnderbraceFactor(); + } else if (mode==MTFMunderset || mode==MTFMoverset) { + ev2.fontSize=ev2.fontSize*parent->getUndersetFactor(); + } else if (mode==MTFMfrac || mode==MTFMsfrac) { + ev1.fontSize=ev1.fontSize*parent->getFracFactor(); + ev2.fontSize=ev2.fontSize*parent->getFracFactor(); + } else if (mode==MTFMtfrac || mode==MTFMstfrac) { + ev1.fontSize=ev1.fontSize*parent->getFracFactor()*0.7; + ev2.fontSize=ev2.fontSize*parent->getFracFactor()*0.7; + } + + + double width1=0, baselineHeight1=0, overallHeight1=0;//, strikeoutPos1=0; + double width2=0, baselineHeight2=0, overallHeight2=0, strikeoutPos=0; + child1->getSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos); + child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos); + double ascent1=baselineHeight1; + double descent1=overallHeight1-baselineHeight1; + double ascent2=baselineHeight2; + double descent2=overallHeight2-baselineHeight2; + + double yline=y-xh*0.5; + + + //double overallHeight=overallHeight1+overallHeight2+xh; + //double baselineHeight=3.0*xh/2.0+overallHeight1; + double width=qMax(width1, width2); + + QPen p=painter.pen(); + p.setColor(ev1.color); + p.setStyle(Qt::SolidLine); + p.setWidthF(qMax(parent->ABS_MIN_LINEWIDTH, lw)); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.setPen(p); + if (mode==MTFMfrac || mode==MTFMdfrac || mode==MTFMtfrac) { + QLineF l(x+xw/4.0, yline, x+width+xw/2.0, yline); + if (l.length()>0) painter.drawLine(l); + child1->draw(painter, x+xw/2.0+(width-width1)/2.0, yline-xh*(parent->getFracShiftFactor())-descent1, ev1); + child2->draw(painter, x+xw/2.0+(width-width2)/2.0, yline+xh*(parent->getFracShiftFactor())+ascent2, ev2); + } else if (mode==MTFMstfrac || mode==MTFMsfrac) { + child1->draw(painter, x, yline-descent1, ev1); + child2->draw(painter, x+width+xw, yline+ascent2, ev2); + QLineF l(x+width+1.2*xw, yline-descent1-ascent1, x+width-0.2*xw, yline+ascent1+descent1); + if (l.length()>0) painter.drawLine(l); + } else if (mode==MTFMstackrel) { + child1->draw(painter, x+xw/2.0+(width-width1)/2.0, yline-xh*(parent->getFracShiftFactor())-descent1, ev1); + child2->draw(painter, x+xw/2.0+(width-width2)/2.0, yline+xh*(parent->getFracShiftFactor())+ascent2, ev2); + } else if (mode==MTFMunderset) { + child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); + child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y+descent1+xh/6.0+ascent2, ev2); + } else if (mode==MTFMunderbrace) { + double ybrace=y+descent1+bw/2.0; + QPainterPath path=JKQTMathTextMakeHBracePath(x+xw/2.0+(width1)/2.0, ybrace, width, bw); + painter.drawPath(path); + + child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); + child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y+descent1+bw+ascent2, ev2); + } else if (mode==MTFMoverset) { + child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); + child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-xh/6.0-descent2, ev2); + } else if (mode==MTFMoverbrace) { + double ybrace=y-ascent1-bw/2.0; + + { + painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(x+xw/2.0+(width1)/2.0, ybrace); + painter.rotate(180); + QPainterPath path=JKQTMathTextMakeHBracePath(0,0, width, bw); + painter.drawPath(path); + } + + child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); + child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-bw-descent2, ev2); + } + + + if (mode==MTFMstackrel) return x+width+ xw; + else if (mode==MTFMstfrac || mode==MTFMsfrac) return x+width+width2+xw; + else return x+width+xw; + +} + +bool JKQTMathTextFracNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/) { + bool ok=false; + + + + return ok; +} + +void JKQTMathTextFracNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + child1->setDrawBoxes(draw); + child2->setDrawBoxes(draw); + +} + +JKQTMathTextNode *JKQTMathTextFracNode::getChild1() const { + return this->child1; +} + +JKQTMathTextNode *JKQTMathTextFracNode::getChild2() const { + return this->child2; +} + +JKQTMathTextFracMode JKQTMathTextFracNode::getMode() const { + return this->mode; +} + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h new file mode 100644 index 0000000000..b1f419e277 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextfracnode.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTFRACNODE_H +#define JKQTMATHTEXTFRACNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing a \\frac node + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFracNode: public JKQTMathTextNode { + public: + JKQTMathTextFracNode(JKQTMathText* parent, JKQTMathTextNode* child_top, JKQTMathTextNode* child_bottom, JKQTMathTextFracMode mode); + virtual ~JKQTMathTextFracNode() override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \brief returns the 1st child node */ + JKQTMathTextNode* getChild1() const; + /** \brief returns the 2nd child node */ + JKQTMathTextNode* getChild2() const; + /** \copydoc mode */ + JKQTMathTextFracMode getMode() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + JKQTMathTextNode* child1; + JKQTMathTextNode* child2; + JKQTMathTextFracMode mode; +}; + + +#endif // JKQTMATHTEXTFRACNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextinstructionnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextinstructionnode.cpp new file mode 100644 index 0000000000..dcda9a407a --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextinstructionnode.cpp @@ -0,0 +1,164 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + + +JKQTMathTextInstruction1Node::JKQTMathTextInstruction1Node(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters): + JKQTMathTextNode(_parent) +{ + this->name=name; + this->child=child; + this->parameters=parameters; + + JKQTMathTextEnvironment ev; + if (!setupMTenvironment(ev)) { + parent->addToErrorList(QObject::tr("unknown instruction '%1' found!").arg(name)); + } +} + +JKQTMathTextInstruction1Node::~JKQTMathTextInstruction1Node() { + if (child!=nullptr) delete child; +} + +QString JKQTMathTextInstruction1Node::getTypeName() const +{ + return QLatin1String("MTinstruction1Node(")+name+")"; +} + +void JKQTMathTextInstruction1Node::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + JKQTMathTextEnvironment ev=currentEv; + + setupMTenvironment(ev); + + child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + if (name=="colorbox" || name=="fbox" || name=="boxed") { + QFontMetricsF fm(ev.getFont(parent)); + double xw=fm.boundingRect("x").width(); + width+=xw; + overallHeight+=xw; + baselineHeight+=xw/2.0; + } +} + +double JKQTMathTextInstruction1Node::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + doDrawBoxes(painter, x, y, currentEv); + JKQTMathTextEnvironment ev=currentEv; + + setupMTenvironment(ev); + + QPen oldPen=painter.pen(); + double shiftX=0; + if (name=="colorbox" || name=="fbox" || name=="boxed") { + QColor fcol=currentEv.color; + if (name=="colorbox") fcol=QColor(parameters.value(0, ev.color.name())); + //qDebug()<<"COLOR="<getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); + QPen p=painter.pen(); + QFontMetricsF fm(currentEv.getFont(parent)); + double xw=fm.boundingRect("x").width(); + p.setColor(fcol); + painter.setPen(p); + painter.drawRect(QRectF(x,y-baselineHeight-xw/2,width+xw,overallHeight+xw)); + shiftX=xw/2.0; + } + + double xnew= child->draw(painter, x+shiftX, y, ev); + painter.setPen(oldPen); + return xnew; +} + +bool JKQTMathTextInstruction1Node::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + JKQTMathTextEnvironment ev=currentEv; + + setupMTenvironment(ev); + + return child->toHtml(html, ev, defaultEv); +} + +void JKQTMathTextInstruction1Node::setDrawBoxes(bool draw) +{ + drawBoxes=draw; + child->setDrawBoxes(draw); +} + +JKQTMathTextNode *JKQTMathTextInstruction1Node::getChild() const { + return this->child; +} + +QString JKQTMathTextInstruction1Node::getName() const { + return this->name; +} + +QStringList JKQTMathTextInstruction1Node::getParameters() const { + return this->parameters; +} + +bool JKQTMathTextInstruction1Node::setupMTenvironment(JKQTMathTextEnvironment &ev) +{ + if (name=="bf" || name=="textbf" || name=="mathbf") ev.bold=true; + else if (name=="em") ev.italic=!ev.italic; + else if (name=="it" || name=="textit" || name=="mathit") ev.italic=true; + else if (name=="textcolor" || name=="mathcolor" || name=="color") ev.color=QColor(parameters.value(0, ev.color.name())); + else if (name=="ensuremath" || name=="equation") { ev.italic=true; ev.insideMath=true; } + else if (name=="sc" || name=="textsc" || name=="mathsc") ev.smallCaps=true; + else if (name=="ul" || name=="underline" || name=="underlined") ev.underlined=true; + else if (name=="ol" || name=="overline" || name=="overlined") ev.overline=true; + else if (name=="strike") ev.strike=true; + else if (name=="rm" || name=="textrm") { ev.font=JKQTMathTextEnvironmentFont::MTEroman; ev.italic=false; } + else if (name=="mathrm" || name=="unit" || name=="operatorname") { ev.font=JKQTMathTextEnvironmentFont::MTEroman; ev.italic=false; } + else if (name=="mathbfit" || name=="bfit" || name=="textbfit") { ev.bold=true; ev.italic=true; } + else if (name=="text" || name=="mbox" || name=="ensuretext") { ev.insideMath=false; ev.font=JKQTMathTextEnvironmentFont::MTEroman; ev.italic=false; } + else if (name=="mat") { ev.font=JKQTMathTextEnvironmentFont::MTEroman; ev.italic=false; ev.bold=true; } + else if (name=="cal" || name=="textcal" || name=="mathcal") { ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic; ev.italic=false; } + else if (name=="fcal" || name=="textfcal" || name=="mathfcal") { ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic; ev.bold=true; } + else if (name=="frak" || name=="textfrak" || name=="mathfrak") { ev.font=JKQTMathTextEnvironmentFont::MTEfraktur; ev.italic=false; } + else if (name=="ffrak" || name=="textffrak" || name=="mathffrak") { ev.font=JKQTMathTextEnvironmentFont::MTEfraktur; ev.bold=true; } + else if (name=="bb" || name=="textbb" || name=="mathbb") { ev.font=JKQTMathTextEnvironmentFont::MTEblackboard; ev.italic=false; } + else if (name=="tt" || name=="texttt" || name=="mathtt") { ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter; ev.italic=false; } + else if (name=="sf" || name=="textsf" || name=="mathsf") { ev.font=JKQTMathTextEnvironmentFont::MTEsans; ev.italic=false; } + else if (name=="sfit" || name=="textsfit" || name=="mathsfit") { ev.font=JKQTMathTextEnvironmentFont::MTEsans; ev.italic=true; } + else if (name=="script" || name=="scr" || name=="textscript" || name=="textscr" || name=="mathscript" || name=="mathscr") { ev.font=JKQTMathTextEnvironmentFont::MTEscript; ev.italic=false; } + else if (name=="fscript" || name=="fscr" || name=="textfscript" || name=="textfscr" || name=="mathfscript" || name=="mathfscr") { ev.font=JKQTMathTextEnvironmentFont::MTEscript; ev.bold=true; ev.italic=false; } + else if (name=="displaystyle") { ev.fontSize=ev.fontSize/0.8; } + else if (name=="scriptstyle") { ev.fontSize=ev.fontSize*0.8; } + else if (name=="scriptscriptstyle") { ev.fontSize=ev.fontSize*0.8*0.8; } + else { + return false; + } + + return true; +} diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextinstructionnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextinstructionnode.h new file mode 100644 index 0000000000..5839ee341a --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextinstructionnode.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTINSTRUCTIONNODE_H +#define JKQTMATHTEXTINSTRUCTIONNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + +/** \brief subclass representing an instruction node with exactly one argument in the syntax tree + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextInstruction1Node: public JKQTMathTextNode { + public: + explicit JKQTMathTextInstruction1Node(JKQTMathText* parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters=QStringList()); + virtual ~JKQTMathTextInstruction1Node() override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \brief convert node to HTML and returns \c true on success */ + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \brief returns the child node */ + JKQTMathTextNode* getChild() const; + /** \copydoc name */ + QString getName() const; + /** \copydoc parameters */ + QStringList getParameters() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + bool setupMTenvironment(JKQTMathTextEnvironment &ev); + + JKQTMathTextNode* child; + QString name; + QStringList parameters; +}; + + + + + +#endif // JKQTMATHTEXTINSTRUCTIONNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp new file mode 100644 index 0000000000..4b12f081b8 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp @@ -0,0 +1,440 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextlistnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h" +#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h" +#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + +JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent): + JKQTMathTextNode(_parent) +{ + nodes.clear(); + // these operations cause sub/sup script to be typeset over/under the operator, not right besides! + subsupOperations<<"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() { + for (int i=0; igetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + + + double xnew=0; + bool wasBrace=false; + for (int i=0; i0 && wasBrace) { + nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); + prevNodeSizePtr=&prevNodeSize; + } + + + 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 (i+1(nodes[i+1])) { // is this subscript? + double w1, w2, oh, bh, sp; + nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr); + + if (bh>baselineHeight) { + overallHeight=overallHeight+bh-baselineHeight; + baselineHeight=bh; + strikeoutPos=sp; + } + if (baselineHeight+oh-bh>overallHeight) { + overallHeight=baselineHeight+oh-bh; + strikeoutPos=sp; + } + + i++; + nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtr); + //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; + 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; + nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); + subn->getChild()->getSize(painter, ev, w2, bh2, oh2, sp2); + //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; + } + double w=qMax(w1, w2)+fm.boundingRect(' ').width(); + i++; + doDraw=false; + xnew+=w; + //qDebug()<<"### subsupop: sub overallHeight="<0 && wasBrace) { + nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); + prevNodeSizePtr=&prevNodeSize; + } + + + 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 (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); + i++; + //painter.setPen(QPen("magenta")); + //painter.drawEllipse(xnew-4,ynew-4,8,8); + double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); + //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); + i++; + //painter.setPen(QPen("magenta")); + //painter.drawEllipse(xnew-4,ynew-4,8,8); + double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr); + //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*parent->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; + + 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*parent->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; + + 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(); + } + } + } + } + + if (idraw(painter, xnew, ynew, currentEv, prevNodeSizePtr); + } + wasBrace=dynamic_cast(nodes[i]); + } + return xnew; +} + +bool JKQTMathTextListNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + bool ok=true; + for (int i=0; itoHtml(h, currentEv, defaultEv); + html=html+h; + } + return ok; +} + +void JKQTMathTextListNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + for (int i=0; isetDrawBoxes(draw); + } +} + +QList JKQTMathTextListNode::getNodes() const { + return this->nodes; +} + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h new file mode 100644 index 0000000000..2891ab8e85 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h @@ -0,0 +1,70 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTLISTNODE_H +#define JKQTMATHTEXTLISTNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing a list of nodes in the syntax tree + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextListNode: public JKQTMathTextNode { + public: + explicit JKQTMathTextListNode(JKQTMathText* parent); + virtual ~JKQTMathTextListNode() override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \brief add a child node */ + void addNode(JKQTMathTextNode* n) { nodes.append(n); } + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \copydoc nodes */ + QList getNodes() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + QList nodes; + QSet subsupOperations; +}; + +#endif // JKQTMATHTEXTLISTNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextmatrixnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextmatrixnode.cpp new file mode 100644 index 0000000000..1df0126ecd --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextmatrixnode.cpp @@ -0,0 +1,198 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextmatrixnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + + + + +JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, QVector > children): + JKQTMathTextNode(_parent) +{ + this->lines=children.size(); + this->columns=0; + for (int i=0; ithis->columns) this->columns=children[i].size(); + } + this->children=children; +} + +JKQTMathTextMatrixNode::~JKQTMathTextMatrixNode() { + for (int i=0; igetFracFactor(); + + + QVector colwidth, rowheight; + //QVector > widths, heights, baselines; + + double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos1=0; + //widths.resize(lines); + colwidth.resize(columns); for (int i=0; igetSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos1); + /*widths[i].operator[](j)=width1; + baselines[i].operator[](j)=baselineHeight; + heights[i].operator[](j)=overallHeight1;*/ + if (overallHeight1>rowheight[i]) rowheight[i]=overallHeight1; + if (width1>colwidth[j]) colwidth[j]=width1; + } + } + + + overallHeight=(lines-1)*xw/2.0; + width=columns*xw; + for (int i=0; igetFracFactor(); + + + QVector colwidth, rowheight, rowascent; + //QVector > widths, heights, baselines; + + double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos=0; + //widths.resize(lines); + colwidth.resize(columns); for (int i=0; igetSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos); + /*widths[i].operator[](j)=width1; + baselines[i].operator[](j)=baselineHeight; + heights[i].operator[](j)=overallHeight1;*/ + if (overallHeight1>rowheight[i]) rowheight[i]=overallHeight1; + if (baselineHeight1>rowascent[i]) rowascent[i]=baselineHeight1; + if (width1>colwidth[j]) colwidth[j]=width1; + } + } + + double overallHeight=(lines-1)*xw/2.0; + double width=(columns)*xw; + for (int i=0; i0) yy=yy+rowascent[0]; + for (int i=0; idraw(painter, xx, yy, ev1); + xx=xx+colwidth[j]+xw; + } + + if (i > JKQTMathTextMatrixNode::getChildren() const { + return this->children; +} + +int JKQTMathTextMatrixNode::getColumns() const { + return this->columns; +} + +int JKQTMathTextMatrixNode::getLines() const { + return this->lines; +} + +void JKQTMathTextMatrixNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + for (int i=0; isetDrawBoxes(draw); + } + } + +} + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextmatrixnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextmatrixnode.h new file mode 100644 index 0000000000..682c4abeda --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextmatrixnode.h @@ -0,0 +1,71 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTMATRIXNODE_H +#define JKQTMATHTEXTMATRIXNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing a \\begin{matrix} node + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode { + public: + JKQTMathTextMatrixNode(JKQTMathText* parent, QVector > children); + virtual ~JKQTMathTextMatrixNode() override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \brief returns the child nodes */ + QVector > getChildren() const; + /** \copydoc columns */ + int getColumns() const; + /** \copydoc lines */ + int getLines() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + QVector > children; + int columns; + int lines; +}; + +#endif // JKQTMATHTEXTMATRIXNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp new file mode 100644 index 0000000000..2a0790050c --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp @@ -0,0 +1,115 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + +// -------------------------------------------------------------------------------------------------- +// -- implementation of the JKQTMathTextNode's methods +// -------------------------------------------------------------------------------------------------- +JKQTMathTextNode::JKQTMathTextNode(JKQTMathText* parent) { + this->parent=parent; + drawBoxes=false; +} + +JKQTMathTextNode::~JKQTMathTextNode() += default; + +void JKQTMathTextNode::getSize(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) +{ + double w=width, b=baselineHeight, o=overallHeight, s=strikeoutPos; + getSizeInternal(painter, currentEv, w, b, o, s, prevNodeSize); + + if (w<1e5) width=w; + if (b<1e5) baselineHeight=b; + if (o<1e5) overallHeight=o; + if (s<1e5) strikeoutPos=s; +} + + +double JKQTMathTextNode::getNonItalicXCorretion(QPainter &painter, double width_potentiallyitalic, const JKQTMathTextEnvironment &ev_potentiallyitalic, JKQTMathTextNode* child) const +{ + double italic_xcorrection=0.0; + if (ev_potentiallyitalic.italic) { + JKQTMathTextEnvironment ev_nonitalic=ev_potentiallyitalic; + ev_nonitalic.italic=false; + double width_nonitalic=0, baselineHeight_nonitalic=0, overallHeight_nonitalic=0, strikeoutPos_nonitalic=0; + child->getSize(painter, ev_nonitalic, width_nonitalic, baselineHeight_nonitalic, overallHeight_nonitalic, strikeoutPos_nonitalic); + italic_xcorrection=width_potentiallyitalic-width_nonitalic; + } + return italic_xcorrection; +} + + +bool JKQTMathTextNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/) { + return false; +} + +bool JKQTMathTextNode::getDrawBoxes() const { + return this->drawBoxes; +} + + +void JKQTMathTextNode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) { + if (drawBoxes) { + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + double w, oh, bh, sp; + getSize(painter, currentEv, w, bh, oh, sp); + QPen p=painter.pen(); + p.setColor("lightcoral"); + p.setWidthF(0.5); + painter.setPen(p); + QRectF r(x, y-bh, w, oh); + painter.drawRect(r); + p.setColor("lightblue"); + painter.setPen(p); + if (w>0) painter.drawLine(QLineF(x, y, x+w, y)); + p.setColor("green"); + painter.setPen(p); + painter.drawEllipse(QRectF(x-3.0,y-3.0,6.0,6.0)); + p.setColor("lightgreen"); + painter.setPen(p); + painter.drawLine(QLineF(x-2.0, y, x+2.0, y)); + painter.drawLine(QLineF(x, y-2, x, y+2.0)); + + } +} + +void JKQTMathTextNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; +} + +QString JKQTMathTextNode::getTypeName() const +{ + return "JKQTMathTextNode"; +} diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextnode.h new file mode 100644 index 0000000000..30ce8df896 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTNODE_H +#define JKQTMATHTEXTNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include + +class JKQTMathText; // forward + +/** \brief subclass representing one node in the syntax tree + * \ingroup jkqtmathtext_items + * + * \image html jkqtmathtext_node_geo.png + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode { + public: + explicit JKQTMathTextNode(JKQTMathText* parent); + JKQTMathTextNode(const JKQTMathTextNode&)=delete; + JKQTMathTextNode& operator=(const JKQTMathTextNode&)=delete; + virtual ~JKQTMathTextNode(); + /** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal() + * + * \param painter painter to use for determining the size + * \param currentEv current environment object + * \param[out] width width of the block/node + * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline + * \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight + * \param[out] strikeoutPos position of the strikeout-line + * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) + * + */ + void getSize(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr); + /** \brief calculates the x-size-difference between the given (probably) italic (width externally calculated: \A width_potentiallyitalic, \a ev_potentiallyitalic) and the non-italic version of \a child */ + double getNonItalicXCorretion(QPainter &painter, double width_potentiallyitalic, const JKQTMathTextEnvironment &ev_potentiallyitalic, JKQTMathTextNode* child) const; + /** \brief draw the contents at the designated position + * + * \param painter QPainter to use + * \param x x-position, where the drawing starts [Pixel] + * \param y Y-position of the baseline, where the drawing starts [Pixel] + * \param currentEv JKQTMathTextEnvironment object describing the current drawing environment/settings + * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) + * \return the x position which to use for the next part of the text + */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr)=0; + /** \brief convert node to HTML and returns \c true on success + * \param[out] html new HTML code is APPENDED to this string + * \param currentEv JKQTMathTextEnvironment object describing the current drawing environment/settings + * \param defaultEv JKQTMathTextEnvironment object describing the default drawing environment/settings when starting to interpret a node tree + * \return \c true on success + */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv); + + /** \brief returns the drawing of colored boxes (for DEBUGGING) around the actual output of the node is enabled */ + bool getDrawBoxes() const; + /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ + virtual void setDrawBoxes(bool draw); + /** \brief return the name of this class as a string */ + virtual QString getTypeName() const; + protected: + /** \brief determine the size of the node, overwrite this function in derived classes + * + * \param painter painter to use for determining the size + * \param currentEv current environment object + * \param[out] width width of the block/node + * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline + * \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight + * \param[out] strikeoutPos position of the strikeout-line + * \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...) + * + */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr)=0; + + /** \brief parent JKQTMathText object (required for several drawing operations */ + JKQTMathText* parent; + /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */ + bool drawBoxes; + /** \brief draws colored boxes (for DEBUGGING) around the actual output of the node + * + * \param painter QPainter to use + * \param x x-position, where the drawing starts [Pixel] + * \param y Y-position of the baseline, where the drawing starts [Pixel] + * \param currentEv JKQTMathTextEnvironment object describing the current drawing environment/settings + */ + void doDrawBoxes(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv); +}; + +#endif // JKQTMATHTEXTNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp new file mode 100644 index 0000000000..12d9a27e2b --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp @@ -0,0 +1,127 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextsqrtnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + +JKQTMathTextSqrtNode::JKQTMathTextSqrtNode(JKQTMathText* _parent, JKQTMathTextNode* child, int degree): + JKQTMathTextNode(_parent) +{ + this->child=child; + this->degree=degree; +} + +JKQTMathTextSqrtNode::~JKQTMathTextSqrtNode() { + if (child!=nullptr) delete child; +} + +void JKQTMathTextSqrtNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + + child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); + + overallHeight=overallHeight*1.2;//+fm.ascent()*0.1; + baselineHeight=baselineHeight*1.2;//+fm.ascent()*0.1; + width=width+fm.boundingRect("A").width()*2; // 1.53 +} + +double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + doDrawBoxes(painter, x, y, currentEv); + double width=0, baselineHeight=0, overallHeight=0, sp=0; + child->getSize(painter, currentEv, width, baselineHeight, overallHeight, sp); + QFont f=currentEv.getFont(parent); + QFont fsmall=f; + QFontMetricsF fm(f, painter.device()); + double w=fm.boundingRect("A").width(); + double a=baselineHeight*1.15; + double d=overallHeight-baselineHeight; + //painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + QPen p=painter.pen(); + p.setColor(currentEv.color); + p.setWidthF(fm.lineWidth()); + //painter.setPen(p); + QPainterPath path; + if (w>0) { + path.moveTo(x+0.1*w, y-0.4*a); + path.lineTo(x+0.33*w, y-0.4*a); + path.lineTo( x+0.66*w, y+0.5*d); + path.lineTo(x+w, y-a); + } + if (degree!=2) { + fsmall.setPointSizeF(fsmall.pointSizeF()/2.0); + fsmall.setItalic(false); + painter.setFont(fsmall); + painter.drawText(QPointF(x+0.33*w, y-0.55*a), QLocale::c().toString(degree)); + } + //painter.restore(); + double xnew=child->draw(painter, x+1.2*w, y, currentEv); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.setPen(p); + if (w>0) { + path.lineTo( xnew+0.2*w, y-a); + path.lineTo(xnew+0.2*w, y-0.8*a); + painter.drawPath(path); + } + + return xnew+0.33*w; +} + +bool JKQTMathTextSqrtNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + html=html+"√"; + bool ok=child->toHtml(html, currentEv, defaultEv); + html=html+" "; + return ok; +} + +void JKQTMathTextSqrtNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + child->setDrawBoxes(draw); + +} + +QString JKQTMathTextSqrtNode::getTypeName() const +{ + return "MTsqrtNode"; +} + +JKQTMathTextNode *JKQTMathTextSqrtNode::getChild() const { + return this->child; +} + +int JKQTMathTextSqrtNode::getDegree() const { + return this->degree; +} + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h new file mode 100644 index 0000000000..6ca672ffc3 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h @@ -0,0 +1,71 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTSQRTNODE_H +#define JKQTMATHTEXTSQRTNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + + +/** \brief subclass representing a sqrt node + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSqrtNode: public JKQTMathTextNode { + public: + JKQTMathTextSqrtNode(JKQTMathText* parent, JKQTMathTextNode* child, int degree=2); + virtual ~JKQTMathTextSqrtNode() override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override ; + /** \brief returns the child node */ + JKQTMathTextNode *getChild() const; + /** \copydoc degree */ + int getDegree() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + JKQTMathTextNode* child; + int degree; +}; + +#endif // JKQTMATHTEXTSQRTNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp new file mode 100644 index 0000000000..7272a00cc5 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp @@ -0,0 +1,203 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + + + +JKQTMathTextSuperscriptNode::JKQTMathTextSuperscriptNode(JKQTMathText* _parent, JKQTMathTextNode* child): + JKQTMathTextNode(_parent) +{ + this->child=child; +} + +JKQTMathTextSuperscriptNode::~JKQTMathTextSuperscriptNode() { + if (child!=nullptr) delete child; +} + +void JKQTMathTextSuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) { + JKQTMathTextEnvironment ev=currentEv; + ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); + QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + double shift=parent->getSuperShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { + shift=prevNodeSize->baselineHeight-(overallHeight-baselineHeight)-shift; + } + + double yshift=shift+overallHeight-baselineHeight; + baselineHeight=overallHeight=overallHeight+shift; + strikeoutPos=strikeoutPos-yshift; + if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.boundingRect(' ').width())*parent->getItalicCorrectionFactor(); +} + +double JKQTMathTextSuperscriptNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize) { + doDrawBoxes(painter, x, y, currentEv); + JKQTMathTextEnvironment ev=currentEv; + ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); + + double cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos; + child->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos); + + QFontMetricsF fm(currentEv.getFont(parent), painter.device()); + QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + double shift=parent->getSuperShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) { + shift=prevNodeSize->baselineHeight-(cOverallHeight-cBaselineHeight)-shift; + } + + double yshift=shift+cOverallHeight-cBaselineHeight; + double xx=x; + if (currentEv.italic && prevNodeSize==nullptr) xx=xx+double(fm.boundingRect(' ').width())*parent->getItalicCorrectionFactor(); + + return child->draw(painter, xx, y-yshift, ev);//+0.5*fm.boundingRect("A").width(); +} + +JKQTMathTextNode *JKQTMathTextSuperscriptNode::getChild() const { + return this->child; +} + + +QString JKQTMathTextSuperscriptNode::getTypeName() const +{ + return "MTsuperscriptNode"; +} + + +bool JKQTMathTextSuperscriptNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) +{ + html=html+""; + bool ok=child->toHtml(html, currentEv, defaultEv); + html=html+""; + return ok; +} + +void JKQTMathTextSuperscriptNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + child->setDrawBoxes(draw); + +} + + + + + + + +JKQTMathTextSubscriptNode::JKQTMathTextSubscriptNode(JKQTMathText* _parent, JKQTMathTextNode* child): + JKQTMathTextNode(_parent) +{ + this->child=child; +} + +JKQTMathTextSubscriptNode::~JKQTMathTextSubscriptNode() { + if (child!=nullptr) delete child; +} + +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*parent->getSubsuperSizeFactor(); + + child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + + QFontMetricsF fm(ev.getFont(parent), painter.device()); + QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + double shift=parent->getSubShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { + shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); + } + + double yshift=baselineHeight-shift; + baselineHeight=shift; + strikeoutPos=fm.strikeOutPos()+yshift; + if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.boundingRect(' ').width())*parent->getItalicCorrectionFactor(); +} + +double JKQTMathTextSubscriptNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize) { + doDrawBoxes(painter, x, y, currentEv); + JKQTMathTextEnvironment ev=currentEv; + ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); + QFontMetricsF fm(ev.getFont(parent), painter.device()); + QRectF tbr=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parent), "M", painter.device()); + + double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; + child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); + double shift=parent->getSubShiftFactor()*tbr.height(); + + if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) { + //qDebug()<<"oldshift="<overallHeight="<overallHeight<<", prevNodeSize->baselineHeight="<baselineHeight; + shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift); + //qDebug()<<"newshift="<child; +} + + +bool JKQTMathTextSubscriptNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + html=html+""; + bool ok=child->toHtml(html, currentEv, defaultEv); + html=html+""; + return ok; +} + +void JKQTMathTextSubscriptNode::setDrawBoxes(bool draw) +{ + this->drawBoxes=draw; + child->setDrawBoxes(draw); + +} + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.h b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.h new file mode 100644 index 0000000000..7a65c933c6 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsubsupernode.h @@ -0,0 +1,96 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTSUBSUPERSCRIPTNODE_H +#define JKQTMATHTEXTSUBSUPERSCRIPTNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing an subscript node with exactly one argument in the syntax tree +* \ingroup jkqtmathtext_items +* +* \image html jkqtmathtext_subscriptnode_getSizeInternal.png +*/ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSubscriptNode: public JKQTMathTextNode { +public: + explicit JKQTMathTextSubscriptNode(JKQTMathText* parent, JKQTMathTextNode* child); + virtual ~JKQTMathTextSubscriptNode() override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; /** \brief returns the child node */ + /** \brief returns the child node */ + JKQTMathTextNode *getChild() const; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; +protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + JKQTMathTextNode* child; +}; + +/** \brief subclass representing an superscript node with exactly one argument in the syntax tree +* \ingroup jkqtmathtext_items +* +* \image html jkqtmathtext_subscriptnode_getSizeInternal.png +* +* \note a MTlistNode might modify the positioning slightly for special cases (e.g. \c \\int , \c \\sum ... or after braces) +*/ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSuperscriptNode: public JKQTMathTextNode { +public: + explicit JKQTMathTextSuperscriptNode(JKQTMathText* parent, JKQTMathTextNode* child); + virtual ~JKQTMathTextSuperscriptNode() override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \brief returns the child node */ + JKQTMathTextNode* getChild() const; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc JKQTMathTextNode::setDrawBoxes() */ + virtual void setDrawBoxes(bool draw) override; +protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + JKQTMathTextNode* child; +}; + +#endif // JKQTMATHTEXTSUBSUPERSCRIPTNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp new file mode 100644 index 0000000000..28dffd91e3 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp @@ -0,0 +1,1288 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + + + + + + + +JKQTMathTextSymbolNode::JKQTMathTextSymbolNode(JKQTMathText* _parent, const QString& name, bool _addWhitespace): + JKQTMathTextNode(_parent), symbolName(name), addWhitespace(_addWhitespace) +{ +} + +JKQTMathTextSymbolNode::~JKQTMathTextSymbolNode() = default; + +QString JKQTMathTextSymbolNode::getTypeName() const +{ + return QLatin1String("JKQTMathTextSymbolNode(")+symbolName+QLatin1String(")"); +} + +bool JKQTMathTextSymbolNode::getWinSymbolProp(JKQTMathTextSymbolNode::SymbolProps& props, const QString &n, const JKQTMathTextEnvironment& currentEv, double mathFontFactor) const +{ + auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Text); + auto fntSym=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Symbols); + + //qDebug()<<" +--- getWinSymbolProp("< winSymbolSymbol; + if (winSymbolSymbol.isEmpty()) { + winSymbolSymbol.insert("leftrightarrow", QChar(0xAB)); + winSymbolSymbol.insert("leftarrow", QChar(0xAC)); + winSymbolSymbol.insert("rightarrow", QChar(0xAE)); + winSymbolSymbol.insert("to", QChar(0xAE)); + winSymbolSymbol.insert("uparrow", QChar(0xAD)); + winSymbolSymbol.insert("downarrow", QChar(0xAF)); + winSymbolSymbol.insert("Leftrightarrow", QChar(0xDB)); + winSymbolSymbol.insert("iff", QChar(0xDB)); + winSymbolSymbol.insert("Leftarrow", QChar(0xDC)); + winSymbolSymbol.insert("Rightarrow", QChar(0xDE)); + winSymbolSymbol.insert("Uparrow", QChar(0xDD)); + winSymbolSymbol.insert("Downarrow", QChar(0xFF)); + winSymbolSymbol.insert("pm", QChar(0xB1)); + winSymbolSymbol.insert("leq", QChar(0xA3)); + winSymbolSymbol.insert("geq", QChar(0xB3)); + winSymbolSymbol.insert("le", QChar(0xA3)); + winSymbolSymbol.insert("ge", QChar(0xB3)); + winSymbolSymbol.insert("times", QChar(0xB4)); + winSymbolSymbol.insert("propto", QChar(0xB5)); + winSymbolSymbol.insert("partial", QChar(0xB6)); + winSymbolSymbol.insert("bullet", QChar(0xB7)); + winSymbolSymbol.insert("neq", QChar(0xB9)); + winSymbolSymbol.insert("ne", QChar(0xB9)); + winSymbolSymbol.insert("equiv", QChar(0xBA)); + winSymbolSymbol.insert("approx", QChar(0xBB)); + winSymbolSymbol.insert("ellipsis", QChar(0xBC)); + winSymbolSymbol.insert("Im", QChar(0xC1)); + winSymbolSymbol.insert("Re", QChar(0xC2)); + winSymbolSymbol.insert("otimes", QChar(0xC4)); + winSymbolSymbol.insert("oplus", QChar(0xC5)); + winSymbolSymbol.insert("oslash", QChar(0xC6)); + winSymbolSymbol.insert("cap", QChar(0xC7)); + winSymbolSymbol.insert("land", QChar(0xC7)); + winSymbolSymbol.insert("cup", QChar(0xC8)); + winSymbolSymbol.insert("lor", QChar(0xC8)); + winSymbolSymbol.insert("supset", QChar(0xC9)); + winSymbolSymbol.insert("supseteq", QChar(0xCA)); + winSymbolSymbol.insert("supsetnot", QChar(0xCB)); + winSymbolSymbol.insert("subset", QChar(0xCC)); + winSymbolSymbol.insert("subseteq", QChar(0xCD)); + winSymbolSymbol.insert("in", QChar(0xCE)); + winSymbolSymbol.insert("notin", QChar(0xCF)); + winSymbolSymbol.insert("angle", QChar(0xD0)); + winSymbolSymbol.insert("nabla", QChar(0xD1)); + winSymbolSymbol.insert("copyright", QChar(0xD3)); + winSymbolSymbol.insert("registered", QChar(0xD2)); + winSymbolSymbol.insert("circledR", QChar(0xD2)); + winSymbolSymbol.insert("trademark", QChar(0xD4)); + winSymbolSymbol.insert("textregistered", QChar(0xD4)); + winSymbolSymbol.insert("cdot", QChar(0xD7)); + winSymbolSymbol.insert("neg", QChar(0xD8)); + winSymbolSymbol.insert("wedge", QChar(0xD9)); + winSymbolSymbol.insert("vee", QChar(0xDA)); + winSymbolSymbol.insert("diamond", QChar(0xE0)); + winSymbolSymbol.insert("langle", QChar(0xE1)); + winSymbolSymbol.insert("rangle", QChar(0xF1)); + winSymbolSymbol.insert("forall", QChar(0x22)); + winSymbolSymbol.insert("exists", QChar(0x24)); + winSymbolSymbol.insert("cong", QChar(0x40)); + winSymbolSymbol.insert("bot", QChar(0x5E)); + winSymbolSymbol.insert("ll", "<<"); + winSymbolSymbol.insert("gg", ">>"); + winSymbolSymbol.insert("Alef", QChar(0xC0)); + winSymbolSymbol.insert("alef", QChar(0xC0)); + winSymbolSymbol.insert("tilde", "~"); + winSymbolSymbol.insert("emptyset", QChar(0xC6)); + winSymbolSymbol.insert("varnothing", QChar(0xC6)); + winSymbolSymbol.insert("lceil", QChar(0xE9)); + winSymbolSymbol.insert("rceil", QChar(0xF9)); + winSymbolSymbol.insert("lfloor", QChar(0xEB)); + winSymbolSymbol.insert("rfloor", QChar(0xFB)); + winSymbolSymbol.insert("subsetnot", QChar(0xCB)); + winSymbolSymbol.insert("DC", "="); + winSymbolSymbol.insert("mid", "|"); + winSymbolSymbol.insert("cdots", QString(3, QChar(0xD7))); + winSymbolSymbol.insert("dots", QChar(0xDC)); + winSymbolSymbol.insert("ldots", QChar(0xDC)); + winSymbolSymbol.insert("cent", "c"); + winSymbolSymbol.insert("sim", QChar(0x7E)); + winSymbolSymbol.insert("infty", QChar(0xA5)); + } + + QHash::iterator itsymbol = winSymbolSymbol.find(n); + if (itsymbol!=winSymbolSymbol.end()) { + props.symbol = itsymbol.value(); + } else if (n == "int") { props.symbol = QChar(0xF2); props.fontFactor = mathFontFactor; props.yfactor = +0.1; } + else if (n == "bbC") { props.symbol = "C"; props.bold = +1; props.italic = -1; } + else if (n == "bbH") { props.symbol = "H"; props.bold = +1; props.italic = -1; } + else if (n == "bbN") { props.symbol = "N"; props.bold = +1; props.italic = -1; } + else if (n == "bbP") { props.symbol = "P"; props.bold = +1; props.italic = -1; } + else if (n == "bbQ") { props.symbol = "Q"; props.bold = +1; props.italic = -1; } + else if (n == "bbR") { props.symbol = "R"; props.bold = +1; props.italic = -1; } + else if (n == "bbZ") { props.symbol = "Z"; props.bold = +1; props.italic = -1; } + else if (n == "iint") { props.symbol = QString(2, QChar(0xF2)); props.fontFactor = mathFontFactor; props.yfactor = +0.1; } + else if (n == "iiint") { props.symbol = QString(3, QChar(0xF2)); props.fontFactor = mathFontFactor; props.yfactor = +0.1; } + else if (n == "bigcap") { props.symbol = QChar(0xC7); props.fontFactor = 2; } + else if (n == "bigcup") { props.symbol = QChar(0xC8); props.fontFactor = 2; } + else if (n == "bigvee") { props.symbol = QChar(0xDA); props.fontFactor = 2; } + else if (n == "bighat") { props.symbol = QChar(0xD9); props.fontFactor = 2; } + + else { // here are text mode symbols, i.e. bold and italic won't be touched + props.bold = -1; + props.italic = -1; + props.font = fnt.first; + if (n == "_") { props.symbol = "_"; props.bold = 0; props.italic = 0; } + else if (n == "}") { props.symbol = "}"; props.italic=-1; } + else if (n == "{") { props.symbol = "{"; props.italic=-1; } + else if (n == "]") { props.symbol = "]"; props.italic=-1; } + else if (n == "[") { props.symbol = "["; props.italic=-1; } + else if (n == "(") { props.symbol = "("; props.italic=-1; } + else if (n == ")") { props.symbol = ")"; props.italic=-1; } + else if (n == "|") { props.symbol = "|"; props.italic=-1; } + else if (n == "hbar") { props.symbol = "h"; props.bold = 0; props.italic = 0; props.drawBar = true; } + else if (n == "euro") { props.symbol = ""; props.bold = 0; props.italic = 0; } + else if (n == "cent") { props.symbol = QChar(0xA2); props.bold = 0; props.italic = 0; } + else if (n == "pound") { props.symbol = QChar(0xA3); props.bold = 0; props.italic = 0; } + else if (n == "yen") { props.symbol = QChar(0xA5); props.bold = 0; props.italic = 0; } + else if (n == "div") { props.symbol = QChar(0xF7); props.bold = 0; props.italic = 0; } + else if (n == "backslash") { props.symbol = "\\"; props.bold = 0; props.italic = 0; } + //else if (n=="|") { symbol="||"; bold=0; italic=0; } + else if (n == "/") { props.symbol = "/"; props.bold = 0; props.italic = 0; } + else if (n == "+") { props.symbol = "+"; props.bold = 0; props.italic = 0; } + else if (n == "-") { props.symbol = "-"; props.bold = 0; props.italic = 0; } + else if (n == "*") { props.symbol = "*"; props.bold = 0; props.italic = 0; } + else if (n == "=") { props.symbol = "= "; props.bold = 0; props.italic = 0; } + else if (n == ">") { props.symbol = ">"; props.bold = 0; props.italic = 0; } + else if (n == "<") { props.symbol = "<"; props.bold = 0; props.italic = 0; } + else if (n == "$") { props.symbol = "$"; props.bold = 0; props.italic = 0; } + else if (n == "%") { props.symbol = "%"; props.bold = 0; props.italic = 0; } + else if (n == "&") { props.symbol = "&"; props.bold = 0; props.italic = 0; } + else if (n == "#") { props.symbol = "#"; props.bold = 0; props.italic = 0; } + else if (n == "ast") { props.symbol = "*"; props.bold = 0; props.italic = 0; } + else if (n == "asterisk") { props.symbol = "*"; props.bold = 0; props.italic = 0; } + else if (n == "glq") { props.symbol = "'"; props.bold = 0; props.italic = 0; } + else if (n == "grq") { props.symbol = "'"; props.bold = 0; props.italic = 0; } + else if (n == "glqq") { props.symbol = "\""; props.bold = 0; props.italic = 0; } + else if (n == "grqq") { props.symbol = "\""; props.bold = 0; props.italic = 0; } + else if (n == "flq") { props.symbol = "<"; props.bold = 0; props.italic = 0; } + else if (n == "frq") { props.symbol = ">"; props.bold = 0; props.italic = 0; } + else if (n == "flqq") { props.symbol = ""; props.bold = 0; props.italic = 0; } + else if (n == "frqq") { props.symbol = ""; props.bold = 0; props.italic = 0; } + else { return false; } + } + + return true; +} + +bool JKQTMathTextSymbolNode::getGreekSymbolProp(JKQTMathTextSymbolNode::SymbolProps& props, const QString &n, const JKQTMathTextEnvironment& currentEv, double mathFontFactor) const +{ + auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Text); + auto fntGreek=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Greek); + + //qDebug()<<" +--- getGreekSymbolProp("< winSymbolGreek; + if (winSymbolGreek.isEmpty()) { + winSymbolGreek.insert("alpha", "a"); + winSymbolGreek.insert("beta", "b"); + winSymbolGreek.insert("gamma", "g"); + winSymbolGreek.insert("delta", "d"); + winSymbolGreek.insert("epsilon", "e"); + winSymbolGreek.insert("varepsilon", "e"); + winSymbolGreek.insert("zeta", "z"); + winSymbolGreek.insert("eta", "h"); + winSymbolGreek.insert("theta", "q"); + winSymbolGreek.insert("vartheta", "J"); + winSymbolGreek.insert("iota", "i"); + winSymbolGreek.insert("kappa", "k"); + winSymbolGreek.insert("lambda", "l"); + winSymbolGreek.insert("mu", "m"); + winSymbolGreek.insert("nu", "n"); + winSymbolGreek.insert("xi", "x"); + winSymbolGreek.insert("pi", "p"); + winSymbolGreek.insert("varpi", "v"); + winSymbolGreek.insert("rho", "r"); + winSymbolGreek.insert("sigma", "s"); + winSymbolGreek.insert("varsigma", "V"); + winSymbolGreek.insert("tau", "t"); + winSymbolGreek.insert("upsilon", "u"); + winSymbolGreek.insert("phi", "f"); + winSymbolGreek.insert("varphi", "j"); + winSymbolGreek.insert("chi", "c"); + winSymbolGreek.insert("psi", "y"); + winSymbolGreek.insert("omega", "w"); + winSymbolGreek.insert("Gamma", "G"); + winSymbolGreek.insert("Delta", "D"); + winSymbolGreek.insert("Theta", "Q"); + winSymbolGreek.insert("Lambda", "L"); + winSymbolGreek.insert("Omega", "W"); + winSymbolGreek.insert("Xi", "X"); + winSymbolGreek.insert("Pi", "P"); + winSymbolGreek.insert("Sigma", "S"); + winSymbolGreek.insert("Upsilon", ""); + winSymbolGreek.insert("Phi", "F"); + winSymbolGreek.insert("Psi", "Y"); + } + + static QHash unicodeGreek; + if (unicodeGreek.isEmpty()) { + unicodeGreek.insert("alpha", QChar(0x3B1)); + unicodeGreek.insert("beta", QChar(0x3B2)); + unicodeGreek.insert("gamma", QChar(0x3B3)); + unicodeGreek.insert("delta", QChar(0x3B4)); + unicodeGreek.insert("epsilon", QChar(0x3B5)); + unicodeGreek.insert("varepsilon", QChar(0x3B5)); + unicodeGreek.insert("zeta", QChar(0x3B6)); + unicodeGreek.insert("eta", QChar(0x3B7)); + unicodeGreek.insert("theta", QChar(0x3B8)); + unicodeGreek.insert("vartheta", QChar(0x3D1)); + unicodeGreek.insert("iota", QChar(0x3B9)); + unicodeGreek.insert("kappa", QChar(0x3BA)); + unicodeGreek.insert("lambda", QChar(0x3BB)); + unicodeGreek.insert("mu", QChar(0x3BC)); + unicodeGreek.insert("nu", QChar(0x3BD)); + unicodeGreek.insert("xi", QChar(0x3BE)); + unicodeGreek.insert("pi", QChar(0x3C0)); + unicodeGreek.insert("varpi", QChar(0x3D6)); + unicodeGreek.insert("rho", QChar(0x3C1)); + unicodeGreek.insert("varrho", QChar(0x3F1)); + unicodeGreek.insert("sigma", QChar(0x3C3)); + unicodeGreek.insert("varsigma", QChar(0x3C2)); + unicodeGreek.insert("tau", QChar(0x3C4)); + unicodeGreek.insert("upsilon", QChar(0x3C5)); + unicodeGreek.insert("phi", QChar(0x3D5)); + unicodeGreek.insert("varphi", QChar(0x3C6)); + unicodeGreek.insert("chi", QChar(0x3C7)); + unicodeGreek.insert("psi", QChar(0x3C8)); + unicodeGreek.insert("omega", QChar(0x3C9)); + unicodeGreek.insert("Omega", QChar(0x3A9)); + unicodeGreek.insert("Gamma", QChar(0x393)); + unicodeGreek.insert("Delta", QChar(0x394)); + unicodeGreek.insert("Theta", QChar(0x398)); + unicodeGreek.insert("Lambda", QChar(0x39B)); + unicodeGreek.insert("Xi", QChar(0x39E)); + unicodeGreek.insert("Pi", QChar(0x3A0)); + unicodeGreek.insert("prod", QChar(0x3A0)); + unicodeGreek.insert("Sigma", QChar(0x3A3)); + unicodeGreek.insert("sum", QChar(0x3A3)); + unicodeGreek.insert("Upsilon", QChar(0x3A5)); + unicodeGreek.insert("Phi", QChar(0x3A6)); + unicodeGreek.insert("Psi", QChar(0x3A8)); + } + + //qDebug()<<"##SEARCHING "<::iterator itgreek = unicodeGreek.find(n); + if (itgreek!=unicodeGreek.end()) { + //qDebug()<<"##SEARCHING "<::iterator itgreek = unicodeGreek.find(n); + if (itgreek!=unicodeGreek.end()) { + //qDebug()<<"##SEARCHING "<::iterator itgreek = winSymbolGreek.find(n); + if (itgreek!=winSymbolGreek.end()) { + props.symbol = itgreek.value(); + //qDebug()<<"##SEARCHING "<") { props.symbol = ">"; props.bold = 0; } + else if (n == "|") { props.symbol = "|"; props.bold = 0; } + else if (n == "}") { props.symbol = "}"; } + else if (n == "{") { props.symbol = "{"; } + else if (n == "]") { props.symbol = "]"; } + else if (n == "[") { props.symbol = "["; } + else if (n == "(") { props.symbol = "("; } + else if (n == ")") { props.symbol = ")"; } + else if (n == "|") { props.symbol = "|"; } + else if (n == "$") { props.symbol = "$"; } + else if (n == "%") { props.symbol = "%"; } + else if (n == "&") { props.symbol = "&"; } + else if (n == "#") { props.symbol = "#"; } + else if (n == "ast") { props.symbol = "*"; } + else if (n == "dots") { props.symbol = "..."; } + else if (n == "ldots") { props.symbol = "..."; } + else if (n == "colon") { props.symbol = ":"; } + + else {return false;} + return true; +} + +bool JKQTMathTextSymbolNode::getUnicodeBaseSymbolProp(JKQTMathTextSymbolNode::SymbolProps& props, const QString &n) const +{ + + //qDebug()<<"--- getUnicodeBaseSymbolProp("< unicodeBaseSymbol; + if (unicodeBaseSymbol.isEmpty()) { + + unicodeBaseSymbol.insert("diamond", QChar(0xE0)); + unicodeBaseSymbol.insert("infty", QChar(0x221E)); + unicodeBaseSymbol.insert("partial", QChar(0x2202)); + unicodeBaseSymbol.insert("times", QChar(0x2A2F)); + unicodeBaseSymbol.insert("*", QChar(0x2217)); + unicodeBaseSymbol.insert("ast", QChar(0x2217)); + unicodeBaseSymbol.insert("asterisk", QChar(0x2217)); + unicodeBaseSymbol.insert("star", QChar(0x22C6)); + unicodeBaseSymbol.insert("bullet", QChar(0x2219)); + unicodeBaseSymbol.insert("copyright", QChar(0x00A9)); + unicodeBaseSymbol.insert("registered", QChar(0x00AE)); + unicodeBaseSymbol.insert("circledR", QChar(0x00AE)); + unicodeBaseSymbol.insert("trademark", QChar(0x2122)); + unicodeBaseSymbol.insert("textregistered", QChar(0x2122)); + unicodeBaseSymbol.insert("cdot", QChar(0x00B7)); + unicodeBaseSymbol.insert("pm", QChar(0x00B1)); + unicodeBaseSymbol.insert("leq", QChar(0x2264)); + unicodeBaseSymbol.insert("geq", QChar(0x2265)); + unicodeBaseSymbol.insert("le", QChar(0x2264)); + unicodeBaseSymbol.insert("ge", QChar(0x2265)); + unicodeBaseSymbol.insert("hbar", QChar(0x210F)); + unicodeBaseSymbol.insert("EUR", QChar(0x20AC)); + unicodeBaseSymbol.insert("euro", QChar(0x20AC)); + unicodeBaseSymbol.insert("circ", QChar(0x2218)); + unicodeBaseSymbol.insert("cent", QChar(0x00A2)); + unicodeBaseSymbol.insert("pound", QChar(0x00A3)); + unicodeBaseSymbol.insert("yen", QChar(0x00A5)); + unicodeBaseSymbol.insert("dollar", QChar(0x0024)); + unicodeBaseSymbol.insert("neq", QChar(0x2260)); + unicodeBaseSymbol.insert("lnot", QChar(0x2260)); + unicodeBaseSymbol.insert("Angstrom", QChar(0x00AC)); + unicodeBaseSymbol.insert("co", QChar(0x2105)); + unicodeBaseSymbol.insert("No", QChar(0x2116)); + unicodeBaseSymbol.insert("Ohm", QChar(0x2126)); + unicodeBaseSymbol.insert("ohm", QChar(0x2126)); + unicodeBaseSymbol.insert("tcohm", QChar(0x2126)); + unicodeBaseSymbol.insert("partial", QChar(0x2202)); + unicodeBaseSymbol.insert("cdots", QString(QChar(0x00B7)) + QString(QChar(0x00B7)) + QString(QChar(0x00B7))); + unicodeBaseSymbol.insert("approx", QChar(0x2248)); + unicodeBaseSymbol.insert("Angstroem", QChar(0x212B)); + unicodeBaseSymbol.insert("-", QChar(0x2212)); + unicodeBaseSymbol.insert("dots", QChar(0x2026)); + unicodeBaseSymbol.insert("ldots", QChar(0x2026)); + } + + QHash::iterator itbasesymbol = unicodeBaseSymbol.find(n); + if (itbasesymbol!=unicodeBaseSymbol.end()) { + props.symbol = itbasesymbol.value(); + //qDebug()<<"### found "< unicodeSymbol; + if (unicodeSymbol.isEmpty()) { + unicodeSymbol.insert("leftrightarrow", QChar(0x2194)); + unicodeSymbol.insert("leftarrow", QChar(0x2190)); + unicodeSymbol.insert("rightarrow", QChar(0x2192)); + unicodeSymbol.insert("to", QChar(0x2192)); + unicodeSymbol.insert("uparrow", QChar(0x2191)); + unicodeSymbol.insert("downarrow", QChar(0x2193)); + unicodeSymbol.insert("updownarrow", QChar(0x2195)); + unicodeSymbol.insert("Leftrightarrow", QChar(0x21D4)); + unicodeSymbol.insert("iff", QChar(0x21D4)); + unicodeSymbol.insert("Leftarrow", QChar(0x21D0)); + unicodeSymbol.insert("Rightarrow", QChar(0x21D2)); + unicodeSymbol.insert("Uparrow", QChar(0x21D1)); + unicodeSymbol.insert("Downarrow", QChar(0x21D3)); + unicodeSymbol.insert("Updownarrow", QChar(0x21D5)); + unicodeSymbol.insert("mp", QChar(0x2213)); + unicodeSymbol.insert("ll", QChar(0x226A)); + unicodeSymbol.insert("gg", QChar(0x226B)); + unicodeSymbol.insert("Alef", QChar(0x2135)); + unicodeSymbol.insert("Aleph", QChar(0x2135)); + unicodeSymbol.insert("Bet", QChar(0x2136)); + unicodeSymbol.insert("Beth", QChar(0x2136)); + unicodeSymbol.insert("Gimel", QChar(0x2137)); + unicodeSymbol.insert("Dalet", QChar(0x2138)); + unicodeSymbol.insert("alef", QChar(0x2135)); + unicodeSymbol.insert("aleph", QChar(0x2135)); + unicodeSymbol.insert("bet", QChar(0x2136)); + unicodeSymbol.insert("beth", QChar(0x2136)); + unicodeSymbol.insert("gimel", QChar(0x2137)); + unicodeSymbol.insert("dalet", QChar(0x2138)); + unicodeSymbol.insert("nexists", QChar(0x2204)); + unicodeSymbol.insert("ni", QChar(0x220B)); + unicodeSymbol.insert("notni", QChar(0x220C)); + unicodeSymbol.insert("tilde", QChar(0x223C)); + unicodeSymbol.insert("sim", QChar(0x223C)); + unicodeSymbol.insert("emptyset", QChar(0x2300)); + unicodeSymbol.insert("varnothing", QChar(0x2300)); + unicodeSymbol.insert("odot", QChar(0x2299)); + unicodeSymbol.insert("ominus", QChar(0x2296)); + unicodeSymbol.insert("lceil", QChar(0x2308)); + unicodeSymbol.insert("rceil", QChar(0x2309)); + unicodeSymbol.insert("lfloor", QChar(0x230A)); + unicodeSymbol.insert("rfloor", QChar(0x230B)); + unicodeSymbol.insert("subsetnot", QChar(0x2284)); + unicodeSymbol.insert("DC", QChar(0x2393)); + unicodeSymbol.insert("bot", QChar(0x22A4)); + unicodeSymbol.insert("perp", QChar(0x22A5)); + unicodeSymbol.insert("sqcap", QChar(0x2293)); + unicodeSymbol.insert("sqcup", QChar(0x2294)); + unicodeSymbol.insert("triangle", QChar(0x2206)); + unicodeSymbol.insert("square", QChar(0x25A1)); + unicodeSymbol.insert("setminus", QChar(0x2216)); + unicodeSymbol.insert("mid", QChar(0x2223)); + unicodeSymbol.insert("nmid", QChar(0x2224)); + unicodeSymbol.insert("vdots", QChar(0x22EE)); + unicodeSymbol.insert("iddots", QChar(0x22F0)); + unicodeSymbol.insert("ddots", QChar(0x22F1)); + unicodeSymbol.insert("perthousand", QChar(0x2030)); + unicodeSymbol.insert("leftharpoonup", QChar(0x21BC)); + unicodeSymbol.insert("rightharpoonup", QChar(0x21C0)); + unicodeSymbol.insert("upharpoonleft", QChar(0x21BF)); + unicodeSymbol.insert("downharpoonleft", QChar(0x21C3)); + unicodeSymbol.insert("leftrightharpoon", QChar(0x21CB)); + unicodeSymbol.insert("rightleftharpoon", QChar(0x21CC)); + unicodeSymbol.insert("leftharpoondown", QChar(0x21BD)); + unicodeSymbol.insert("rightharpoondown", QChar(0x21C1)); + unicodeSymbol.insert("upharpoonright", QChar(0x21BE)); + unicodeSymbol.insert("downharpoonright", QChar(0x21C2)); + unicodeSymbol.insert("nwarrow", QChar(0x2196)); + unicodeSymbol.insert("nearrow", QChar(0x2197)); + unicodeSymbol.insert("searrow", QChar(0x2198)); + unicodeSymbol.insert("swarrow", QChar(0x2199)); + unicodeSymbol.insert("mapsto", QChar(0x21A6)); + unicodeSymbol.insert("div", QChar(0x00F7)); + unicodeSymbol.insert("multimap", QChar(0x22B8)); + unicodeSymbol.insert("maporiginal", QChar(0x22B6)); + unicodeSymbol.insert("mapimage", QChar(0x22B7)); + unicodeSymbol.insert("benzene", QChar(0x232C)); + unicodeSymbol.insert("propto", QChar(0x221D)); + unicodeSymbol.insert("ne", QChar(0x2260)); + unicodeSymbol.insert("equiv", QChar(0x2261)); + unicodeSymbol.insert("ellipsis", QChar(0x2026)); + unicodeSymbol.insert("Im", QChar(0x2111)); + unicodeSymbol.insert("Re", QChar(0x211C)); + unicodeSymbol.insert("otimes", QChar(0x2297)); + unicodeSymbol.insert("oplus", QChar(0x2295)); + unicodeSymbol.insert("oslash", QChar(0x2298)); + unicodeSymbol.insert("cap", QChar(0x2229)); + unicodeSymbol.insert("land", QChar(0x2229)); + unicodeSymbol.insert("cup", QChar(0x222A)); + unicodeSymbol.insert("lor", QChar(0x222A)); + unicodeSymbol.insert("supset", QChar(0x2283)); + unicodeSymbol.insert("supseteq", QChar(0x2286)); + unicodeSymbol.insert("supsetnot", QChar(0x2285)); + unicodeSymbol.insert("subset", QChar(0x2282)); + unicodeSymbol.insert("subseteq", QChar(0x2286)); + unicodeSymbol.insert("in", QChar(0x2208)); + unicodeSymbol.insert("notin", QChar(0x2209)); + unicodeSymbol.insert("angle", QChar(0x2220)); + unicodeSymbol.insert("measuredangle", QChar(0x2221)); + unicodeSymbol.insert("sphericalangle", QChar(0x2222)); + unicodeSymbol.insert("rightangle", QChar(0x221F)); + unicodeSymbol.insert("nabla", QChar(0x2207)); + unicodeSymbol.insert("parallel", QChar(0x2225)); + unicodeSymbol.insert("nparallel", QChar(0x2226)); + unicodeSymbol.insert("neg", QChar(0x00AC)); + unicodeSymbol.insert("wedge", QChar(0x2227)); + unicodeSymbol.insert("vee", QChar(0x2228)); + unicodeSymbol.insert("langle", QChar(0x2329)); + unicodeSymbol.insert("rangle", QChar(0x232A)); + unicodeSymbol.insert("forall", QChar(0x2200)); + unicodeSymbol.insert("exists", QChar(0x2203)); + unicodeSymbol.insert("bot", QChar(0x22A5)); + unicodeSymbol.insert("geqq", QChar(0x2267)); + unicodeSymbol.insert("leqq", QChar(0x2266)); + unicodeSymbol.insert("prec", QChar(0x227A)); + unicodeSymbol.insert("succ", QChar(0x227B)); + unicodeSymbol.insert("vartriangleleft", QChar(0x22B2)); + unicodeSymbol.insert("cong", QChar(0x2245)); + unicodeSymbol.insert("simeq", QChar(0x2243)); + unicodeSymbol.insert("therefore", QChar(0x2234)); + unicodeSymbol.insert("because", QChar(0x2235)); + unicodeSymbol.insert("lightning", QChar(0x21AF)); + unicodeSymbol.insert("blacksquare", QChar(0x220E)); + unicodeSymbol.insert("Box", QChar(0x25A1)); + unicodeSymbol.insert("celsius", QChar(0x2103)); + unicodeSymbol.insert("AC", QChar(0x223F)); + unicodeSymbol.insert("frown", QChar(0x2322)); + unicodeSymbol.insert("smile", QChar(0x2323)); + unicodeSymbol.insert("smiley", QChar(0x233A)); + unicodeSymbol.insert("blacksmiley", QChar(0x233B)); + unicodeSymbol.insert("frownie", QChar(0x2639)); + unicodeSymbol.insert("varhexagonlrbonds", QChar(0x232C)); + unicodeSymbol.insert("hexagon", QChar(0x2394)); + unicodeSymbol.insert("varcarriagereturn", QChar(0x23CE)); + unicodeSymbol.insert("benzenr", QChar(0x23E3)); + unicodeSymbol.insert("trapezium", QChar(0x23E2)); + unicodeSymbol.insert("female", QChar(0x2640)); + unicodeSymbol.insert("male", QChar(0x2642)); + + unicodeSymbol.insert("accurrent", QChar(0x23E6)); + } + + QHash::iterator itsymbol = unicodeSymbol.find(n); + + if (itsymbol!=unicodeSymbol.end()) { + props.symbol = itsymbol.value(); + } + else if (n == "sum") { props.symbol = QChar(0x2211); props.heightIsAscent = true; props.exactAscent = true; } + else if (n == "prod") { props.symbol = QChar(0x220F); props.heightIsAscent = true; props.exactAscent = true; } + else if (n == "bbC") { props.symbol = QChar(0x2102); props.italic = -1; } + else if (n == "bbH") { props.symbol = QChar(0x210D); props.italic = -1; } + else if (n == "bbN") { props.symbol = QChar(0x2115); props.italic = -1; } + else if (n == "bbP") { props.symbol = QChar(0x2119); props.italic = -1; } + else if (n == "bbQ") { props.symbol = QChar(0x211A); props.italic = -1; } + else if (n == "bbR") { props.symbol = QChar(0x211D); props.italic = -1; } + else if (n == "bbZ") { props.symbol = QChar(0x2124); props.italic = -1; } + else if (n == "iint") { props.symbol = QChar(0x222C); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } + else if (n == "iiint") { props.symbol = QChar(0x222D); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } + else if (n == "oint") { props.symbol = QChar(0x222E); 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 == "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 == "int") { props.symbol = QChar(0x222B); props.fontFactor = mathFontFactor; /*yfactor=+0.1;*/ props.heightIsAscent = true; props.exactAscent = true; } + else {return false;} + return true; +} + +bool JKQTMathTextSymbolNode::getSymbolProp(JKQTMathTextSymbolNode::SymbolProps& props, const QString &n, const JKQTMathTextEnvironment& currentEv, double mathFontFactor) const +{ + auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Text); + auto fntGreek=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Greek); + auto fntSym=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Symbols); + + //qDebug()<<"--- getSymbolProp("<getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Text); + auto fntSym=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Symbols); + auto fntGreek=parent->getFontData(currentEv.font, currentEv.insideMath, JKQTMathText::FontSubclass::Greek); + + JKQTMathTextSymbolNode::SymbolProps props; + double mathFontFactor=1.8; + props.symbol=""; + props.fontFactor=1.0; + props.bold=0; + props.italic=-1; + props.yfactor=0; + props.drawBar=false; + props.font=fnt.first; + props.heightIsAscent=false; + props.exactAscent=false; + props.extendWidthInMathmode=false; + + QString n=symName; + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // statische Lookup-Tabellen vorbereiten + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + static QStringList extendWInMM; + if (extendWInMM.isEmpty()) { + extendWInMM <<"ll"<<"gg"<<"leq"<<"geq"<<"leftrightarrow"<<"leftarrow"<<"rightarrow"<<"to"<<"uparrow"<<"downarrow"<<"updownarrow"<<"Leftrightarrow" + <<"iff"<<"Leftarrow"<<"Rightarrow"<<"Uparrow"<<"Downarrow"<<"Updownarrow"<<"pm"<<"mp"<<"nexists"<<"ni"<<"notni"<<"circ"<<"sim"<<"emptyset"<<"odot"<<"ominus" + <<"subsetnot"<<"bot"<<"leftharpoonup"<<"rightharpoonup"<<"upharpoonleft"<<"downharpoonleft"<<"leftrightharpoon"<<"rightleftharpoon"<<"coprod"<<"leftharpoondown" + <<"rightharpoondown"<<"upharpoonright"<<"downharpoonright"<<"nwarrow"<<"nearrow"<<"searrow"<<"swarrow"<<"mapsto"<<"div"<<"multimap"<<"maporiginal"<<"mapimage" + <<"times"<<"propto"<<"bullet"<<"neq"<<"ne"<<"equiv"<<"approx"<<"otimes"<<"oplus"<<"oslash"<<"cap"<<"land"<<"cup"<<"lor"<<"supset"<<"supseteq"<<"supsetnot" + <<"subset"<<"subseteq"<<"in"<<"notin"<<"cdot"<<"wedge"<<"vee"<<"cong"<<"bot"<<"mid"<<"+"<<"-"<<"|"<<"*"<<"/"<<"<"<<">"; + } + + if (extendWInMM.contains(n)) { + props.extendWidthInMathmode=true; + } + + + static QHash simpleTranslations; + if (simpleTranslations.isEmpty()) { + simpleTranslations.insert("", " "); + simpleTranslations.insert("sin", "sin"); + simpleTranslations.insert("cos", "cos"); + simpleTranslations.insert("tan", "tan"); + simpleTranslations.insert("sinh", "sinh"); + simpleTranslations.insert("cosh", "cosh"); + simpleTranslations.insert("tanh", "tanh"); + simpleTranslations.insert("atan", "atan"); + simpleTranslations.insert("acos", "acos"); + simpleTranslations.insert("asin", "asin"); + simpleTranslations.insert("arcsin", "arcsin"); + simpleTranslations.insert("arccos", "arccos"); + simpleTranslations.insert("arctan", "arctan"); + simpleTranslations.insert("degree", QLatin1String("\xB0")); + simpleTranslations.insert("textdegree ", QLatin1String("\xB0")); + simpleTranslations.insert("ii", "i"); + simpleTranslations.insert("dd", "d"); + simpleTranslations.insert("exp", "exp"); + simpleTranslations.insert("log", "log"); + simpleTranslations.insert("ln", "ln"); + simpleTranslations.insert("ld", "ld"); + simpleTranslations.insert("lb", "lb"); + simpleTranslations.insert("argmin", "argmin"); + simpleTranslations.insert("argmax", "argmax"); + simpleTranslations.insert("max", "max"); + simpleTranslations.insert("mod", "mod"); + simpleTranslations.insert("min", "min"); + simpleTranslations.insert("median", "median"); + simpleTranslations.insert("sign", "sign"); + simpleTranslations.insert("sgn", "sgn"); + simpleTranslations.insert("sec", "sec"); + simpleTranslations.insert("gcd", "gcd"); + simpleTranslations.insert("hom", "hom"); + simpleTranslations.insert("ker", "ker"); + simpleTranslations.insert("dim", "dim"); + simpleTranslations.insert("cot", "cot"); + simpleTranslations.insert("arg", "arg"); + simpleTranslations.insert("det", "det"); + simpleTranslations.insert("deg", "deg"); + simpleTranslations.insert("Pr", "Pr"); + simpleTranslations.insert("coth", "coth"); + } + + + static QHash simpleTranslations_heightIsAscent; + if (simpleTranslations_heightIsAscent.isEmpty()) { + simpleTranslations_heightIsAscent.insert("erf", "erf"); + simpleTranslations_heightIsAscent.insert("median", "median"); + simpleTranslations_heightIsAscent.insert("min", "min"); + simpleTranslations_heightIsAscent.insert("max", "max"); + simpleTranslations_heightIsAscent.insert("inf", "inf"); + simpleTranslations_heightIsAscent.insert("sup", "sup"); + simpleTranslations_heightIsAscent.insert("liminf", "liminf"); + simpleTranslations_heightIsAscent.insert("limsup", "limsup"); + simpleTranslations_heightIsAscent.insert("lim", "lim"); + } + + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + props.font=fnt.first; + QString errorExplanation=""; + QHash::iterator itsimple = simpleTranslations.find(n); + if (itsimple!= simpleTranslations.end()) { + props.symbol=itsimple.value(); + } else { + QHash::iterator itsimplehia = simpleTranslations_heightIsAscent.find(n); + if (itsimplehia != simpleTranslations_heightIsAscent.end()) { + props.symbol = itsimplehia.value(); + props.heightIsAscent = true; + } else { + props.font=fnt.first; + if (!getSymbolProp(props, n, currentEv, mathFontFactor)) { + errorExplanation="didn't find symbol given font def:"+fnt.first+"["+JKQTMathTextFontEncoding2String(fnt.second)+"] / sym:"+fntSym.first+"["+JKQTMathTextFontEncoding2String(fntSym.second)+"] / grk:"+fntGreek.first+"["+JKQTMathTextFontEncoding2String(fntGreek.second)+"]"; + } + } + } + if (addWhitespace) props.symbol+=" "; + + static QSet extraSymbolName = { + "infty", + "|", " ", "quad", "qquad", "space", ";", ":", ",", "!","%" + "longleftarrow", "longrightarrow", + "Longleftarrow", "Longrightarrow", + "longleftrightarrow", "Longleftrightarrow" + }; + + + static QSet extraSymbolNonItalic = { + "+", "-", "*", "/", "<", ">", "=", "|", "{", "(", "[", "]", ")", "}", "\\" + }; + + if (props.symbol.simplified().isEmpty() && extraSymbolNonItalic.contains(n)) { + props.symbol=n; + if (n=="=") props.symbol="= "; + props.italic=-1; + } + + if (props.symbol.simplified().isEmpty() && !extraSymbolName.contains(n)) { + parent->addToErrorList(QObject::tr("unknown symbol '%1' found (%2)!").arg(n).arg(errorExplanation)); + } + + //qDebug()<0) f.setItalic(true); + if (props.bold<0) f.setBold(false); + if (props.bold>0) f.setBold(true); + QFontMetricsF fm(f, painter.device()); + QString symb=props.symbol; + width=0; + if (currentEv.insideMath) width=qMax(JKQTMathTextGetTightBoundingRect(f, symb, painter.device()).width(),JKQTMathTextGetTightBoundingRect(f, "i", painter.device()).width());//fm.width(symbol); + else width=fm.boundingRect(symb).width();//fm.width(symbol); + + width=qMax(fm.boundingRect("j").width(), width); + if (symb.isEmpty()) { + width=fm.boundingRect("a").width(); + if (symbolName=="|") width=fm.boundingRect("1").width()*0.8; + else if (symbolName=="infty") width=fm.boundingRect("M").width(); + else if (symbolName=="quad" || symbolName=="qquad") width=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).width(); + else if (symbolName==" " || symbolName=="space") width=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width(); + else if (symbolName==";") width=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width()*0.75; + else if (symbolName==":") width=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width()*0.5; + else if (symbolName==",") width=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width()*0.25; + else if (symbolName=="!") width=-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width()*0.25; + else if (symbolName=="longleftarrow") { width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="longrightarrow") { width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="Longleftarrow") { width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="Longrightarrow") { width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="longleftrightarrow") { width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + else if (symbolName=="Longleftrightarrow") { width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; } + } + QRectF tbr=JKQTMathTextGetTightBoundingRect(f, symb, painter.device()); + overallHeight=tbr.height();// fm.height(); + baselineHeight=tbr.height()-tbr.bottom(); + if (props.exactAscent) { + //baselineHeight=fm.ascent()*0.8; + } + if (props.heightIsAscent) { + overallHeight=baselineHeight*1.1; + } + if (props.exactAscent && props.heightIsAscent) { + //qDebug()<getMathoperatorWidthFactor(); + +} + +double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + doDrawBoxes(painter, x, y, currentEv); + double width=0; + double baselineHeight=0; + double overallHeight=0, strikeoutPos=0; + getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); + QPen pold=painter.pen(); + QFont fold=painter.font(); + QFont f=currentEv.getFont(parent); + QFont f1=f; + auto props=getSymbolProp(symbolName, currentEv); + f.setFamily(props.font); + f.setPointSizeF(f.pointSizeF()*props.fontFactor); + if (props.italic<0) f.setItalic(false); + if (props.italic>0) f.setItalic(true); + if (props.bold<0) f.setBold(false); + if (props.bold>0) f.setBold(true); + QFontMetricsF fm(f, painter.device()); + QFontMetricsF fm1(f1, painter.device()); + painter.setFont(f); + + double shift=0; + if (props.extendWidthInMathmode && currentEv.insideMath) { + double origwidth=width/parent->getMathoperatorWidthFactor(); + shift=0.5*(width-origwidth); + //width=width*parent->getMathoperatorWidthFactor(); + } + + //std::cout<<"symbol '"<0) painter.drawLine(l); + + // try to draw some often used special symbols, by synthesizing them from + // standard characters in the current drawing font + } else if (symbolName=="infty") { + //std::cout<<"draw infty\n"; + f1.setItalic(false); + painter.setFont(f1); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(x+shift+fm1.boundingRect("8").width()/3.0, y-fm1.xHeight()); + painter.rotate(90); + painter.drawText(QPointF(0,0), "8"); + + } else if (symbolName=="|") { + //std::cout<<"draw infty\n"; + f1.setItalic(false); + painter.setFont(f1); + + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(x+shift, y); + painter.drawText(QPointF(0,0), "|"); + painter.translate(fm1.boundingRect("8").width()/3.0, 0); + painter.drawText(QPointF(0,0), "|"); + + + // here are some spaces + } else if (symbolName==" ") { // full space (width of x) + } else if (symbolName=="space") { // full space (width of x) + } else if (symbolName=="qquad") { // full space(width of M) + } else if (symbolName=="quad") { // full space(width of M) + } else if (symbolName==";") { // 75% space + } else if (symbolName==":") { // 50% space + } else if (symbolName==",") { // 25% space + } else if (symbolName=="!") { // -25% space + } else if (symbolName=="longleftarrow") { + double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); + painter.drawPath(path); + } else if (symbolName=="longrightarrow"){ + double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); + painter.drawPath(path); + } else if (symbolName=="Longleftarrow") { + double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false); + painter.drawPath(path); + } else if (symbolName=="Longrightarrow") { + double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true); + painter.drawPath(path); + } else if (symbolName=="longleftrightarrow") { + double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=JKQTMathTextMakeArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); + painter.drawPath(path); + } else if (symbolName=="Longleftrightarrow") { + double width=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*3.0; + double dx=JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width()*0.25; + double ypos=y-JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()/2.0; + QPainterPath path=JKQTMathTextMakeDArrow(x+shift+dx, ypos, width, JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true); + painter.drawPath(path); + } else { // draw a box to indicate an unavailable symbol + QRectF tbr=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()); + painter.drawRect(QRectF(x+shift,y-tbr.height(), xwi, tbr.height()*0.8)); + } + painter.setPen(pold); + painter.setFont(fold); + return x+width; +} + +bool JKQTMathTextSymbolNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + bool ok=true; + QString s; + JKQTMathTextEnvironment ev=currentEv; + + static QMap entitylut; + if (entitylut.isEmpty()) { + entitylut.insert("sin", "sin"); + entitylut.insert("cos", "cos"); + entitylut.insert("tan", "tan"); + entitylut.insert("sinh", "sinh"); + entitylut.insert("cosh", "cosh"); + entitylut.insert("tanh", "tanh"); + entitylut.insert("atan", "atan"); + entitylut.insert("acos", "acos"); + entitylut.insert("asin", "asin"); + entitylut.insert("arcsin", "arcsin"); + entitylut.insert("arccos", "arccos"); + entitylut.insert("arctan", "arctan"); + entitylut.insert("ii", "i"); + entitylut.insert("dd", "d"); + entitylut.insert("exp", "exp"); + entitylut.insert("log", "log"); + entitylut.insert("ln", "ln"); + entitylut.insert("ld", "ld"); + entitylut.insert("lb", "lb"); + entitylut.insert("erf", "erf"); + entitylut.insert("mod", "mod"); + entitylut.insert("median", "median"); + entitylut.insert("min", "min"); + entitylut.insert("max", "max"); + entitylut.insert("argmin", "argmin"); + entitylut.insert("argmax", "argmax"); + entitylut.insert("inf", "inf"); + entitylut.insert("sup", "sup"); + entitylut.insert("liminf", "liminf"); + entitylut.insert("limsup", "limsup"); + entitylut.insert("lim", "lim"); + entitylut.insert("sec", "sec"); + entitylut.insert("gcd", "gcd"); + entitylut.insert("hom", "hom"); + entitylut.insert("ker", "ker"); + entitylut.insert("dim", "dim"); + entitylut.insert("cot", "cot"); + entitylut.insert("arg", "arg"); + entitylut.insert("det", "det"); + entitylut.insert("deg", "deg"); + entitylut.insert("sign", "sign"); + entitylut.insert("sgn", "sgn"); + entitylut.insert("Pr", "Pr"); + entitylut.insert("coth", "coth"); + entitylut.insert("alpha", "α"); + entitylut.insert("beta", "β"); + entitylut.insert("gamma", "γ"); + entitylut.insert("delta", "δ"); + entitylut.insert("epsilon", "ε"); + entitylut.insert("varepsilon", "ε"); + entitylut.insert("zeta", "ζ"); + entitylut.insert("eta", "η"); + entitylut.insert("theta", "θ"); + entitylut.insert("vartheta", "ϑ"); + entitylut.insert("iota", "ι"); + entitylut.insert("kappa", "κ"); + entitylut.insert("lambda", "λ"); + entitylut.insert("mu", "μ"); + entitylut.insert("nu", "ν"); + entitylut.insert("xi", "ξ"); + entitylut.insert("pi", "π"); + entitylut.insert("varpi", "ϖ"); + entitylut.insert("rho", "ρ"); + entitylut.insert("sigma", "σ"); + entitylut.insert("varsigma", "ς"); + entitylut.insert("tau", "τ"); + entitylut.insert("upsilon", "υ"); + entitylut.insert("phi", "φ"); + entitylut.insert("varphi", "φ"); + entitylut.insert("chi", "χ"); + entitylut.insert("psi", "ψ"); + entitylut.insert("omega", "ω"); + entitylut.insert("Gamma", "Γ"); + entitylut.insert("Delta", "Δ"); + entitylut.insert("Theta", "Θ"); + entitylut.insert("Lambda", "Λ"); + entitylut.insert("Omega", "Ω"); + entitylut.insert("Xi", "Ξ"); + entitylut.insert("Pi", "Π"); + entitylut.insert("Sigma", "Σ"); + entitylut.insert("Upsilon", "Υ"); + entitylut.insert("Phi", "Φ"); + entitylut.insert("Psi", "Ψ"); + entitylut.insert("leftrightarrow", "↔"); + entitylut.insert("leftarrow", "←"); + entitylut.insert("rightarrow", "→"); + entitylut.insert("to", "→"); + entitylut.insert("uparrow", "↑"); + entitylut.insert("downarrow", "↓"); + entitylut.insert("Leftrightarrow", "⇔"); + entitylut.insert("iff", "⇔"); + entitylut.insert("Leftarrow", "⇐"); + entitylut.insert("Rightarrow", "⇒"); + entitylut.insert("Uparrow", "⇑"); + entitylut.insert("Downarrow", "⇓"); + entitylut.insert("pm", "±"); + entitylut.insert("leq", "≤"); + entitylut.insert("geq", "≥"); + entitylut.insert("times", "×"); + entitylut.insert("propto", "∝"); + entitylut.insert("partial", "∂"); + entitylut.insert("bullet", "•"); + entitylut.insert("star", "⋆"); + entitylut.insert("ast", "∗"); + entitylut.insert("asterisk", "∗"); + entitylut.insert("neq", "≠"); + entitylut.insert("ne", "≠"); + entitylut.insert("equiv", "≡"); + entitylut.insert("approx", "≈"); + entitylut.insert("ellipsis", "..."); + entitylut.insert("Im", "ℑ"); + entitylut.insert("Re", "ℜ"); + entitylut.insert("otimes", "⊗"); + entitylut.insert("oplus", "⊕"); + entitylut.insert("oslash", "/"); + entitylut.insert("cap", "∩"); + entitylut.insert("cup", "∪"); + entitylut.insert("land", "∩"); + entitylut.insert("lor", "∪"); + entitylut.insert("supset", "⊃"); + entitylut.insert("supseteq", "⊇"); + entitylut.insert("supsetnot", "⊅"); + entitylut.insert("subset", "⊂"); + entitylut.insert("subseteq", "⊆"); + entitylut.insert("in", "∈"); + entitylut.insert("notin", "∉"); + entitylut.insert("angle", "∠"); + entitylut.insert("nabla", "∇"); + entitylut.insert("copyright", "©"); + entitylut.insert("registered", "®"); + entitylut.insert("trademark", "™"); + entitylut.insert("textregistered", "™"); + entitylut.insert("cdot", "⋅"); + entitylut.insert("neg", "¬"); + entitylut.insert("wedge", "∧"); + entitylut.insert("vee", "∨"); + entitylut.insert("diamond", "◊"); + entitylut.insert("langle", "⟨"); + entitylut.insert("rangle", "⟩"); + entitylut.insert("int", "∫"); + entitylut.insert("forall", "∀"); + entitylut.insert("exists", "∃"); + entitylut.insert("cong", "∼"); + entitylut.insert("bot", "⊥"); + + + entitylut.insert("ll", "<<"); + entitylut.insert("gg", ">>"); + entitylut.insert("bbC", "C"); + entitylut.insert("bbH", "H"); + entitylut.insert("bbN", "N"); + entitylut.insert("bbP", "P"); + entitylut.insert("bbQ", "Q"); + entitylut.insert("bbR", "R"); + entitylut.insert("bbZ", "Z"); + entitylut.insert("Alef", "ℵ"); + entitylut.insert("alef", "ℵ"); + entitylut.insert("tilde", "~"); + entitylut.insert("iint", "∫∫"); + entitylut.insert("iiint", "∫∫∫"); + entitylut.insert("emptyset", "∅"); + entitylut.insert("varnothing", "∅"); + entitylut.insert("lceil", "⌈"); + entitylut.insert("rceil", "⌉"); + entitylut.insert("lfloor", "⌊"); + entitylut.insert("rfloor", "⌋"); + entitylut.insert("subsetnot", "⊄"); + entitylut.insert("DC", "="); + entitylut.insert("cdots", "⋅⋅⋅"); + entitylut.insert("dots", "..."); + entitylut.insert("ldots", "..."); + + entitylut.insert("cent", "¢"); + + entitylut.insert("_", "_"); + entitylut.insert("}", "}"); + entitylut.insert("{", "{"); + entitylut.insert("hbar", "ℏ"); + entitylut.insert("euro", "€"); + entitylut.insert("pound", "£"); + entitylut.insert("yen", "¥"); + entitylut.insert("div", "÷"); + entitylut.insert("backslash", "\\"); + entitylut.insert("$", "$"); + entitylut.insert("%", "%"); + entitylut.insert("&", "&"); + entitylut.insert("#", "#"); + entitylut.insert("ast", "*"); + entitylut.insert("glq", "'"); + entitylut.insert("grq", "'"); + entitylut.insert("glqq", "\""); + entitylut.insert("grqq", "\""); + entitylut.insert("flq", "<"); + entitylut.insert("frq", ">"); + entitylut.insert("flqq", ""); + entitylut.insert("frqq", ""); + } + + + 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 ok=false; + + if (ok) html=html+ev.toHtmlStart(defaultEv)+s+ev.toHtmlAfter(defaultEv); + return ok; +} + +QString JKQTMathTextSymbolNode::getSymbolName() const { + return this->symbolName; +} + +QString JKQTMathTextSymbolNode::getSymbolfontName() const { + JKQTMathTextEnvironment currentEv; + auto props=getSymbolProp(symbolName, currentEv); + return props.font; +} + +bool JKQTMathTextSymbolNode::getAddWhitespace() const +{ + return addWhitespace; +} + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h new file mode 100644 index 0000000000..c5fbdf085a --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h @@ -0,0 +1,106 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTSYMBOLNODE_H +#define JKQTMATHTEXTSYMBOLNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode { + public: + explicit JKQTMathTextSymbolNode(JKQTMathText* parent, const QString& name, bool addWhitespace); + virtual ~JKQTMathTextSymbolNode() override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc symbolName */ + QString getSymbolName() const; + /** \brief get font name of the symbol */ + QString getSymbolfontName() const; + /** \copydoc addWhitespace */ + bool getAddWhitespace() const; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + + /** \brief this string will be sent to the drawText method with properly set fonts */ + QString symbolName; + /** \brief add a whitespace to the symbol? */ + bool addWhitespace; + struct SymbolProps { + /** \brief the symbol name supplied to the constructor */ + QString symbol; + /** \brief font to use for output */ + QString font; + /** \brief magnification factor for the font size */ + double fontFactor; + /** \brief 0: leave italic setting as is, >0: set italic, <0 set italic to false */ + char italic; + /** \brief 0: leave bold setting as is, >0: set bold, <0 set bold to false */ + char bold; + /** \brief this corrects the y position of a symbol: draws at y <- y+ height*yfactor) */ + double yfactor; + /** \brief indicates whether to draw a bar (like for \c \\hbar ) */ + bool drawBar; + bool heightIsAscent; + bool exactAscent; + bool extendWidthInMathmode; + }; + /** \brief retrieve the properties to render the given symbol \a symName in the current environment \a currentEv */ + SymbolProps getSymbolProp(const QString& symName, const JKQTMathTextEnvironment& currentEv) const; + /** \brief fill \a props for the symbol named \a n in the given environment \a currentEv and with the given \a mathFontFactor , returns \c true if the symbol can be drawn using Unicode font (or WinSymbol as Fallback)*/ + bool getSymbolProp(JKQTMathTextSymbolNode::SymbolProps &props, const QString &n, const JKQTMathTextEnvironment ¤tEv, double mathFontFactor) const; + /** \brief fill \a props for the greek letter symbol named \a n in the given environment \a currentEv and with the given \a mathFontFactor , returns \c true if the symbol can be drawn using Unicode font (or WinSymbol as Fallback) */ + bool getGreekSymbolProp(JKQTMathTextSymbolNode::SymbolProps &props, const QString &n, const JKQTMathTextEnvironment ¤tEv, double mathFontFactor) const; + /** \brief fill \a props for the symbol named \a n in the given environment \a currentEv and with the given \a mathFontFactor , returns \c true if the symbol can be drawn using WinSymbol font */ + bool getWinSymbolProp(JKQTMathTextSymbolNode::SymbolProps &props, const QString &n, const JKQTMathTextEnvironment ¤tEv, double mathFontFactor) const; + /** \brief fill \a props for the symbol named \a n , returns \c true if the symbol can be drawn using any font, does not alter the font name!!! */ + bool getStandardTextSymbolProp(JKQTMathTextSymbolNode::SymbolProps &props, const QString &n) const; + /** \brief fill \a props for the symbol named \a n , returns \c true if the symbol can be drawn using any unicode font, does not alter the font name!!! */ + bool getUnicodeBaseSymbolProp(JKQTMathTextSymbolNode::SymbolProps &props, const QString &n) const; + /** \brief fill \a props for the symbol named \a n , returns \c true if the symbol can be drawn using a full unicode font, does not alter the font name!!! */ + bool getUnicodeFullSymbolProp(JKQTMathTextSymbolNode::SymbolProps &props, const QString &n, double mathFontFactor) const; +}; + +#endif // JKQTMATHTEXTSYMBOLNODE_H + + + + + + + + + diff --git a/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp new file mode 100644 index 0000000000..237bb15d88 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp @@ -0,0 +1,264 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include "jkqtmathtext/jkqtmathtext.h" +#include "jkqtcommon/jkqtpcodestructuring.h" +#include "jkqtcommon/jkqtpstringtools.h" +#include +#include +#include +#include +#include +#include +#include + + +JKQTMathTextTextNode::JKQTMathTextTextNode(JKQTMathText* _parent, const QString& textIn, bool addWhitespace, bool stripInnerWhitepace): + JKQTMathTextNode(_parent) +{ + QString text=textIn; + + if (stripInnerWhitepace) { + text=""; + for (int i=0; itext=text; + // strip all whitespace from left + while (this->text.size()>1 && this->text[0].isSpace()) { + this->text=this->text.right(this->text.size()-1); + } + if (addWhitespace /*&& (this->text.size()>0)*/ && (!this->text[this->text.size()-1].isSpace())) this->text=this->text+" "; + //qDebug()<<"JKQTMathTextTextNode( text="< this->text="<text<<"]"; +} + +JKQTMathTextTextNode::~JKQTMathTextTextNode() = default; + +void JKQTMathTextTextNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { + QFont f=currentEv.getFont(parent); + if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" || + text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) || + text==QString(QChar(0x2309)) || text==QString(QChar(0x230A)) || text==QString(QChar(0x230B)))) { + f.setItalic(false); + //f.setFamily(parent->getFontData(currentEv.font, currentEv.insideMath, FontSubclass::Text).first); + } + QString txt=textTransform(text, currentEv, true); + QFontMetricsF fm(f, painter.device()); + QRectF br=fm.boundingRect(txt); + QRectF tbr=JKQTMathTextGetTightBoundingRect(f, txt, painter.device()); //fm.tightBoundingRect(txt); + if (txt=="|") { + br=fm.boundingRect("X"); + tbr=QRectF(0,0,fm.boundingRect("X").width(), fm.ascent());//fm.boundingRect("X"); + br.setWidth(0.7*br.width()); + } + width=br.width();//width(text); + + if (txt.size()>0) { + if (txt[0].isSpace() /*&& br.width()<=0*/) width=width+fm.boundingRect("I").width(); + if (txt.size()>1 && txt[txt.size()-1].isSpace() /*&& (fm.boundingRect("a ").width()==fm.boundingRect("a").width())*/) width=width+fm.boundingRect("I").width(); + } + + //qDebug()<<"text: "<" || + text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) || + text==QString(QChar(0x2309)) || text==QString(QChar(0x230A)) || text==QString(QChar(0x230B)))) { + f.setItalic(false); + } + + + if (onlyDigits && currentEv.insideMath) { + f.setItalic(false); + } + + painter.setFont(f); + + //qDebug()<<"JKQTMathTextTextNode: text="<isFontBlackboardSimulated()) { + QPainterPath path; + path.addText(QPointF(x+dx, y), f, txt); + painter.drawPath(path); + } else { + painter.drawText(QPointF(x+dx, y), txt);//.simplified()); + } + } else { + int i=0; + double xx=x+dx; + QFont ff=f; + QFontMetricsF fmff(ff, painter.device()); + ff.setItalic(false); + while (iisFontBlackboardSimulated()) { + QPainterPath path; + path.addText(QPointF(xx, y), ff, QString(txt[i])); + painter.drawPath(path); + } else { + painter.setFont(ff); + painter.drawText(QPointF(xx, y), QString(txt[i])); + } + xx=xx+fmff.boundingRect(txt[i]).width(); + } else { + if (currentEv.font==MTEblackboard && parent->isFontBlackboardSimulated()) { + QPainterPath path; + path.addText(QPointF(xx, y), f, QString(txt[i])); + painter.drawPath(path); + } else { + painter.setFont(f); + painter.drawText(QPointF(xx, y), QString(txt[i])); + } + xx=xx+fm.boundingRect(txt[i]).width(); + } + i++; + } + } + painter.setPen(pold); + painter.setFont(fold); + + return x+width; +} + +bool JKQTMathTextTextNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) { + html=html+currentEv.toHtmlStart(defaultEv)+text+currentEv.toHtmlAfter(defaultEv); + return true; +} + +QString JKQTMathTextTextNode::getText() const { + return this->text; +} + +QString JKQTMathTextTextNode::getTypeName() const +{ + return QLatin1String("JKQTMathTextTextNode(")+text+")"; +} + +QString JKQTMathTextTextNode::textTransform(const QString &text, JKQTMathTextEnvironment currentEv, bool /*forSize*/) +{ + QString txt=text; + auto fnt=parent->getFontData(currentEv.font, currentEv.insideMath); + if (fnt.second==MTFEunicode || fnt.second==MTFEunicodeLimited) { + if (currentEv.insideMath) { + txt=""; + for (int i=0; i': txt+=QString(QString(" >")); break; + case '=': txt+=QString(QString(" =")); break; + case ';': txt+=QString(QString("; ")); break; + case ',': txt+=QString(QString(", ")); break; + default: txt+=c; break; + } + } + txt=txt.replace(" ", " "); + } + } + + return txt; +} + + + +MTplainTextNode::MTplainTextNode(JKQTMathText *_parent, const QString& _text, bool addWhitespace, bool stripInnerWhitepace): + JKQTMathTextTextNode(_parent, _text, addWhitespace, stripInnerWhitepace) +{ + +} + +QString MTplainTextNode::getTypeName() const +{ + return QLatin1String("MTplainTextNode(")+text+")"; +} + + +QString MTplainTextNode::textTransform(const QString &_text, JKQTMathTextEnvironment /*currentEv*/, bool /*forSize*/) +{ + return _text; +} + + +JKQTMathTextWhitespaceNode::JKQTMathTextWhitespaceNode(JKQTMathText *_parent): + JKQTMathTextTextNode(_parent, " ", false, false) +{ + +} + +JKQTMathTextWhitespaceNode::~JKQTMathTextWhitespaceNode() += default; + +QString JKQTMathTextWhitespaceNode::getTypeName() const +{ + return QLatin1String("JKQTMathTextWhitespaceNode(")+text+")"; +} + +bool JKQTMathTextWhitespaceNode::toHtml(QString &html, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/) { + html=html+" "; + return true; +} diff --git a/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h new file mode 100644 index 0000000000..f0dd3b49c9 --- /dev/null +++ b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h @@ -0,0 +1,93 @@ +/* + Copyright (c) 2008-2022 Jan W. Krieger () + with contributions from: Razi Alavizadeh + + + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + +#ifndef JKQTMATHTEXTTEXTNODE_H +#define JKQTMATHTEXTTEXTNODE_H +#include "jkqtmathtext/jkqtmathtext_imexport.h" +#include "jkqtmathtext/jkqtmathtexttools.h" +#include "jkqtmathtext/nodes/jkqtmathtextnode.h" +#include + +class JKQTMathText; // forward +// JKQTMATHTEXT_LIB_EXPORT + + +/** \brief subclass representing one text node in the syntax tree + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextNode { + public: + explicit JKQTMathTextTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); + virtual ~JKQTMathTextTextNode() override; + /** \copydoc JKQTMathTextNode::draw() */ + virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; + /** \copydoc text */ + QString getText() const; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override ; + protected: + /** \copydoc JKQTMathTextNode::getSizeInternal() */ + virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; + /** \brief text-contents of the node */ + QString text; + /** \brief transforms the text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */ + virtual QString textTransform(const QString& text, JKQTMathTextEnvironment currentEv, bool forSize=false); +}; + +/** \brief subclass representing one text node in the syntax tree + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT MTplainTextNode: public JKQTMathTextTextNode { + public: + explicit MTplainTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + protected: + /** \copydoc JKQTMathTextTextNode::textTransform() */ + virtual QString textTransform(const QString& text, JKQTMathTextEnvironment currentEv, bool forSize=false) override; +}; +/** \brief subclass representing one whitepsace node in the syntax tree + * \ingroup jkqtmathtext_items + */ +class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextWhitespaceNode: public JKQTMathTextTextNode { + public: + explicit JKQTMathTextWhitespaceNode(JKQTMathText* parent); + virtual ~JKQTMathTextWhitespaceNode() override; + /** \copydoc JKQTMathTextNode::getTypeName() */ + virtual QString getTypeName() const override; + /** \copydoc JKQTMathTextNode::toHtml() */ + virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; +}; + +#endif // JKQTMATHTEXTTEXTNODE_H + + + + + + + + +