JKQTMathText: NEW: array/tabular-environments have limited support for formatting string like l|r|c and for \hline , \hdashline , \toprule , \midrule , \bottomrule
@ -184,12 +184,56 @@
|
||||
.
|
||||
|
||||
|
||||
\section JKQTMathTextSuppoertedLaTeXTabular Tabular Environments
|
||||
|
||||
\see Additional matrix-environments are listed in \ref
|
||||
|
||||
For text-mode tables, the \c tabular -environment is supported:
|
||||
- <code>$\\begin{tabular}{COLSPEC} a & b & ...\\\\ c & d & ...\\end{tabular}$</code>
|
||||
\c COLSPEC is a LaTeX column specifier, i.e. a sequence composed of these parts:
|
||||
- \c l : left-aligned column
|
||||
- \c c : centered column
|
||||
- \c r : right-aligned column
|
||||
- \c | : single line
|
||||
- \c || : double line
|
||||
- \c : : single dashed line
|
||||
- \c :: : double dashed line
|
||||
.
|
||||
.
|
||||
In all these environments, you can use the following instructions to draw lines above/below a row in the matrix:
|
||||
- \c \\hline or \c \\midrule: a single line
|
||||
- \c \\hline\\hline : a double line
|
||||
- \c \\toprule or \c \\bottomrule : a heavy line
|
||||
- \c \\hdashline : a single dashed line
|
||||
- \c \\hdashline\\hdashline : a double dashed line
|
||||
.
|
||||
|
||||
Here is an example:
|
||||
\code
|
||||
\begin{tabular}{:l|cr||}
|
||||
\hdashline
|
||||
a1--- & b1--- & c1---\\
|
||||
a2- & b2- & c2-\\
|
||||
\hline
|
||||
a3 & b3 & c3\\
|
||||
\hline\hline
|
||||
a4 & b4 & c4\\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\endcode
|
||||
|
||||
\image html jkqtmathtext/jkqtmathtext_tabular.png
|
||||
|
||||
|
||||
\section JKQTMathTextSuppoertedLaTeXMathSupport Supported Mathematical Constructs
|
||||
|
||||
\subsection JKQTMathTextSuppoertedLaTeXSubSuper Sub- and Superscript
|
||||
The standard LaTeX sub-/superscript instructions (i.e. \c text_{sub} or \c text^{super} ) are supported:
|
||||
- \c ^{...} \c _{...} : display the contents of braces in superscript/subscript \image html jkqtmathtext/jkqtmathtext_supersub.png
|
||||
<br>Special subscript/superscript typesetting applies, when the sub/super follows \c \\sum \c \\Prod ...: \image html jkqtmathtext/jkqtmathtext_specialsubsuper.png
|
||||
- <code>$\\substack[lrc]{...\\\\...}$</code> allows to e.g. subset several lines below a \c \\sum using \c \\sum\\limits_\\substack{a<5\\\\b<100}: \image html jkqtmathtext/jkqtmathtext_substack.png
|
||||
- \c \\limits , \c \\nolimits : Several special symbols, like \c \\sum , \c \\lim , ... cause sub-/superscripts to be positioned below/above the symbol, not besides it. This behaviour can be altered by using \c \\limits and \c \\nolimits : \image html jkqtmathtext/jkqtmathtext_limits.png
|
||||
|
||||
.
|
||||
|
||||
\subsection JKQTMathTextSuppoertedLaTeXBraces Braces/Parantheses ...
|
||||
@ -235,27 +279,47 @@
|
||||
.
|
||||
|
||||
\subsection JKQTMathTextSuppoertedLaTeXFrac Fraction Type Instructions
|
||||
Several Matrix/Array-typed LaTeX instructions are supported:
|
||||
Several fraction-typed LaTeX instructions are supported:
|
||||
- <code>$\\frac{...}{...}$</code> \image html jkqtmathtext/MTFMfrac.png
|
||||
- <code>$\\tfrac{...}{...}$</code> (70% smaller font) \image html jkqtmathtext/MTFMtfrac.png
|
||||
- <code>$\\dfrac{...}{...}$</code> \image html jkqtmathtext/MTFMdfrac.png
|
||||
- <code>$\\sfrac{...}{...}$</code> \image html jkqtmathtext/MTFMsfrac.png
|
||||
- <code>$\\stfrac{...}{...}$</code> (70% smaller font) \image html jkqtmathtext/MTFMstfrac.png
|
||||
- <code>$\\stackrel{...}{...}$ $\\binom{...}{...}$</code> \image html jkqtmathtext/jkqtmathtext_brace_stackrel.png
|
||||
.
|
||||
|
||||
\subsection JKQTMathTextSuppoertedLaTeXMatrix Matrix/Array Type Instructions
|
||||
Several Matrix/Array-typed LaTeX instructions are supported:
|
||||
Simple instructions are:
|
||||
- <code>$\\stackrel{...}{...}$ $\\binom{...}{...}$</code> \image html jkqtmathtext/jkqtmathtext_brace_stackrel.png
|
||||
.
|
||||
|
||||
Several Matrix/Array-typed LaTeX instructions are supported:
|
||||
- <code>$\\begin{cases} ... & ... \\\\ ... & ... \\end{cases}$</code> \image html jkqtmathtext/jkqtmathtext_brace_begincases.png
|
||||
- <code>$\\begin{array} a & b & ...\\\\ c & d & ...\\end{array}$</code> <code>$\\begin{matrix} a & b & ...\\\\ c & d & ...\\end{matrix}$</code> \image html jkqtmathtext/jkqtmathtext_array.png
|
||||
- <code>$\\begin{matrix} a & b & ...\\\\ c & d & ...\\end{matrix}$</code> \image html jkqtmathtext/jkqtmathtext_matrix.png
|
||||
- <code>$\\begin{pmatrix} a & b & ...\\\\ c & d & ...\\end{pmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_pmatrix.png
|
||||
- <code>$\\begin{bmatrix} a & b & ...\\\\ c & d & ...\\end{bmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_bmatrix.png
|
||||
- <code>$\\begin{Bmatrix} a & b & ...\\\\ c & d & ...\\end{Bmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_bbmatrix.png
|
||||
- <code>$\\begin{vmatrix} a & b & ...\\\\ c & d & ...\\end{vmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_vmatrix.png
|
||||
- <code>$\\begin{Vmatrix} a & b & ...\\\\ c & d & ...\\end{Vmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_vvmatrix.png
|
||||
- <code>$\\substack[lrc]{...\\\\...}$</code> \image html jkqtmathtext/jkqtmathtext_substack.png
|
||||
- <code>$\\lsubstack{...\\\\...}$</code> \image html jkqtmathtext/jkqtmathtext_lsubstack.png
|
||||
- <code>$\\rsubstack{...\\\\...}$</code> \image html jkqtmathtext/jkqtmathtext_rsubstack.png
|
||||
- <code>$\\begin{array}{COLSPEC} a & b & ...\\\\ c & d & ...\\end{array}$</code> \image html jkqtmathtext/jkqtmathtext_array.png
|
||||
\c COLSPEC is a LaTeX column specifier, i.e. a sequence composed of these parts:
|
||||
- \c l : left-aligned column
|
||||
- \c c : centered column
|
||||
- \c r : right-aligned column
|
||||
- \c | : single line
|
||||
- \c || : double line
|
||||
- \c : : single dashed line
|
||||
- \c :: : double dashed line
|
||||
.
|
||||
.
|
||||
In all these environments, you can use the following instructions to draw lines above/below a row in the matrix:
|
||||
- \c \\hline or \c \\midrule: a single line
|
||||
- \c \\hline\\hline : a double line
|
||||
- \c \\toprule or \c \\bottomrule : a heavy line
|
||||
- \c \\hdashline : a single dashed line
|
||||
- \c \\hdashline\\hdashline : a double dashed line
|
||||
.
|
||||
|
||||
|
||||
|
@ -41,7 +41,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
|
||||
<li>JKQTMathText:<ul>
|
||||
<li>check sub/superscript with italic text in math mode, possibly a correction is necessary</li>
|
||||
<li>explore options to make font-environment-modifying commands avails, like "{blacktext\\color{red}redtext}", today only commands like "\\textcolor{red}{redtext}" work</li>
|
||||
<li>improve support for array-environment with limited support for formatting string like l|r|c and maybe add support for \\hline command, possibly also \\cellcolor etz.</li>
|
||||
<li></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
@ -89,6 +89,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>NEW: additional method JKQTMathtext::getSizeDetail() that returns all size-properties as a convenient struct, also added matching varinat JKQTMathTextNode::getSize() </li>
|
||||
<li>NEW: additional method JKQTMathtext::drawIntoPixmap(), JKQTMathtext::drawIntoPicture(), JKQTMathtext::drawIntoImage() which returns a QPixmap, QPicture and QImage respectively that contains the render result of the currently parsed markup</li>
|
||||
<li>NEW: added command line tool \ref JKQTMathTextRenderCmdLineTool that renders LaTeX into images, using it to generate the documentation images for JKQTMathText</li>
|
||||
<li>NEW: array/tabular-environments have limited support for formatting string like \c l|r|c and for \c \\hline , \c \\hdashline , \c \\toprule , \c \\midrule , \c \\bottomrule</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
|
Before Width: | Height: | Size: 995 B After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.9 KiB |
BIN
doc/images/jkqtmathtext/jkqtmathtext_limits.png
Normal file
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.7 KiB |
BIN
doc/images/jkqtmathtext/jkqtmathtext_matrix.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.cdr
Normal file
BIN
doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.png
Normal file
After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
doc/images/jkqtmathtext/jkqtmathtext_tabular.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
@ -84,7 +84,7 @@ jkqtmathtext_mathdeco.png
|
||||
$\vec{x}\ \dot{x}\ \ddot{x}\ \overline{x}\ \underline{x}\ \hat{x}\ \tilde{x}\ \uul{x}\ \ool{x}\ \bar{x}\ \arrow{x}\ \widehat{x}\ \widetilde{x}\ ...$
|
||||
---
|
||||
jkqtmathtext_textaccents.png
|
||||
\begin{array}
|
||||
\begin{array}{llll}
|
||||
{\backslash}"A: & \"A\"a & {\backslash}`A: & \`A\`a \\
|
||||
{\backslash}'A: & \'A\'a &{\backslash}{\circonflex}A: & \^A\^a \\
|
||||
{\backslash}{\sim}A: & \~A\~a &{\backslash}r\{A\}: & \r{A}\r{a} \\
|
||||
@ -96,7 +96,7 @@ jkqtmathtext_textaccents.png
|
||||
\end{array}
|
||||
---
|
||||
jkqtmathtext_mathaccents.png
|
||||
\begin{array}
|
||||
\begin{array}{llll}
|
||||
{\backslash}dot\{A\}: & $\dot{A}\dot{a}$ & {\backslash}ddot\{A\}: & $\ddot{A}\ddot{a}$ \\
|
||||
{\backslash}grave\{A\}: & $\grave{A}\grave{a}$ & {\backslash}acute\{A\}: & $\acute{A}\acute{a}$ \\
|
||||
{\backslash}acute\{A\}: & $\acute{A}\acute{a}$ & {\backslash}tilde\{A\}: & $\tilde{A}\tilde{a}$ \\
|
||||
|
@ -1,7 +1,4 @@
|
||||
---
|
||||
jkqtmathtext_brace_array.png
|
||||
$\left\langle\begin{array}a&b&...\\ c&d&...\end{array}\right\rangle$
|
||||
---
|
||||
jkqtmathtext_brace_bbig.png
|
||||
$\Bigl[\Bigl(r^{123}\Bigr)\Bigr]$
|
||||
---
|
||||
|
@ -28,8 +28,11 @@ jkqtmathtext_substack.png
|
||||
{\backslash}substack: $\sum\limits_\substack{0\leq i\leq10\\-5\leq j\leq1000}f_{i,j}$
|
||||
---
|
||||
jkqtmathtext_mathmode_and_textmode.png
|
||||
\begin{array}text: & abc123+d/e\\ math: & $abc123+d/e$\end{array}
|
||||
\begin{matrix}text: & abc123+d/e\\ math: & $abc123+d/e$\end{matrix}
|
||||
---
|
||||
jkqtmathtext_mathoperator_width_factor.png
|
||||
--showboxes
|
||||
\begin{array}Math: $a=b$ & text: a=b\\\textcolor{blue}{extra space}&\textcolor{blue}{normal spacing}\end{array}
|
||||
\begin{matrix}Math: $a=b$ & text: a=b\\\textcolor{blue}{extra space}&\textcolor{blue}{normal spacing}\end{matrix}
|
||||
---
|
||||
jkqtmathtext_limits.png
|
||||
no specifier: $\sum_{i=0}^\infty k_i^2\ \ \lim_{x\rightarrow0}f(x)\ \ \nabla_{x}f(x)$ \ \ \ \ \ {\backslash}limits: $\sum\limits_{i=0}^\infty k_i^2\ \ \lim\limits_{x\rightarrow0}f(x)\ \ \nabla\limits_{x}f(x)$ \ \ \ \ \ {\backslash}nolimits: $\sum\nolimits_{i=0}^\infty k_i^2\ \ \lim\nolimits_{x\rightarrow0}f(x)\ \ \nabla\nolimits_{x}f(x)$
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
jkqtmathtext_array.png
|
||||
$\begin{array}a&b&...\\ c&d&...\end{array}$
|
||||
jkqtmathtext_matrix.png
|
||||
$\mat{M}_1=\begin{matrix}a&b&...\\ c&d&...\end{matrix}\ \ \ \ \ \ \mat{M}_2=\left\langle\begin{matrix}a&b&...\\ c&d&...\end{matrix}\right\rangle$
|
||||
---
|
||||
jkqtmathtext_bmatrix.png
|
||||
$\begin{bmatrix}a&b&...\\ c&d&...\end{bmatrix}$
|
||||
@ -18,4 +18,30 @@ jkqtmathtext_vvmatrix.png
|
||||
$\begin{Vmatrix}a&b&...\\ c&d&...\end{Vmatrix}$
|
||||
---
|
||||
jkqtmathtext_brace_begincases.png
|
||||
$f(x)=\begin{cases}\sfrac{1}{2} & \text{if} 0\leq x\leq 1 \\ \sfrac{2}{3} & \text{if} 3\leq x\leq 4 \\ 0 & \text{elsewhere} \end{cases}$
|
||||
$f(x)=\begin{cases}\sfrac{1}{2} & \text{if}\ 0\leq x\leq 1 \\ \sfrac{2}{3} & \text{if}\ 3\leq x\leq 4 \\ 0 & \text{elsewhere} \end{cases}$
|
||||
---
|
||||
jkqtmathtext_tabular.png
|
||||
\begin{tabular}{:l|cr||}
|
||||
\hdashline
|
||||
a1--- & b1--- & c1---\\
|
||||
a2- & b2- & c2-\\
|
||||
\hline
|
||||
a3 & b3 & c3\\
|
||||
\hline\hline
|
||||
a4 & b4 & c4\\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
---
|
||||
jkqtmathtext_array.png
|
||||
$\mat{M}_\cdot=\begin{array}{l:ll}
|
||||
\alpha & a & \ldots \\
|
||||
\hdashline
|
||||
\beta & b & \ldots \\
|
||||
\vdots & \vdots & \ddots \\
|
||||
\end{array}
|
||||
\ \ \ \ \ \mat{M}_{()}=\left(\begin{array}{l:ll}
|
||||
\alpha & a & \ldots \\
|
||||
\hdashline
|
||||
\beta & b & \ldots \\
|
||||
\vdots & \vdots & \ddots \\
|
||||
\end{array}\right)$
|
||||
|
@ -97,6 +97,8 @@ TestForm::TestForm(QWidget *parent) :
|
||||
ui->cmbTestset->addItem("text: framed", "\\begin{framed}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{framed}");
|
||||
ui->cmbTestset->addItem("text: shaded", "\\begin{shaded}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{shaded}");
|
||||
ui->cmbTestset->addItem("text: snugshade", "\\begin{snugshade}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{snugshade}");
|
||||
ui->cmbTestset->addItem("text: tabular", "\\begin{tabular}{:l|cr||}\\hdashline a1--- & b1-- & c1---\\\\ a2-- & b2\\_ & c2\\_\\\\\\hline a3 & b3 & c3\\\\\\hline\\hline a4 & b4 & c4\\\\\\bottomrule\\end{tabular}");
|
||||
ui->cmbTestset->addItem("math: array", "$\\mat{M}=\\left(\\begin{array}{l:ll} \\alpha & a & \\ldots \\\\ \\hdashline \\beta & b & \\ldots \\\\ \\vdots & \\vdots & \\ddots \\\\ \\end{array}\\right)$");
|
||||
ui->cmbTestset->addItem("mathtest", "This is normal text: $this is math:\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle\\ \\ \\ g(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1} \\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\left\\{\\vec{a}\\left|\\|\\vec{a}\\|_2\\geq2\\right.\\right\\} \\vec{r}\\vec{R}\\frac{\\sqrt{\\sqrt{\\sqrt{\\sum_{i=0}^\\infty \\hat{i}^2}+y^\\alpha}+1}}{\\dot{v}\\equiv\\ddot{r}}\\argmin_{\\vec{k}}\\sum_{\\sqrt{i}=0}^{N}\\int_{x_0}^{x_1}\\left(\\left(\\left(x\\right)\\right)\\right)\\underbrace{\\left[\\left\\{\\frac{\\partial f}{\\partial x}\\right\\}\\cdot\\frac{1}{2}\\right]}{\\text{underbraced text \\hbar}}\\cdots\\frac{\\sqrt{\\sum_{i=0}^2 \\hat{i}^2}+y^\\alpha}{\\dot{v}\\equiv\\ddot{r}}, \\hat{t}\\hat{T} \\overbrace{\\left|\\sqrt{x\\cdot Y}\\right|}{\\propto\\bbN\\circ\\bbZ} \\left<\\arrow{x(\\tau)}\\cdot\\vec{R}(t+\\bar{\\tau})\\right> \\alpha\\beta\\gamma\\delta\\epsilon\\Gamma\\Delta\\Theta\\Omega \\left\\_\\left~\\cbrt{\\hbar\\omega}\\right~\\right\\_$");
|
||||
ui->cmbTestset->addItem("math: upper/lower parantheses test:", "$\\text{bblabla} \\frac{1}{2}\\cdot\\left(\\frac{1}{\\mathrm{e}^x+\\mathrm{e}^{-x}}\\right)\\cdot\\left(\\frac{1}{\\frac{1+2}{5+x}}\\right)\\cdot\\left(\\frac{1}{\\exp\\left[-\\frac{y^2}{\\sqrt{x}}\\right]\\cdot\\exp\\left[-\\frac{1}{\\frac{1}{2}}\\right]}\\right) $");
|
||||
ui->cmbTestset->addItem("math: ACF test", "$g_{rg}^{ab}(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-\\frac{1}{2}}$");
|
||||
|
@ -99,6 +99,14 @@ JKQTMathText::JKQTMathText(QObject* parent):
|
||||
sqrt_height_factor=1.2;
|
||||
sqrt_smallfont_factor=0.57;
|
||||
|
||||
matrix_linewidth_thin_factor=0.4;
|
||||
matrix_linewidth_heavy_factor=1.5;
|
||||
matrix_line_separation_factor=2.0;
|
||||
matrix_xSeparation_factor=0.5;
|
||||
matrix_ySeparation_factor=0.5;
|
||||
matrix_xPadding_factor=0.5;
|
||||
matrix_yPadding_factor=0.5;
|
||||
|
||||
blackboradFontMode=MTBBDMdefault;
|
||||
|
||||
|
||||
@ -231,6 +239,13 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group)
|
||||
bigmathoperator_font_factor=settings.value(group+"bigmathoperator_font_factor", bigmathoperator_font_factor).toDouble();
|
||||
frac_nested_factor=settings.value(group+"frac_nested_factor", frac_nested_factor).toDouble();
|
||||
|
||||
matrix_linewidth_thin_factor=settings.value(group+"matrix_linewidth_thin_factor", matrix_linewidth_thin_factor).toDouble();
|
||||
matrix_linewidth_heavy_factor=settings.value(group+"matrix_linewidth_heavy_factor", matrix_linewidth_heavy_factor).toDouble();
|
||||
matrix_line_separation_factor=settings.value(group+"matrix_line_separation_factor", matrix_line_separation_factor).toDouble();
|
||||
matrix_xSeparation_factor=settings.value(group+"matrix_xSeparation_factor", matrix_xSeparation_factor).toDouble();
|
||||
matrix_ySeparation_factor=settings.value(group+"matrix_ySeparation_factor", matrix_ySeparation_factor).toDouble();
|
||||
matrix_xPadding_factor=settings.value(group+"matrix_xPadding_factor", matrix_xPadding_factor).toDouble();
|
||||
matrix_yPadding_factor=settings.value(group+"matrix_yPadding_factor", matrix_yPadding_factor).toDouble();
|
||||
|
||||
if (settings.value(group+"use_stix_fonts", false).toBool()) useSTIX();
|
||||
if (settings.value(group+"use_xits_fonts", false).toBool()) useXITS();
|
||||
@ -272,6 +287,13 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const
|
||||
settings.setValue(group+ "sqrt_smallfont_factor", sqrt_smallfont_factor);
|
||||
settings.setValue(group+ "bigmathoperator_font_factor", bigmathoperator_font_factor);
|
||||
settings.setValue(group+ "frac_nested_factor", frac_nested_factor);
|
||||
settings.setValue(group+ "matrix_linewidth_thin_factor", matrix_linewidth_thin_factor);
|
||||
settings.setValue(group+ "matrix_linewidth_heavy_factor", matrix_linewidth_heavy_factor);
|
||||
settings.setValue(group+ "matrix_line_separation_factor", matrix_line_separation_factor);
|
||||
settings.setValue(group+ "matrix_xSeparation_factor", matrix_xSeparation_factor);
|
||||
settings.setValue(group+ "matrix_ySeparation_factor", matrix_ySeparation_factor);
|
||||
settings.setValue(group+ "matrix_xPadding_factor", matrix_xPadding_factor);
|
||||
settings.setValue(group+ "matrix_yPadding_factor", matrix_yPadding_factor);
|
||||
}
|
||||
|
||||
bool JKQTMathText::useSTIX(bool mathModeOnly) {
|
||||
@ -966,6 +988,76 @@ double JKQTMathText::getSqrtSmallFontFactor() const
|
||||
return sqrt_smallfont_factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixLinewidthThinFactor()
|
||||
{
|
||||
return matrix_linewidth_thin_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixLinewidthThinFactor(double factor)
|
||||
{
|
||||
matrix_linewidth_thin_factor=factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixLinewidthHeavyFactor()
|
||||
{
|
||||
return matrix_linewidth_heavy_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixLinewidthHeavyFactor(double factor)
|
||||
{
|
||||
matrix_linewidth_heavy_factor=factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixLineSeparationFactor()
|
||||
{
|
||||
return matrix_line_separation_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixLineSeparationFactor(double factor)
|
||||
{
|
||||
matrix_line_separation_factor=factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixXSeparationFactor()
|
||||
{
|
||||
return matrix_xSeparation_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixXSeparationFactor(double factor)
|
||||
{
|
||||
matrix_xSeparation_factor=factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixYSeparationFactor()
|
||||
{
|
||||
return matrix_ySeparation_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixYSeparationFactor(double factor)
|
||||
{
|
||||
matrix_ySeparation_factor=factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixXPaddingFactor()
|
||||
{
|
||||
return matrix_xPadding_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixXPaddingFactor(double factor)
|
||||
{
|
||||
matrix_xPadding_factor=factor;
|
||||
}
|
||||
|
||||
double JKQTMathText::getMatrixYPaddingFactor()
|
||||
{
|
||||
return matrix_yPadding_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setMatrixYPaddingFactor(double factor)
|
||||
{
|
||||
matrix_yPadding_factor=factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setUseUnparsed(bool __value)
|
||||
{
|
||||
this->useUnparsed = __value;
|
||||
@ -1531,6 +1623,7 @@ void JKQTMathText::giveBackToTokenizer(size_t count)
|
||||
}
|
||||
|
||||
JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace, const QString& quitOnEnvironmentEnd, bool quitOnClosingBracket) {
|
||||
QMap<QString,size_t> countLine;
|
||||
//std::cout<<" entering parseLatexString()\n";
|
||||
JKQTMathTextHorizontalListNode* nl=new JKQTMathTextHorizontalListNode(this);
|
||||
if (get) getToken();
|
||||
@ -1593,6 +1686,12 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
|
||||
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
|
||||
} else if (currentInstructionName=="nolimits") {
|
||||
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
|
||||
} else if (currentInstructionName=="hline" || currentInstructionName=="midrule") {
|
||||
countLine["hline"]=countLine.value("hline",0)+1;
|
||||
} else if (currentInstructionName=="hdashline") {
|
||||
countLine["hdashline"]=countLine.value("hdashline",0)+1;
|
||||
} else if (currentInstructionName=="toprule" || currentInstructionName=="bottomrule") {
|
||||
countLine["heavyline"]=countLine.value("heavyline",0)+1;
|
||||
} else if (currentInstructionName=="right") {
|
||||
getToken();
|
||||
if (currentToken==MTTtext) {
|
||||
@ -1717,34 +1816,89 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
|
||||
|
||||
} else if (currentToken==MTTinstructionBegin) {
|
||||
const QString envname=currentTokenName;
|
||||
if (envname=="matrix" || envname=="array" || envname=="aligned" || envname=="align" || envname=="cases" || envname=="pmatrix"|| envname=="bmatrix"|| envname=="Bmatrix"|| envname=="vmatrix"|| envname=="Vmatrix") {
|
||||
if (envname=="matrix" || envname=="array" || envname=="aligned" || envname=="align" || envname=="cases" || envname=="pmatrix"|| envname=="bmatrix"|| envname=="Bmatrix"|| envname=="vmatrix"|| envname=="Vmatrix" || envname=="tabular") {
|
||||
QString colspec="";
|
||||
if (envname=="tabular" || envname=="array") {
|
||||
if (getToken()==MTTopenbrace) {
|
||||
colspec=readUntil(true, "}");
|
||||
} else {
|
||||
error_list.append(tr("error @ ch. %1: expected {COLUMNSPEC} after '\\begin{%2}'").arg(currentTokenID).arg(envname));
|
||||
}
|
||||
}
|
||||
JKQTMathTextMatrixNode* matrixNode=new JKQTMathTextMatrixNode(this, colspec);
|
||||
QVector< QVector<JKQTMathTextNode*> > items;
|
||||
//int lines=0;
|
||||
//int cols=0;
|
||||
bool first=true;
|
||||
bool firstLine=true;
|
||||
QVector<JKQTMathTextNode*> line;
|
||||
size_t colCount=0;
|
||||
//std::cout<<"found \\begin{matrix}\n";
|
||||
while (first || currentToken==MTTampersand || currentToken==MTTinstructionNewline) {
|
||||
JKQTMathTextNode* it=parseLatexString(true, MTBTAny, envname);
|
||||
while (getToken()==MTTwhitespace) ; // eat whitespace
|
||||
JKQTMathTextNode* it=simplifyAndTrimJKQTMathTextNode(parseLatexString(false, MTBTAny, envname));
|
||||
if (firstLine) {
|
||||
if (lastLineCount.value("hline",0)==1) {
|
||||
matrixNode->setTopLine(JKQTMathTextMatrixNode::LTline);
|
||||
} else if (lastLineCount.value("hline",0)>1) {
|
||||
matrixNode->setTopLine(JKQTMathTextMatrixNode::LTdoubleline);
|
||||
} else if (lastLineCount.value("heavyline",0)>0) {
|
||||
matrixNode->setTopLine(JKQTMathTextMatrixNode::LTheavyline);
|
||||
} else if (lastLineCount.value("hdashline",0)==1) {
|
||||
matrixNode->setTopLine(JKQTMathTextMatrixNode::LTdashed);
|
||||
} else if (lastLineCount.value("hdashline",0)>1) {
|
||||
matrixNode->setTopLine(JKQTMathTextMatrixNode::LTdoubleDashed);
|
||||
}
|
||||
} else {
|
||||
if (lastLineCount.value("hline",0)==1) {
|
||||
matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTline);
|
||||
} else if (lastLineCount.value("hline",0)>1) {
|
||||
matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTdoubleline);
|
||||
} else if (lastLineCount.value("heavyline",0)>0) {
|
||||
matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTheavyline);
|
||||
} else if (lastLineCount.value("hdashline",0)==1) {
|
||||
matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTdashed);
|
||||
} else if (lastLineCount.value("hdashline",0)>1) {
|
||||
matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTdoubleDashed);
|
||||
}
|
||||
}
|
||||
if (currentToken==MTTampersand) {
|
||||
//std::cout<<" appending item\n";
|
||||
line.append(it);
|
||||
} else {
|
||||
line.append(it);
|
||||
//std::cout<<" appending item and line with "<<line.size()<<" items.\n";
|
||||
if (currentToken==MTTinstructionEnd) {
|
||||
JKQTMathTextMultiChildNode* mnc=dynamic_cast<JKQTMathTextMultiChildNode*>(it);
|
||||
if (mnc && mnc->childCount()>0) {
|
||||
line.append(it);
|
||||
} else {
|
||||
line.append(it);
|
||||
}
|
||||
} else {
|
||||
line.append(it);
|
||||
}
|
||||
if (currentToken==MTTinstructionNewline || line.size()>0) {
|
||||
colCount=qMax(colCount, static_cast<size_t>(line.size()));
|
||||
if (line.size()==0 || (line.size()>1 && line.size()==colCount)) {
|
||||
items.append(line);
|
||||
} else if (line.size()>1 && line.size()!=colCount) {
|
||||
error_list.append(tr("error @ ch. %1: wrong number of entries widthin '\\begin{%2}...\\end{%2}'").arg(currentTokenID).arg(envname));
|
||||
}
|
||||
}
|
||||
line.clear();
|
||||
firstLine=false;
|
||||
}
|
||||
first=false;
|
||||
}
|
||||
//std::cout<<" creating matrix-node with "<<items.size()<<" items.\n";
|
||||
if (envname=="pmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTParenthesis, MTBTParenthesis, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="cases") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTNone, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="Bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTCurlyBracket, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSingleLine, MTBTSingleLine, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="Vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTDoubleLine, MTBTDoubleLine, new JKQTMathTextMatrixNode(this, items)));
|
||||
else nl->addChild(new JKQTMathTextMatrixNode(this, items));
|
||||
matrixNode->setChildren(items);
|
||||
if (envname=="pmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTParenthesis, MTBTParenthesis, matrixNode));
|
||||
else if (envname=="cases") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTNone, matrixNode));
|
||||
else if (envname=="bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, matrixNode));
|
||||
else if (envname=="Bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTCurlyBracket, matrixNode));
|
||||
else if (envname=="vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSingleLine, MTBTSingleLine, matrixNode));
|
||||
else if (envname=="Vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTDoubleLine, MTBTDoubleLine, matrixNode));
|
||||
else nl->addChild(matrixNode);
|
||||
//std::cout<<" creating matrix-node ... done!\n";
|
||||
} else if (envname=="center" || envname=="document" || envname=="flushleft" || envname=="flushright") {
|
||||
JKQTMathTextHorizontalAlignment alignment=MTHALeft;
|
||||
@ -1795,6 +1949,8 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
|
||||
if (getNew) getToken();
|
||||
}
|
||||
//std::cout<<" leaving parseLatexString()\n";
|
||||
lastLineCount=countLine;
|
||||
|
||||
return simplifyJKQTMathTextNode(nl);
|
||||
}
|
||||
|
||||
@ -2126,6 +2282,8 @@ bool JKQTMathText::parse(const QString& text, bool addSpaceBeforeAndAfter){
|
||||
currentToken=MTTnone;
|
||||
currentTokenName="";
|
||||
parsingMathEnvironment=false;
|
||||
lastLineCount.clear();
|
||||
|
||||
error_list.clear();
|
||||
parsedNode=parseLatexString(true);
|
||||
unparsedNode=new JKQTMathTextVerbatimNode(this, text);
|
||||
|
@ -606,6 +606,35 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
/** \copydoc sqrt_smallfont_factor */
|
||||
double getSqrtSmallFontFactor() const;
|
||||
|
||||
/** \copydoc matrix_linewidth_thin_factor */
|
||||
double getMatrixLinewidthThinFactor();
|
||||
/** \copydoc matrix_linewidth_thin_factor */
|
||||
void setMatrixLinewidthThinFactor(double factor);
|
||||
/** \copydoc matrix_linewidth_heavy_factor */
|
||||
double getMatrixLinewidthHeavyFactor();
|
||||
/** \copydoc matrix_linewidth_heavy_factor */
|
||||
void setMatrixLinewidthHeavyFactor(double factor);
|
||||
/** \copydoc matrix_line_separation_factor */
|
||||
double getMatrixLineSeparationFactor();
|
||||
/** \copydoc matrix_line_separation_factor */
|
||||
void setMatrixLineSeparationFactor(double factor);
|
||||
/** \copydoc matrix_xSeparation_factor */
|
||||
double getMatrixXSeparationFactor();
|
||||
/** \copydoc matrix_xSeparation_factor */
|
||||
void setMatrixXSeparationFactor(double factor);
|
||||
/** \copydoc matrix_ySeparation_factor */
|
||||
double getMatrixYSeparationFactor();
|
||||
/** \copydoc matrix_ySeparation_factor */
|
||||
void setMatrixYSeparationFactor(double factor);
|
||||
/** \copydoc matrix_xPadding_factor */
|
||||
double getMatrixXPaddingFactor();
|
||||
/** \copydoc matrix_xPadding_factor */
|
||||
void setMatrixXPaddingFactor(double factor);
|
||||
/** \copydoc matrix_yPadding_factor */
|
||||
double getMatrixYPaddingFactor();
|
||||
/** \copydoc matrix_yPadding_factor */
|
||||
void setMatrixYPaddingFactor(double factor);
|
||||
|
||||
|
||||
|
||||
/** \copydoc useUnparsed */
|
||||
@ -798,6 +827,43 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
double sqrt_width_Xfactor;
|
||||
/** \brief height-increase of the sqrt-symbol, as factor of the child's height */
|
||||
double sqrt_height_factor;
|
||||
|
||||
/** \brief width of thin table lines, this factor is multiplied with the current \c font.linewidth()
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_linewidth_thin_factor;
|
||||
/** \brief width of heavy table lines, this factor is multiplied with the current \c font.linewidth()
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_linewidth_heavy_factor;
|
||||
/** \brief separation of double-lines in tables, this factor is multiplied with the \c font.linewidth()
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_line_separation_factor;
|
||||
/** \brief x-separation of two columns, this factor is multiplied with the \c font.width("x")
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_xSeparation_factor;
|
||||
/** \brief y-separation of two columns, this factor is multiplied with the \c font.width("x")
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_ySeparation_factor;
|
||||
/** \brief x-padding of two columns, this factor is multiplied with the \c font.width("x")
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_xPadding_factor;
|
||||
/** \brief y-padding of two columns, this factor is multiplied with the \c font.width("x")
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*/
|
||||
double matrix_yPadding_factor;
|
||||
|
||||
/** \brief a list that will be filled with error messages while parsing, if any error occur
|
||||
*
|
||||
* This list of errors is (mostly) filled during a call to parse(). During rendering (e.g. with draw() )
|
||||
@ -891,6 +957,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
tokenType currentToken;
|
||||
/** \brief the JKQTMathTextBraceType associated with the last \c \\right command the parser encountered */
|
||||
JKQTMathTextBraceType lastRightBraceType;
|
||||
/** \brief returns the number of \c \\hline , \c \\hdashline , ... commands in the last parseLatexString() call */
|
||||
QMap<QString,size_t> lastLineCount;
|
||||
/** \brief used by the tokenizer. Name of the current token, id applicable */
|
||||
QString currentTokenName;
|
||||
/** \brief used by the tokenizer. Points to the currently read character in parseString */
|
||||
|
@ -553,6 +553,14 @@ void JKQTMathTextHorizontalListNode::clearChildren(bool deleteChildren)
|
||||
clearChildrenImpl(deleteChildren);
|
||||
}
|
||||
|
||||
void JKQTMathTextHorizontalListNode::deleteChild(int i)
|
||||
{
|
||||
if (i>=0 && i<nodes.size()) {
|
||||
delete nodes[i];
|
||||
nodes.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
JKQTMathTextNode *JKQTMathTextHorizontalListNode::getChild(int i)
|
||||
{
|
||||
return nodes[i];
|
||||
@ -748,6 +756,13 @@ void JKQTMathTextVerticalListNode::clearChildrenImpl(bool deleteChildren)
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
void JKQTMathTextVerticalListNode::deleteChild(int i)
|
||||
{
|
||||
if (i>=0 && i<nodes.size()) {
|
||||
delete nodes[i];
|
||||
nodes.remove(i);
|
||||
}
|
||||
}
|
||||
void JKQTMathTextVerticalListNode::clearChildren(bool deleteChildren)
|
||||
{
|
||||
clearChildrenImpl(deleteChildren);
|
||||
|
@ -60,6 +60,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextHorizontalListNode: public JKQTMathTex
|
||||
virtual int childCount() const override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::clearChildren() */
|
||||
virtual void clearChildren(bool deleteChildren=true) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
|
||||
virtual void deleteChild(int i) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual JKQTMathTextNode* getChild(int i) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
@ -122,6 +124,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextVerticalListNode: public JKQTMathTextM
|
||||
virtual int childCount() const override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::clearChildren() */
|
||||
virtual void clearChildren(bool deleteChildren=true) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
|
||||
virtual void deleteChild(int i) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual JKQTMathTextNode* getChild(int i) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
|
@ -38,8 +38,41 @@
|
||||
|
||||
|
||||
|
||||
JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, QVector<QVector<JKQTMathTextNode*> > children):
|
||||
JKQTMathTextNode(_parent)
|
||||
JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, const QVector<QVector<JKQTMathTextNode *> > &children, const QString &columnSpec):
|
||||
JKQTMathTextNode(_parent),
|
||||
verticalLineRHSColumn(),
|
||||
verticalLineLeft(LTnone),
|
||||
horizontalLineBottomRow(),
|
||||
horizontalLineTop(LTnone),
|
||||
columns(0),
|
||||
lines(0)
|
||||
{
|
||||
setChildren(children);
|
||||
parseColumnSpec(columnSpec);
|
||||
}
|
||||
|
||||
JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText *_parent, const QString &columnSpec):
|
||||
JKQTMathTextNode(_parent),
|
||||
verticalLineRHSColumn(),
|
||||
verticalLineLeft(LTnone),
|
||||
horizontalLineBottomRow(),
|
||||
horizontalLineTop(LTnone),
|
||||
columns(0),
|
||||
lines(0)
|
||||
{
|
||||
parseColumnSpec(columnSpec);
|
||||
}
|
||||
|
||||
JKQTMathTextMatrixNode::~JKQTMathTextMatrixNode() {
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
delete children[i].at(j);
|
||||
}
|
||||
}
|
||||
children.clear();
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::setChildren(const QVector<QVector<JKQTMathTextNode *> > &children)
|
||||
{
|
||||
this->lines=children.size();
|
||||
this->columns=0;
|
||||
@ -54,13 +87,14 @@ JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, QVector<QV
|
||||
}
|
||||
}
|
||||
|
||||
JKQTMathTextMatrixNode::~JKQTMathTextMatrixNode() {
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
delete children[i].at(j);
|
||||
}
|
||||
}
|
||||
children.clear();
|
||||
void JKQTMathTextMatrixNode::setRowBottomLine(int col, LineType line)
|
||||
{
|
||||
horizontalLineBottomRow[col]=line;
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::setTopLine(LineType line)
|
||||
{
|
||||
horizontalLineTop=line;
|
||||
}
|
||||
|
||||
QString JKQTMathTextMatrixNode::getTypeName() const
|
||||
@ -68,108 +102,6 @@ QString JKQTMathTextMatrixNode::getTypeName() const
|
||||
return "MTmatrixNode";
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
||||
JKQTMathTextEnvironment ev1=currentEv;
|
||||
|
||||
double xh=fm.strikeOutPos();//fm.xHeight();
|
||||
//double Ah=fm.ascent();
|
||||
double xw=fm.boundingRect("x").width();
|
||||
|
||||
//ev1.fontSize=ev1.fontSize*parent->getFracFactor();
|
||||
|
||||
|
||||
QVector<double> colwidth, rowheight;
|
||||
//QVector<QVector<double> > widths, heights, baselines;
|
||||
|
||||
double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos1=0;
|
||||
//widths.resize(lines);
|
||||
colwidth.resize(columns); for (int i=0; i<columns; i++) colwidth[i]=0;
|
||||
rowheight.resize(lines);
|
||||
//heights=baselines=widths;
|
||||
for (int i=0; i<lines; i++) {
|
||||
rowheight[i]=0;
|
||||
//widths[i].resize(columns);
|
||||
//baselines[i]=heights[i]=widths[i];
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
children[i].at(j)->getSize(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; i<columns; i++) width=width+colwidth[i];
|
||||
for (int i=0; i<lines; i++) overallHeight=overallHeight+rowheight[i];
|
||||
baselineHeight=overallHeight/2.0+xh;
|
||||
strikeoutPos=xh;
|
||||
}
|
||||
|
||||
double JKQTMathTextMatrixNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
doDrawBoxes(painter, x, y, currentEv);
|
||||
|
||||
QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
||||
JKQTMathTextEnvironment ev1=currentEv;
|
||||
|
||||
double xh=fm.strikeOutPos();//fm.xHeight();
|
||||
//double Ah=fm.ascent();
|
||||
double xw=fm.boundingRect("x").width();
|
||||
|
||||
//ev1.fontSize=ev1.fontSize;*parent->getFracFactor();
|
||||
|
||||
|
||||
QVector<double> colwidth, rowheight, rowascent;
|
||||
//QVector<QVector<double> > widths, heights, baselines;
|
||||
|
||||
double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos=0;
|
||||
//widths.resize(lines);
|
||||
colwidth.resize(columns); for (int i=0; i<columns; i++) colwidth[i]=0;
|
||||
rowheight.resize(lines);
|
||||
rowascent.resize(lines);
|
||||
//heights=baselines=widths;
|
||||
for (int i=0; i<lines; i++) {
|
||||
rowheight[i]=0;
|
||||
rowascent[i]=0;
|
||||
//widths[i].resize(columns);
|
||||
//baselines[i]=heights[i]=widths[i];
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
if (children[i].at(j)!=nullptr) children[i].at(j)->getSize(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; i<columns; i++) width=width+colwidth[i];
|
||||
for (int i=0; i<lines; i++) overallHeight=overallHeight+rowheight[i];
|
||||
double baselineHeight=overallHeight/2.0+xh;
|
||||
|
||||
double xx=x;
|
||||
double yy=y-baselineHeight;
|
||||
if (lines>0) yy=yy+rowascent[0];
|
||||
for (int i=0; i<lines; i++) {
|
||||
xx=x;
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
children[i].at(j)->draw(painter, xx, yy, ev1);
|
||||
xx=xx+colwidth[j]+xw;
|
||||
}
|
||||
|
||||
if (i<lines-1) yy=yy+(rowheight[i]-rowascent[i])+xw/2.0+rowascent[i+1];
|
||||
}
|
||||
|
||||
|
||||
return x+width;
|
||||
}
|
||||
|
||||
bool JKQTMathTextMatrixNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/)
|
||||
{
|
||||
@ -188,6 +120,7 @@ int JKQTMathTextMatrixNode::getLines() const {
|
||||
return this->lines;
|
||||
}
|
||||
|
||||
|
||||
void JKQTMathTextMatrixNode::setDrawBoxes(bool draw)
|
||||
{
|
||||
this->drawBoxes=draw;
|
||||
@ -199,5 +132,204 @@ void JKQTMathTextMatrixNode::setDrawBoxes(bool draw)
|
||||
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::drawVLine(QPainter &painter, double x, double y, double height, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation)
|
||||
{
|
||||
if (lt==LTnone) return;
|
||||
QPen p(color, linewidth, Qt::SolidLine);
|
||||
if (lt==LTdashed || lt==LTdoubleDashed) p.setStyle(Qt::DashLine);
|
||||
if (lt==LTheavyline) p.setWidth(linewidthHeavy);
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.setPen(p);
|
||||
if (lt==LTline || lt==LTdashed || lt==LTheavyline) {
|
||||
painter.drawLine(QPointF(x,y), QPointF(x,y+height));
|
||||
} else if (lt==LTdoubleline || lt==LTdoubleDashed) {
|
||||
painter.drawLine(QPointF(x-doublelineseparation/2.0,y), QPointF(x-doublelineseparation/2.0,y+height));
|
||||
painter.drawLine(QPointF(x+doublelineseparation/2.0,y), QPointF(x+doublelineseparation/2.0,y+height));
|
||||
}
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::drawHLine(QPainter &painter, double x, double y, double width, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation)
|
||||
{
|
||||
if (lt==LTnone) return;
|
||||
QPen p(color, linewidth, Qt::SolidLine);
|
||||
if (lt==LTdashed || lt==LTdoubleDashed) p.setStyle(Qt::DashLine);
|
||||
if (lt==LTheavyline) p.setWidth(linewidthHeavy);
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.setPen(p);
|
||||
if (lt==LTline || lt==LTdashed || lt==LTheavyline) {
|
||||
painter.drawLine(QPointF(x,y), QPointF(x+width,y));
|
||||
} else if (lt==LTdoubleline || lt==LTdoubleDashed) {
|
||||
painter.drawLine(QPointF(x,y-doublelineseparation/2.0), QPointF(x+width,y-doublelineseparation/2.0));
|
||||
painter.drawLine(QPointF(x,y+doublelineseparation/2.0), QPointF(x+width,y+doublelineseparation/2.0));
|
||||
}
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::parseColumnSpec(const QString &columnSpec)
|
||||
{
|
||||
int i=0;
|
||||
while (i<columnSpec.size()) {
|
||||
if (columnSpec[i]=='l') {
|
||||
columnAlignment<<MTHALeft;
|
||||
} else if (columnSpec[i]=='c') {
|
||||
columnAlignment<<MTHACentered;
|
||||
} else if (columnSpec[i]=='r') {
|
||||
columnAlignment<<MTHARight;
|
||||
} else if (columnSpec.mid(i,2)=="||") {
|
||||
if (columnAlignment.size()==0) {
|
||||
verticalLineLeft=LTdoubleline;
|
||||
} else {
|
||||
verticalLineRHSColumn[columnAlignment.size()-1]=LTdoubleline;
|
||||
}
|
||||
i++;
|
||||
} else if (columnSpec.mid(i,2)=="::") {
|
||||
if (columnAlignment.size()==0) {
|
||||
verticalLineLeft=LTdoubleDashed;
|
||||
} else {
|
||||
verticalLineRHSColumn[columnAlignment.size()-1]=LTdoubleDashed;
|
||||
}
|
||||
i++;
|
||||
} else if (columnSpec.mid(i,1)=="|") {
|
||||
if (columnAlignment.size()==0) {
|
||||
verticalLineLeft=LTline;
|
||||
} else {
|
||||
verticalLineRHSColumn[columnAlignment.size()-1]=LTline;
|
||||
}
|
||||
} else if (columnSpec.mid(i,1)==":") {
|
||||
if (columnAlignment.size()==0) {
|
||||
verticalLineLeft=LTdashed;
|
||||
} else {
|
||||
verticalLineRHSColumn[columnAlignment.size()-1]=LTdashed;
|
||||
}
|
||||
} else if (!columnSpec[i].isSpace()){
|
||||
parentMathText->addToErrorList(QString("array spec has unknown character '%1' (full spec was '%2')").arg(columnSpec[i]).arg(columnSpec));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JKQTMathTextMatrixNode::LayoutInfo::LayoutInfo():
|
||||
JKQTMathTextNodeSize(), colwidth(), rowheight()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKQTMathTextMatrixNode::LayoutInfo JKQTMathTextMatrixNode::calcLayout(QPainter &painter, const JKQTMathTextEnvironment ¤tEv) const
|
||||
{
|
||||
LayoutInfo l;
|
||||
|
||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
||||
JKQTMathTextEnvironment ev1=currentEv;
|
||||
|
||||
const double xheight=fm.strikeOutPos();
|
||||
const double xwidth=fm.boundingRect("x").width();
|
||||
const double XPadding=parentMathText->getMatrixXPaddingFactor()*xwidth;
|
||||
const double YPadding=parentMathText->getMatrixYPaddingFactor()*xwidth;
|
||||
const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
|
||||
const double YSeparation=parentMathText->getMatrixYSeparationFactor()*xwidth;
|
||||
|
||||
l.colwidth.resize(columns); for (int i=0; i<columns; i++) l.colwidth[i]=0;
|
||||
l.rowheight.resize(lines);
|
||||
l.rowascent.resize(lines);
|
||||
l.cellwidth.resize(lines);
|
||||
l.leftPadding=(verticalLineLeft==LTnone)?0:XPadding;
|
||||
l.rightPadding=(verticalLineRHSColumn.value(columns-1,LTnone)==LTnone)?0:XPadding;
|
||||
l.topPadding=(horizontalLineTop==LTnone)?0:YPadding;
|
||||
l.bottomPadding=(horizontalLineBottomRow.value(lines-1,LTnone)==LTnone)?0:YPadding;
|
||||
for (int ll=0; ll<lines; ll++) l.cellwidth[ll]=QVector<double>(columns, 0.0);
|
||||
QVector<double> rowdescent;
|
||||
rowdescent.resize(lines);
|
||||
for (int i=0; i<lines; i++) {
|
||||
l.rowheight[i]=0;
|
||||
l.rowascent[i]=0;
|
||||
rowdescent[i]=0;
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
const JKQTMathTextNodeSize cs=children[i].at(j)->getSize(painter, ev1);
|
||||
l.cellwidth[i].operator[](j)=cs.width;
|
||||
l.colwidth[j]=qMax(l.colwidth[j], cs.width);
|
||||
l.rowascent[i]=qMax(l.rowascent[i], cs.baselineHeight);
|
||||
rowdescent[i]=qMax(rowdescent[i], cs.getDescent());
|
||||
}
|
||||
l.rowheight[i]=l.rowascent[i]+rowdescent[i];
|
||||
}
|
||||
|
||||
|
||||
l.overallHeight=(lines-1)*YSeparation+l.topPadding+l.bottomPadding;
|
||||
l.width=(columns-1)*XSeparation+l.leftPadding+l.rightPadding;
|
||||
for (int i=0; i<columns; i++) l.width=l.width+l.colwidth[i];
|
||||
for (int i=0; i<lines; i++) l.overallHeight=l.overallHeight+l.rowheight[i];
|
||||
l.baselineHeight=l.overallHeight/2.0+xheight;
|
||||
l.strikeoutPos=xheight;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
const LayoutInfo l=calcLayout(painter, currentEv);
|
||||
width=l.width;
|
||||
overallHeight=l.overallHeight;
|
||||
baselineHeight=l.baselineHeight;
|
||||
strikeoutPos=l.strikeoutPos;
|
||||
}
|
||||
|
||||
double JKQTMathTextMatrixNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
doDrawBoxes(painter, x, y, currentEv);
|
||||
|
||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
||||
JKQTMathTextEnvironment ev1=currentEv;
|
||||
|
||||
const LayoutInfo l=calcLayout(painter, currentEv);
|
||||
|
||||
const double xheight=fm.strikeOutPos();
|
||||
const double xwidth=fm.boundingRect("x").width();
|
||||
//const double XPadding=parentMathText->getMatrixXPaddingFactor()*xwidth;
|
||||
//const double YPadding=parentMathText->getMatrixYPaddingFactor()*xwidth;
|
||||
const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
|
||||
const double YSeparation=parentMathText->getMatrixYSeparationFactor()*xwidth;
|
||||
const double yTop=y-l.baselineHeight+l.topPadding;
|
||||
const double xLeft=x+l.leftPadding;
|
||||
const double linewidth=parentMathText->getMatrixLinewidthThinFactor()*fm.lineWidth();
|
||||
const double linewidthThick=parentMathText->getMatrixLinewidthHeavyFactor()*fm.lineWidth();
|
||||
const double lineSeparation=parentMathText->getMatrixLineSeparationFactor()*fm.lineWidth();
|
||||
double leftlineX=xLeft-l.leftPadding/2.0;
|
||||
double rightlineX=x+l.width-l.rightPadding/2.0;
|
||||
double toplineY=yTop-l.topPadding/2.0;
|
||||
double bottomlineY=y+l.getDescent()-l.bottomPadding/2;
|
||||
if (verticalLineLeft==LTdoubleline || verticalLineLeft==LTdoubleDashed) leftlineX-=linewidth;
|
||||
if (horizontalLineTop==LTdoubleline || horizontalLineTop==LTdoubleDashed) toplineY-=linewidth;
|
||||
if (verticalLineRHSColumn.value(lines-1, LTnone)==LTdoubleline || verticalLineRHSColumn.value(lines-1, LTnone)==LTdoubleDashed) rightlineX+=linewidth;
|
||||
if (horizontalLineBottomRow.value(columns-1, LTnone)==LTdoubleline || horizontalLineBottomRow.value(columns-1, LTnone)==LTdoubleDashed) bottomlineY+=linewidth;
|
||||
|
||||
|
||||
|
||||
double xx;
|
||||
double yy=yTop;
|
||||
if (lines>0) yy=yy+l.rowascent[0];
|
||||
for (int i=0; i<lines; i++) {
|
||||
xx=xLeft;
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
const double cw=l.getCellwidth(i, j);
|
||||
double xoffset=0;
|
||||
if (columnAlignment.value(j, MTHALeft)==MTHACentered) xoffset=(l.colwidth[j]-cw)/2.0;
|
||||
else if (columnAlignment.value(j, MTHALeft)==MTHARight) xoffset=(l.colwidth[j]-cw);
|
||||
children[i].at(j)->draw(painter, xx+xoffset, yy, ev1);
|
||||
xx=xx+l.colwidth[j]+XSeparation;
|
||||
if (i==0 && j<columns-1) drawVLine(painter, xx-XSeparation/2.0, toplineY, bottomlineY-toplineY, verticalLineRHSColumn.value(j, LTnone), linewidth, linewidthThick, currentEv.color, lineSeparation);
|
||||
}
|
||||
|
||||
if (i<lines-1) {
|
||||
double yline=yy+(l.rowheight[i]-l.rowascent[i])+YSeparation/2.0;
|
||||
yy=yline+YSeparation/2.0+l.rowascent[i+1];
|
||||
drawHLine(painter, leftlineX, yline, rightlineX-leftlineX, horizontalLineBottomRow.value(i, LTnone), linewidth, linewidthThick, currentEv.color, lineSeparation);
|
||||
}
|
||||
}
|
||||
|
||||
drawVLine(painter, leftlineX, toplineY, bottomlineY-toplineY, verticalLineLeft, linewidth, linewidthThick, currentEv.color, lineSeparation);
|
||||
drawVLine(painter, rightlineX, toplineY, bottomlineY-toplineY, verticalLineRHSColumn.value(columns-1, LTnone), linewidth, linewidthThick, currentEv.color, lineSeparation);
|
||||
drawHLine(painter, leftlineX, toplineY, rightlineX-leftlineX, verticalLineLeft, linewidth, linewidthThick, currentEv.color, lineSeparation);
|
||||
drawHLine(painter, leftlineX, bottomlineY, rightlineX-leftlineX, horizontalLineBottomRow.value(lines-1, LTnone), linewidth, linewidthThick, currentEv.color, lineSeparation);
|
||||
|
||||
return x+l.width;
|
||||
}
|
||||
|
@ -32,13 +32,39 @@ class JKQTMathText; // forward
|
||||
// JKQTMATHTEXT_LIB_EXPORT
|
||||
|
||||
|
||||
/** \brief subclass representing a \\begin{matrix} node
|
||||
/** \brief subclass representing a \c \\begin{matrix} , \c \\begin{tabular} , \c \\begin{array} , ... node
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
* Definition of the matrix geometry
|
||||
* \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
|
||||
*
|
||||
*
|
||||
* Two examples:
|
||||
* \image html jkqtmathtext/jkqtmathtext_tabular.png
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_array.png
|
||||
*/
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode {
|
||||
public:
|
||||
JKQTMathTextMatrixNode(JKQTMathText* parent, QVector<QVector<JKQTMathTextNode*> > children);
|
||||
/** \brief types of lines */
|
||||
enum LineType {
|
||||
LTnone, /*!< \brief noline */
|
||||
LTline, /*!< \brief single line */
|
||||
LTdoubleline, /*!< \brief double line */
|
||||
LTheavyline, /*!< \brief heavier/thick line */
|
||||
LTdashed, /*!< \brief single dashed line */
|
||||
LTdoubleDashed, /*!< \brief double dashed line */
|
||||
LTdefault=LTnone
|
||||
};
|
||||
JKQTMathTextMatrixNode(JKQTMathText* parent, const QVector<QVector<JKQTMathTextNode*> >& children, const QString& columnSpec=QString());
|
||||
JKQTMathTextMatrixNode(JKQTMathText* parent, const QString& columnSpec=QString());
|
||||
virtual ~JKQTMathTextMatrixNode() override;
|
||||
/** \brief sets the child nodes */
|
||||
void setChildren(const QVector<QVector<JKQTMathTextNode*> >& children);
|
||||
/** \copydoc horizontalLineBottomRow */
|
||||
void setRowBottomLine(int col, LineType line);
|
||||
/** \copydoc horizontalLineTop */
|
||||
void setTopLine(LineType line);
|
||||
/** \copydoc JKQTMathTextNode::getTypeName() */
|
||||
virtual QString getTypeName() const override;
|
||||
/** \copydoc JKQTMathTextNode::draw() */
|
||||
@ -52,16 +78,63 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode {
|
||||
/** \copydoc lines */
|
||||
int getLines() const;
|
||||
protected:
|
||||
/** \brief describes the layout of the whole node */
|
||||
struct LayoutInfo: public JKQTMathTextNodeSize {
|
||||
LayoutInfo();
|
||||
/** \brief widths of the columns */
|
||||
QVector<double> colwidth;
|
||||
/** \brief widths of the cells */
|
||||
QVector<QVector<double> > cellwidth;
|
||||
inline double& getCellwidth(int line, int col) {
|
||||
return cellwidth[line].operator[](col);
|
||||
}
|
||||
inline const double& getCellwidth(int line, int col) const {
|
||||
return cellwidth[line].operator[](col);
|
||||
}
|
||||
/** \brief heights of the rows */
|
||||
QVector<double> rowheight;
|
||||
/** \brief ascents of the rows */
|
||||
QVector<double> rowascent;
|
||||
double leftPadding;
|
||||
double rightPadding;
|
||||
double topPadding;
|
||||
double bottomPadding;
|
||||
|
||||
};
|
||||
/** \brief calclates the layout of the whole block/node
|
||||
*
|
||||
* \note This function does NOT call transformEnvironment();
|
||||
* it has to be called before calling this!
|
||||
*/
|
||||
LayoutInfo calcLayout(QPainter& painter, const JKQTMathTextEnvironment& currentEv) const;
|
||||
/** \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;
|
||||
/** \brief child nodes making up the matrix, vector of rows */
|
||||
QVector<QVector<JKQTMathTextNode*> > children;
|
||||
/** \brief alignment of the columns */
|
||||
QVector<JKQTMathTextHorizontalAlignment> columnAlignment;
|
||||
/** \brief lines to the right of each column */
|
||||
QMap<int,LineType> verticalLineRHSColumn;
|
||||
/** \brief line at the left of the table */
|
||||
LineType verticalLineLeft;
|
||||
/** \brief lines to the bottom of each row */
|
||||
QMap<int,LineType> horizontalLineBottomRow;
|
||||
/** \brief line at the top of the table */
|
||||
LineType horizontalLineTop;
|
||||
|
||||
/** \brief number of columns in the matrix */
|
||||
int columns;
|
||||
/** \brief number of rows in the matrix */
|
||||
int lines;
|
||||
|
||||
/** \brief draw a vertical line starting at pixel position (\a x, \a y ) with length \a height, using linetype \a lt, width \a linewidth and \a color */
|
||||
static void drawVLine(QPainter& painter, double x, double y, double height, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation);
|
||||
/** \brief draw a horizontal line starting at pixel position (\a x, \a y ) with length \a width, using linetype \a lt, width \a linewidth and \a color */
|
||||
static void drawHLine(QPainter& painter, double x, double y, double width, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation);
|
||||
/** \brief parses a column specifier */
|
||||
void parseColumnSpec(const QString& columnspec);
|
||||
};
|
||||
|
||||
#endif // JKQTMATHTEXTMATRIXNODE_H
|
||||
|
@ -285,6 +285,18 @@ void JKQTMathTextDualChildNode::clearChildren(bool deleteChildren)
|
||||
if (deleteChildren&&c2) delete c2;
|
||||
}
|
||||
|
||||
void JKQTMathTextDualChildNode::deleteChild(int i)
|
||||
{
|
||||
if (child1&&i==0) {
|
||||
delete child1;
|
||||
child1=nullptr;
|
||||
}
|
||||
if (child2&&i==1) {
|
||||
delete child2;
|
||||
child2=nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
JKQTMathTextMultiChildNode::JKQTMathTextMultiChildNode(JKQTMathText *parentMathText):
|
||||
JKQTMathTextNode(parentMathText)
|
||||
{
|
||||
|
@ -232,6 +232,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMultiChildNode: public JKQTMathTextNod
|
||||
|
||||
/** \brief clear all children, deleting them if \a deleteChildren==true */
|
||||
virtual void clearChildren(bool deleteChildren=true) =0;
|
||||
/** \brief delete the i-th child */
|
||||
virtual void deleteChild(int i) =0;
|
||||
|
||||
/** \copydoc JKQTMathTextNode::setDrawBoxes() */
|
||||
virtual void setDrawBoxes(bool draw) override;
|
||||
@ -266,6 +268,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDualChildNode: public JKQTMathTextMult
|
||||
virtual int childCount() const override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual void clearChildren(bool deleteChildren=true) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
|
||||
virtual void deleteChild(int i) override;
|
||||
|
||||
|
||||
protected:
|
||||
/** \brief first child node of this node */
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
|
||||
#include "jkqtmathtext/nodes/jkqtmathtextlistnode.h"
|
||||
#include "jkqtmathtext/nodes/jkqtmathtextwhitespacenode.h"
|
||||
#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
|
||||
#include "jkqtmathtext/jkqtmathtexttools.h"
|
||||
#include "jkqtmathtext/jkqtmathtext.h"
|
||||
#include <QDebug>
|
||||
@ -65,3 +67,42 @@ JKQTMathTextNode *simplifyJKQTMathTextNode(JKQTMathTextNode *node)
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
JKQTMathTextNode *simplifyAndTrimJKQTMathTextNode(JKQTMathTextNode *node)
|
||||
{
|
||||
auto cleanText=[](JKQTMathTextNode* t) {
|
||||
JKQTMathTextMultiChildNode* nmc=dynamic_cast<JKQTMathTextMultiChildNode*>(t);
|
||||
JKQTMathTextNode* tt0=(nmc&&nmc->childCount()>0)?nmc->getFirstChild():t;
|
||||
JKQTMathTextNode* tt1=(nmc&&nmc->childCount()>0)?nmc->getLastChild():t;
|
||||
JKQTMathTextTextNode* txt0=dynamic_cast<JKQTMathTextTextNode*>(tt0);
|
||||
if (txt0) {
|
||||
txt0->removeLeadingWhitespace();
|
||||
}
|
||||
JKQTMathTextTextNode* txt1=dynamic_cast<JKQTMathTextTextNode*>(tt1);
|
||||
if (txt1) {
|
||||
txt1->removeTrailingWhitespace();
|
||||
}
|
||||
};
|
||||
JKQTMathTextNode* t=node;
|
||||
for (int iter=0; iter<3; iter++) {
|
||||
t=simplifyJKQTMathTextNode(t);
|
||||
JKQTMathTextMultiChildNode* nmc=dynamic_cast<JKQTMathTextMultiChildNode*>(t);
|
||||
if (nmc && nmc->childCount()>0) {
|
||||
bool done=false;
|
||||
cleanText(nmc);
|
||||
while (!done && nmc->childCount()>0) {
|
||||
JKQTMathTextWhitespaceNode* ws0=dynamic_cast<JKQTMathTextWhitespaceNode*>(nmc->getFirstChild());
|
||||
JKQTMathTextWhitespaceNode* ws1=dynamic_cast<JKQTMathTextWhitespaceNode*>(nmc->getLastChild());
|
||||
if (ws0 && ws0->getWhitespaceType()==JKQTMathTextWhitespaceNode::WSTNormal) {
|
||||
nmc->deleteChild(0);
|
||||
} else if (ws1 && ws1->getWhitespaceType()==JKQTMathTextWhitespaceNode::WSTNormal) {
|
||||
nmc->deleteChild(nmc->childCount()-1);
|
||||
} else {
|
||||
done=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanText(t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
@ -37,6 +37,13 @@ class JKQTMathTextNode; // forward
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode* simplifyJKQTMathTextNode(JKQTMathTextNode* node);
|
||||
|
||||
/** \brief calls simplifyJKQTMathTextNode(). In addition it tries to clear whitespace at the start and end of the tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
* \see simplifyJKQTMathTextNode()
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode* simplifyAndTrimJKQTMathTextNode(JKQTMathTextNode* node);
|
||||
|
||||
#endif // JKQTMATHTEXTNODETOOLS_H
|
||||
|
||||
|
||||
|
@ -227,3 +227,15 @@ void JKQTMathTextSqrtNode::clearChildren(bool deleteChildren)
|
||||
}
|
||||
}
|
||||
|
||||
void JKQTMathTextSqrtNode::deleteChild(int i)
|
||||
{
|
||||
if (child && i==0) {
|
||||
delete child;
|
||||
child=nullptr;
|
||||
}
|
||||
if (childDegree && i==1) {
|
||||
delete childDegree;
|
||||
childDegree=nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSqrtNode: public JKQTMathTextMultiChil
|
||||
virtual int childCount() const override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual void clearChildren(bool deleteChildren=true) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
|
||||
virtual void deleteChild(int i) override;
|
||||
|
||||
protected:
|
||||
/** \copydoc JKQTMathTextNode::getSizeInternal() */
|
||||
|
@ -376,6 +376,16 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorText
|
||||
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf).addHtml(ophtml, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0);
|
||||
}
|
||||
|
||||
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorText(const QString &op)
|
||||
{
|
||||
return NarrowMathOperatorText(op, op);
|
||||
}
|
||||
|
||||
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorText(const QString &op, const QString &ophtml)
|
||||
{
|
||||
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0)).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf).addHtml(ophtml, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0);
|
||||
}
|
||||
|
||||
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorSymbolUnicode(const QString &unicode)
|
||||
{
|
||||
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf);
|
||||
@ -532,7 +542,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
symbols["brcorner"]=s; symbols["lrcorner"]=s; }
|
||||
{ auto s=UprightSymbolUnicode(QChar(0x2022)).addUprightHtml("•").addUprightWinSymbol(QChar(0xB7));
|
||||
symbols["bullet"]=s; symbols["textbullet"]=s; }
|
||||
symbols["cdots"]=UnicodeSymbol(QChar(0x22EF)).addHtml("···").addStd(QString(3, QChar(0xB7)));
|
||||
symbols["cdots"]=UprightSymbolUnicode(QChar(0x22EF)).addHtml("···").addStd(QString(3, QChar(0xB7)));
|
||||
{ auto s=UnicodeSymbol(QChar(0x2103)).addUprightStd("°C").addUprightHtml("°C");
|
||||
symbols["celsius"]=s; symbols["degC"]=s; symbols["degreeCelsius"]=s; }
|
||||
symbols["ell"]=UprightSymbolUnicode(QChar(0x2113), "ℓ");
|
||||
@ -583,8 +593,6 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
symbols["infty"]=UnicodeSymbol(QChar(0x221E)).addHtml("∞").addWinSymbol(QChar(0xA5)).addStd("8", RotateSymbol90);
|
||||
symbols["langle"]=UprightSymbolUnicode(QChar(0x2329)).addWinSymbol(QChar(0xE1));
|
||||
symbols["lceil"]=UprightSymbolUnicode(QChar(0x2308)).addHtml("⌈").addWinSymbol(QChar(0xE9));
|
||||
{ auto s=SimpleTextSymbol("...").addUnicode(QChar(0x2026)).addWinSymbol(QChar(0xB6));
|
||||
symbols["ldots"]=s; symbols["dots"]=s; }
|
||||
symbols["lfloor"]=UprightSymbolUnicode(QChar(0x230A)).addHtml("⌊").addWinSymbol(QChar(0xEB));
|
||||
symbols["lightning"]=UnicodeSymbol(QChar(0x21AF));
|
||||
symbols["male"]=UnicodeSymbol(QChar(0x2642)).addHtml("♂");
|
||||
@ -642,46 +650,46 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
/**************************************************************************************
|
||||
* STANDARD MathOperator Strings
|
||||
**************************************************************************************/
|
||||
symbols["Pr"] = MathOperatorText("Pr");
|
||||
symbols["acos"] = MathOperatorText("acos");
|
||||
symbols["arccos"] = MathOperatorText("arccos");
|
||||
symbols["arcsin"] = MathOperatorText("arcsin");
|
||||
symbols["arctan"] = MathOperatorText("arctan");
|
||||
symbols["arg"] = MathOperatorText("arg").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["argmax"] = MathOperatorText("arg max", "arg max").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["argmin"] = MathOperatorText("arg min", "arg min").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["asin"] = MathOperatorText("asin");
|
||||
symbols["atan"] = MathOperatorText("atan");
|
||||
symbols["cos"] = MathOperatorText("cos");
|
||||
symbols["cosh"] = MathOperatorText("cosh");
|
||||
symbols["cot"] = MathOperatorText("cot");
|
||||
symbols["coth"] = MathOperatorText("coth");
|
||||
symbols["coth"] = MathOperatorText("coth");
|
||||
symbols["deg"] = MathOperatorText("deg");
|
||||
symbols["det"] = MathOperatorText("det");
|
||||
symbols["dim"] = MathOperatorText("dim");
|
||||
symbols["exp"] = MathOperatorText("exp");
|
||||
symbols["gcd"] = MathOperatorText("gcd");
|
||||
symbols["hom"] = MathOperatorText("hom");
|
||||
symbols["ker"] = MathOperatorText("ker");
|
||||
symbols["lb"] = MathOperatorText("lb");
|
||||
symbols["ld"] = MathOperatorText("ld");
|
||||
symbols["lim"] = MathOperatorText("lim").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["liminf"] = MathOperatorText("lim inf", "lim inf").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["limsup"] = MathOperatorText("lim sup", "lim sup").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["ln"] = MathOperatorText("ln");
|
||||
symbols["log"] = MathOperatorText("log");
|
||||
symbols["max"] = MathOperatorText("max");
|
||||
symbols["median"] = MathOperatorText("median");
|
||||
symbols["min"] = MathOperatorText("min");
|
||||
symbols["mod"] = MathOperatorText("mod");
|
||||
symbols["sec"] = MathOperatorText("sec");
|
||||
symbols["sgn"] = MathOperatorText("sgn");
|
||||
symbols["sign"] = MathOperatorText("sign");
|
||||
symbols["sin"] = MathOperatorText("sin");
|
||||
symbols["sinh"] = MathOperatorText("sinh");
|
||||
symbols["tan"] = MathOperatorText("tan");
|
||||
symbols["tanh"] = MathOperatorText("tanh");
|
||||
symbols["Pr"] = NarrowMathOperatorText("Pr");
|
||||
symbols["acos"] = NarrowMathOperatorText("acos");
|
||||
symbols["arccos"] = NarrowMathOperatorText("arccos");
|
||||
symbols["arcsin"] = NarrowMathOperatorText("arcsin");
|
||||
symbols["arctan"] = NarrowMathOperatorText("arctan");
|
||||
symbols["arg"] = NarrowMathOperatorText("arg").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["argmax"] = NarrowMathOperatorText("arg max", "arg max").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["argmin"] = NarrowMathOperatorText("arg min", "arg min").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["asin"] = NarrowMathOperatorText("asin");
|
||||
symbols["atan"] = NarrowMathOperatorText("atan");
|
||||
symbols["cos"] = NarrowMathOperatorText("cos");
|
||||
symbols["cosh"] = NarrowMathOperatorText("cosh");
|
||||
symbols["cot"] = NarrowMathOperatorText("cot");
|
||||
symbols["coth"] = NarrowMathOperatorText("coth");
|
||||
symbols["coth"] = NarrowMathOperatorText("coth");
|
||||
symbols["deg"] = NarrowMathOperatorText("deg");
|
||||
symbols["det"] = NarrowMathOperatorText("det");
|
||||
symbols["dim"] = NarrowMathOperatorText("dim");
|
||||
symbols["exp"] = NarrowMathOperatorText("exp");
|
||||
symbols["gcd"] = NarrowMathOperatorText("gcd");
|
||||
symbols["hom"] = NarrowMathOperatorText("hom");
|
||||
symbols["ker"] = NarrowMathOperatorText("ker");
|
||||
symbols["lb"] = NarrowMathOperatorText("lb");
|
||||
symbols["ld"] = NarrowMathOperatorText("ld");
|
||||
symbols["lim"] = NarrowMathOperatorText("lim").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["liminf"] = NarrowMathOperatorText("lim inf", "lim inf").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["limsup"] = NarrowMathOperatorText("lim sup", "lim sup").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["ln"] = NarrowMathOperatorText("ln");
|
||||
symbols["log"] = NarrowMathOperatorText("log");
|
||||
symbols["max"] = NarrowMathOperatorText("max");
|
||||
symbols["median"] = NarrowMathOperatorText("median");
|
||||
symbols["min"] = NarrowMathOperatorText("min");
|
||||
symbols["mod"] = NarrowMathOperatorText("mod");
|
||||
symbols["sec"] = NarrowMathOperatorText("sec");
|
||||
symbols["sgn"] = NarrowMathOperatorText("sgn");
|
||||
symbols["sign"] = NarrowMathOperatorText("sign");
|
||||
symbols["sin"] = NarrowMathOperatorText("sin");
|
||||
symbols["sinh"] = NarrowMathOperatorText("sinh");
|
||||
symbols["tan"] = NarrowMathOperatorText("tan");
|
||||
symbols["tanh"] = NarrowMathOperatorText("tanh");
|
||||
|
||||
/**************************************************************************************
|
||||
* STANDARD MathOperator Symbols
|
||||
@ -701,12 +709,12 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
symbols["Updownarrow"]=UprightSymbolUnicode(QChar(0x21D5)).addUprightHtml("⇕");
|
||||
symbols["approx"]=MathOperatorSymbolUnicode(QChar(0x2248)).addMathOperatorHtml("≈").addMathOperatorWinSymbol(QChar(0xBB));
|
||||
symbols["bbC"]=UnicodeSymbol(QChar(0x2102));
|
||||
symbols["bbH"]=MathOperatorSymbolUnicode(QChar(0x210D));
|
||||
symbols["bbN"]=MathOperatorSymbolUnicode(QChar(0x2115));
|
||||
symbols["bbP"]=MathOperatorSymbolUnicode(QChar(0x2119));
|
||||
symbols["bbQ"]=MathOperatorSymbolUnicode(QChar(0x211A));
|
||||
symbols["bbR"]=MathOperatorSymbolUnicode(QChar(0x211D));
|
||||
symbols["bbZ"]=MathOperatorSymbolUnicode(QChar(0x2124));
|
||||
symbols["bbH"]=UnicodeSymbol(QChar(0x210D));
|
||||
symbols["bbN"]=UnicodeSymbol(QChar(0x2115));
|
||||
symbols["bbP"]=UnicodeSymbol(QChar(0x2119));
|
||||
symbols["bbQ"]=UnicodeSymbol(QChar(0x211A));
|
||||
symbols["bbR"]=UnicodeSymbol(QChar(0x211D));
|
||||
symbols["bbZ"]=UnicodeSymbol(QChar(0x2124));
|
||||
symbols["because"]=MathOperatorSymbolUnicode(QChar(0x2235)).addMathOperatorHtml("∵");
|
||||
symbols["bigcap"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C2)).addMathOperatorHtml("⋂").addMathOperatorWinSymbol(QChar(0xC7), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
symbols["bigcup"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C3)).addMathOperatorHtml("⋃").addMathOperatorWinSymbol(QChar(0xC8), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
@ -727,7 +735,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
symbols["coprod"]=NarrowMathOperatorSymbolUnicode(QChar(0x2210)).addMathOperatorHtml("∐").addWinSymbol(QChar(0xD5), ItalicOff|BoldOff|FlipSymbolUpDown, 1.8, 0.1).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
{ auto s=MathOperatorSymbolUnicode(QChar(0x222A)).addMathOperatorHtml("∪").addMathOperatorWinSymbol(QChar(0xC8));
|
||||
symbols["cup"]=s; symbols["lor"]=s; }
|
||||
symbols["ddots"]=MathOperatorSymbolUnicode(QChar(0x22F1)).addMathOperatorHtml("⋱");
|
||||
symbols["ddots"]=UprightSymbolUnicode(QChar(0x22F1)).addMathOperatorHtml("⋱");
|
||||
symbols["div"]=MathOperatorSymbolUnicode(QChar(0x00F7)).addMathOperatorHtml("÷").addMathOperatorWinSymbol(QChar(0xB8));
|
||||
symbols["downarrow"]=UprightSymbolUnicode(QChar(0x2193)).addUprightHtml("↓").addUprightWinSymbol(QChar(0xAF));
|
||||
symbols["downharpoonleft"]=UprightSymbolUnicode(QChar(0x21C3)).addUprightHtml("⇃");
|
||||
@ -735,13 +743,13 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
{ auto s=MathOperatorSymbolUnicode(QChar(0x2205)).addMathOperatorHtml("∅").addMathOperatorWinSymbol(QChar(0xC6)).addStd("0", BoldOff|ItalicOff|DrawSlash);
|
||||
symbols["emptyset"]=s; symbols["varnothing"]=s; }
|
||||
symbols["equiv"]=MathOperatorSymbolUnicode(QChar(0x2261)).addMathOperatorHtml("≡").addMathOperatorWinSymbol(QChar(0xBA));
|
||||
symbols["exists"]=MathOperatorSymbolUnicode(QChar(0x2203)).addMathOperatorHtml("∃").addMathOperatorWinSymbol(QChar(0x24)).addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight);
|
||||
symbols["forall"]=MathOperatorSymbolUnicode(QChar(0x2200)).addMathOperatorHtml("∀").addMathOperatorWinSymbol(QChar(0x22)).addStd("A", ItalicOff|BoldOff|FlipSymbolUpDown);
|
||||
symbols["exists"]=NarrowMathOperatorSymbolUnicode(QChar(0x2203)).addMathOperatorHtml("∃").addMathOperatorWinSymbol(QChar(0x24)).addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight);
|
||||
symbols["forall"]=NarrowMathOperatorSymbolUnicode(QChar(0x2200)).addMathOperatorHtml("∀").addMathOperatorWinSymbol(QChar(0x22)).addStd("A", ItalicOff|BoldOff|FlipSymbolUpDown);
|
||||
{ auto s=MathOperatorSymbolUnicode(QChar(0x2265)).addMathOperatorHtml("≥").addMathOperatorWinSymbol(QChar(0xB3));
|
||||
symbols["geq"]=s; symbols["ge"]=s; }
|
||||
symbols["geqq"]=MathOperatorSymbolUnicode(QChar(0x2267)).addMathOperatorHtml("≧");
|
||||
symbols["gg"]=MathOperatorSymbolUnicode(QChar(0x226B)).addMathOperatorHtml("≫").addMathOperatorStd(">>");
|
||||
symbols["iddots"]=MathOperatorSymbolUnicode(QChar(0x22F0)).addMathOperatorHtml("⋰");
|
||||
symbols["iddots"]=UprightSymbolUnicode(QChar(0x22F0)).addMathOperatorHtml("⋰");
|
||||
{ auto s=UprightSymbolUnicode(QChar(0x21D4)).addUprightHtml("⇔").addUprightWinSymbol(QChar(0xDB));
|
||||
symbols["iff"]=s; symbols["Leftrightarrow"]=s; }
|
||||
symbols["iiint"]=NarrowMathOperatorSymbolUnicode(QChar(0x222D)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("∭").addMathOperatorWinSymbol(QString(3, QChar(0xF2)), 1.8, 0.1);
|
||||
@ -770,17 +778,17 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
symbols["mid"]=MathOperatorSymbolUnicode(QChar(0x2223)).addMathOperatorHtml("∣").addMathOperatorWinSymbol(QChar(0xBD)).addMathOperatorStd("|");
|
||||
symbols["mp"]=MathOperatorSymbolUnicode(QChar(0x2213)).addMathOperatorHtml("∓").addWinSymbol(QChar(0xB1),ItalicOff|BoldOff|FlipSymbolUpDown).addStd(QChar(0xB1),ItalicOff|BoldOff|FlipSymbolUpDown);
|
||||
symbols["multimap"]=MathOperatorSymbolUnicode(QChar(0x22B8)).addMathOperatorHtml("⊸");
|
||||
symbols["nabla"]=MathOperatorSymbolUnicode(QChar(0x2207)).addMathOperatorHtml("∇").addMathOperatorWinSymbol(QChar(0xD1));
|
||||
symbols["ne"]=MathOperatorSymbolUnicode(QChar(0x2260)).addMathOperatorHtml("≠").addMathOperatorWinSymbol(QChar(0xB9));
|
||||
symbols["nabla"]=NarrowMathOperatorSymbolUnicode(QChar(0x2207)).addMathOperatorHtml("∇").addMathOperatorWinSymbol(QChar(0xD1));
|
||||
symbols["ne"]=NarrowMathOperatorSymbolUnicode(QChar(0x2260)).addMathOperatorHtml("≠").addMathOperatorWinSymbol(QChar(0xB9));
|
||||
symbols["nearrow"]=UprightSymbolUnicode(QChar(0x2197)).addUprightHtml("↗");
|
||||
{ auto s=MathOperatorSymbolUnicode(QChar(0x00AC)).addMathOperatorHtml("¬").addMathOperatorWinSymbol(QChar(0xD8));
|
||||
symbols["neg"]=s; symbols["lnot"]=s; }
|
||||
symbols["neq"]=MathOperatorSymbolUnicode(QChar(0x2260)).addMathOperatorHtml("≠").addMathOperatorWinSymbol(QChar(0xB9)).addStd("=", ItalicOff|BoldOff|DrawSlash);
|
||||
symbols["nexists"]=MathOperatorSymbolUnicode(QChar(0x2204)).addMathOperatorHtml("∄").addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight|DrawSlash).addMathOperatorWinSymbol(QChar(0x24), ItalicOff|BoldOff|DrawSlash);
|
||||
symbols["ni"]=MathOperatorSymbolUnicode(QChar(0x220B)).addMathOperatorHtml("∋").addMathOperatorWinSymbol(QChar(0xCE), ItalicOff|BoldOff|FlipSymbolLeftRight);
|
||||
symbols["nmid"]=MathOperatorSymbolUnicode(QChar(0x2224)).addMathOperatorHtml("∤");
|
||||
symbols["notin"]=MathOperatorSymbolUnicode(QChar(0x2209)).addMathOperatorHtml("∉").addMathOperatorWinSymbol(QChar(0xCF));
|
||||
symbols["notni"]=MathOperatorSymbolUnicode(QChar(0x220C)).addMathOperatorHtml("∌");
|
||||
symbols["nexists"]=NarrowMathOperatorSymbolUnicode(QChar(0x2204)).addMathOperatorHtml("∄").addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight|DrawSlash).addMathOperatorWinSymbol(QChar(0x24), ItalicOff|BoldOff|DrawSlash);
|
||||
symbols["ni"]=NarrowMathOperatorSymbolUnicode(QChar(0x220B)).addMathOperatorHtml("∋").addMathOperatorWinSymbol(QChar(0xCE), ItalicOff|BoldOff|FlipSymbolLeftRight);
|
||||
symbols["nmid"]=NarrowMathOperatorSymbolUnicode(QChar(0x2224)).addMathOperatorHtml("∤");
|
||||
symbols["notin"]=NarrowMathOperatorSymbolUnicode(QChar(0x2209)).addMathOperatorHtml("∉").addMathOperatorWinSymbol(QChar(0xCF));
|
||||
symbols["notni"]=NarrowMathOperatorSymbolUnicode(QChar(0x220C)).addMathOperatorHtml("∌");
|
||||
symbols["nparallel"]=MathOperatorSymbolUnicode(QChar(0x2226)).addMathOperatorHtml("∦");
|
||||
symbols["nwarrow"]=UprightSymbolUnicode(QChar(0x2196)).addUprightHtml("↖");
|
||||
symbols["odot"]=MathOperatorSymbolUnicode(QChar(0x2299)).addMathOperatorHtml("⊙");
|
||||
@ -791,7 +799,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
symbols["oplus"]=MathOperatorSymbolUnicode(QChar(0x2295)).addMathOperatorHtml("⊕").addMathOperatorWinSymbol(QChar(0xC5));
|
||||
symbols["oslash"]=MathOperatorSymbolUnicode(QChar(0x2298)).addMathOperatorHtml("⊘");
|
||||
symbols["otimes"]=MathOperatorSymbolUnicode(QChar(0x2297)).addMathOperatorHtml("⊗").addMathOperatorWinSymbol(QChar(0xC4));
|
||||
symbols["parallel"]=MathOperatorSymbolUnicode(QChar(0x2225)).addMathOperatorHtml("∥").addMathOperatorStd("||");
|
||||
symbols["parallel"]=NarrowMathOperatorSymbolUnicode(QChar(0x2225)).addMathOperatorHtml("∥").addMathOperatorStd("||");
|
||||
symbols["pm"] = MathOperatorSymbol(QChar(0xB1), "±").addMathOperatorWinSymbol(QChar(0xB1));
|
||||
symbols["prec"]=MathOperatorSymbolUnicode(QChar(0x227A)).addMathOperatorHtml("≺");
|
||||
symbols["prod"]=NarrowMathOperatorSymbolUnicode(QChar(0x220F)).addMathOperatorWinSymbol(QChar(0xD5), 1.8, 0.1).addMathOperatorHtml("∏").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
|
||||
@ -821,13 +829,13 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
|
||||
{ auto s=UprightSymbolUnicode(QChar(0x2192)).addUprightHtml("→").addUprightWinSymbol(QChar(0xAE));
|
||||
symbols["to"]=s; symbols["rightarrow"]=s; }
|
||||
symbols["top"]=MathOperatorSymbolUnicode(QChar(0x22A4)).addMathOperatorHtml("⊤").addMathOperatorWinSymbol(QChar(0x5E));
|
||||
symbols["triangle"]=MathOperatorSymbolUnicode(QChar(0x2206));
|
||||
symbols["triangle"]=NarrowMathOperatorSymbolUnicode(QChar(0x2206));
|
||||
symbols["uparrow"]=UprightSymbolUnicode(QChar(0x2191)).addUprightHtml("↑").addUprightWinSymbol(QChar(0xAD));
|
||||
symbols["updownarrow"]=UprightSymbolUnicode(QChar(0x2195)).addUprightHtml("↕");
|
||||
symbols["upharpoonleft"]=UprightSymbolUnicode(QChar(0x21BF)).addUprightHtml("↿");
|
||||
symbols["upharpoonright"]=UprightSymbolUnicode(QChar(0x21BE)).addUprightHtml("↾");
|
||||
symbols["vartriangleleft"]=MathOperatorSymbolUnicode(QChar(0x22B2)).addMathOperatorHtml("⊲");
|
||||
symbols["vdots"]=MathOperatorSymbolUnicode(QChar(0x22EE)).addMathOperatorHtml("⋮");
|
||||
symbols["vartriangleleft"]=NarrowMathOperatorSymbolUnicode(QChar(0x22B2)).addMathOperatorHtml("⊲");
|
||||
symbols["vdots"]=UprightSymbolUnicode(QChar(0x22EE)).addMathOperatorHtml("⋮");
|
||||
symbols["vee"]=MathOperatorSymbolUnicode(QChar(0x2228)).addMathOperatorHtml("∨").addMathOperatorWinSymbol(QChar(0xDA));
|
||||
symbols["vdash"]=MathOperatorSymbolUnicode(QChar(0x22A2)).addMathOperatorHtml("⊢");
|
||||
symbols["dashv"]=MathOperatorSymbolUnicode(QChar(0x22A3)).addMathOperatorHtml("⊣");
|
||||
|
@ -289,6 +289,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
|
||||
static SymbolFullProps NarrowMathOperatorSymbolStd(const QString& symbol);
|
||||
/** \brief constructs a SymbolProps for a narrow math-operator symbol like \c \\pm ... in unicode-full-encoding, i.e. ItalicOff, BoldOff, SmallExtendWidthInMathmode */
|
||||
static SymbolFullProps NarrowMathOperatorSymbolStd(const QString& symbol, const QString& symbolHTML);
|
||||
/** \brief constructs a SymbolProps for a narrow math-operator like \c \\sin ..., i.e. ItalicOff, BoldOff, HeightIsAscent, ExtendWidthInMathmode */
|
||||
static SymbolFullProps NarrowMathOperatorText(const QString& op);
|
||||
/** \brief constructs a SymbolProps with explicit HTML for a narrow math-operator like \c \\sin ..., i.e. ItalicOff, BoldOff, HeightIsAscent, ExtendWidthInMathmode */
|
||||
static SymbolFullProps NarrowMathOperatorText(const QString& op, const QString& ophtml);
|
||||
|
||||
|
||||
/** \brief symbols that can be generated in any standard-font */
|
||||
|
@ -337,6 +337,16 @@ QString JKQTMathTextTextNode::getTypeName() const
|
||||
return QLatin1String("JKQTMathTextTextNode(")+text+")";
|
||||
}
|
||||
|
||||
void JKQTMathTextTextNode::removeTrailingWhitespace()
|
||||
{
|
||||
while (text.size()>0 && text[text.size()-1].isSpace()) text=text.left(text.size()-1);
|
||||
}
|
||||
|
||||
void JKQTMathTextTextNode::removeLeadingWhitespace()
|
||||
{
|
||||
while (text.size()>0 && text[0].isSpace()) text=text.right(text.size()-1);
|
||||
}
|
||||
|
||||
QString JKQTMathTextTextNode::textTransform(const QString &text, const JKQTMathTextEnvironment ¤tEv) const
|
||||
{
|
||||
QString txt=text;
|
||||
|
@ -68,6 +68,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextTextBaseN
|
||||
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 remove trailing whitespace, is used by simplifyJKQTMathTextNode() */
|
||||
void removeTrailingWhitespace();
|
||||
/** \brief remove leading whitespace, is used by simplifyJKQTMathTextNode() */
|
||||
void removeLeadingWhitespace();
|
||||
protected:
|
||||
/** \brief defines how a character shold be drawn, used by splitTextForLayout */
|
||||
enum FontMode {
|
||||
|