JKQTMathText:

- NEW: added environment-modifying commands for font sizes: \c \\tiny ... \c \\normalsize ... \c \\Huge
- NEW: added environment-modifying commands for text color: \c {\\color{COL}...}
- NEW: added environment-modifying commands for text formatting: \c {\\bfseries...}, \c {\\itshape...}, \c {\\bf...}, \c {\\it...}, \c {\\sffamily...}, \c {\\ttfamily...}, ...
- REFACTORING: split up several .h/.cpp-files in nodes subdirectory
This commit is contained in:
jkriege2 2022-08-19 12:16:00 +02:00
parent bc4d5e2b86
commit 5722970496
96 changed files with 3078 additions and 1749 deletions

View File

@ -2,8 +2,10 @@
\defgroup jkqtmathtext_renderingmodel JKQTMathText Rendering Model
\ingroup jkqtmathtext_general
\section jkqtmathtext_renderingmodel_basics Basics
JKQTMathText parses an (LaTeX) input string of mathematicalkmarkup and in a first step generates a memory representation of the it (cf. \ref jkqtmathtext_items ).
JKQTMathText parses an input string of mathematical markup (i.e. LaTeX) and in a first step generates a memory representation of the it (cf. \ref jkqtmathtext_items ).
Then this memory representation is used to draw the represented math using the renndering API of <a href="https://doc.qt.io/qt-6/qpainter.html">QPainter</a>.
As an example, we look at the following LaTeX markup, representing the solution to a quadratic equation:
@ -25,7 +27,10 @@
\image html jkqtmathtext/jkqtmathtext_doc_quadraticeq_tree.png
\note The memory representation is independent of the actual math markup language (e.g. LaTeX) which was initially parsed.
But of course it is modelled, so the features of the supported markup languages are supported by the memory model.
But of course it is modelled, so the features of the supported markup languages are supported by the memory model.
\note Also the parser performs optimizations on the tree, e.g. by removing a JKQTMathTextHorizontalListNode if it contains
only one entry!
You can see that each node corresponds to a box, if these are overlayed over the rendering:
@ -38,5 +43,27 @@
\image html jkqtmathtext_node_geo.png
\section jkqtmathtext_renderingmodel_linebreaks Linebreaks and Blocks
As described above, JKQTMathText represents the mathematicl markup as a tree of boxes. When calling JKQTMathText::parse() without
any additional parameters, the base-node is a JKQTMathTextVerticalListNode that can represent several lines of text. A new line
is started when a \c \\\\ or \c \\newline command is found. Automatic line breaking is not performed, i.e. each line can possibly
become very long, also longer than the available space for drawing! Also lineabreaks are only allowed directly in the current
context. You cannot write
\code.tex
\textbf{line1\\text2}
\endcode
but have to write
\code.tex
\textbf{line1}\\
\textbf{line2}
\endcode
With environment-altering instructions like \c \\bfserie or \c \\it this can be overcome: If you write
\code.tex
\bf line1\\
line2
\endcode
both lines are typeset in bold face!
*/

View File

@ -22,17 +22,29 @@
- operators are typeset with additional space around them
.
\section JKQTMathTextSuppoertedLaTeXFontProps Font Properties
The supported LaTeX subset is listes below. Please note that some commands are used differently than in actual LaTeX.
For example \c \\bf is just a renamed form of \c \\textbf and used as \c \\bf{...} and NOT as \c {\\bf...} .
\section JKQTMathTextSuppoertedLaTeXFormatting Formatting
The supported LaTeX subset for formatting text is listed in this section.
\subsection JKQTMathTextSuppoertedLaTeXFontPropsFontProps Font Properties
JKQTMathText supports these instructions for font properties:
- \c \\bf{...} \c \\textbf{...} \c \\mathbf{...}: draw the contained text in bold face \image html jkqtmathtext/jkqtmathtext_bold.png
- \c \\it{...} \c \\textit{...} \c \\mathit{...} : draw the contained text in italic face \image html jkqtmathtext/jkqtmathtext_italic.png
- \c \\rm{...} \c \\textrm{...} \c \\mathrm{...} \c \\mbox{...} : draw the contained text in normal upright roman font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\sf{...} \c \\textsf{...} \c \\mathsf{...} : draw the contained text in normal upright sans-serif font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\textcal{...} \c \\mathcal{...} : draw the contained text in caligraphic font face \image html jkqtmathtext/jkqtmathtext_cal.png
- \c \\textfrak{...} \c \\mathfrak{...} : draw the contained text in fraktur font face \image html jkqtmathtext/jkqtmathtext_frak.png
- \c \\textscript{...} \c \\mathscript{...} : draw the contained text in script font face \image html jkqtmathtext/jkqtmathtext_script.png
- \c \\textbf{...} \c \\mathbf{...} \c {\\bf...} \c {\\bfseries...}: draw the contained text in bold face \image html jkqtmathtext/jkqtmathtext_bold.png
- \c \\textit{...} \c \\mathit{...} \c {\\it...} \c {\\itshape...} : draw the contained text in italic face \image html jkqtmathtext/jkqtmathtext_italic.png
- \c \\emph{...} : emphasize text \image html jkqtmathtext/jkqtmathtext_emph.png
- \c \\textsc{...} \c \\mathsc{...} \c {\\sc...} \c {\\scshape...} : draw the text in small caps \image html jkqtmathtext/jkqtmathtext_sc.png
- \c \\uppercase{...} : draw the text in all uppercase \image html jkqtmathtext/jkqtmathtext_uppercase.png
- \c \\lowercase{...} : draw the text in all uppercase \image html jkqtmathtext/jkqtmathtext_lowercase.png
.
\subsection JKQTMathTextSuppoertedLaTeXFontPropsFonts Font Selection
These instructions are supported to select a font:
- \c \\textrm{...} \c \\mathrm{...} \c {\\rm...} \c {\\rmfamily...} \c \\mbox{...} : draw the contained text in normal upright roman font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\textsf{...} \c \\mathsf{...} \c {\\sf...} \c {\\sffamily...} : draw the contained text in normal upright sans-serif font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\textcal{...} \c \\mathcal{...} \c {\\cal...} : draw the contained text in caligraphic font face \image html jkqtmathtext/jkqtmathtext_cal.png
- \c \\textfrak{...} \c \\mathfrak{...} \c {\\frak...} : draw the contained text in fraktur font face \image html jkqtmathtext/jkqtmathtext_frak.png
- \c \\textscript{...} \c \\mathscript{...} \c {\\script...} : draw the contained text in script font face \image html jkqtmathtext/jkqtmathtext_script.png
- \c \\texttt{...} \c \\mathtt{...} \c {\\tt...} \c {\\ttshape...} : draw text in typewriter font \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\userfont{font}{...} : draw text in a user-specific font, available on the system \image html jkqtmathtext/jkqtmathtext_userfont.png (generated by <code>default, \\userfont{Arial}{Arial}, \\userfont{Comic Sans MS}{Comic Sans MS}</code> )
- \c \\textbb{...} \c \\mathbb{...} : draw the contained text in blackboard font face \image html jkqtmathtext/jkqtmathtext_bb.png
Blackboard fonts are not widely available on target systems (viable fonts are e.g. <code>"Double Stroke", "CloisterOpenFace BT", "GoudyHandtooled BT", "Castellar", "MathJax_AMS", "Castellar Standard", "MathJax_AMS Standard", "Colonna MT"</code>). But the most important blackboard characters are usually available in the higher unicode codepoints of Fonts specialized for math (e.g. XIST, STIX, ASANA). Therefore JKQTMathText supports using these characters, or simulating a blackboard font in addition to using one of the fonts above. You can set that by setting JKQTMathText::setFontBlackboradMode() with one of the options from JKQTMathTextBlackboradDrawingMode:
- MTBBDMfontDirectly: use a blackboard font specified by JKQTMathText::setFontBlackboard() \image html jkqtmathtext/jkqtmathtext_bb_font_directly.png using \c JKQTMathText::setFontBlackboard("Castellar")
@ -40,23 +52,65 @@
- MTBBDMunicodeCharactersOrFontDirectly: \image html jkqtmathtext/jkqtmathtext_bb_unicode_or_font_directly.png using \c JKQTMathText::setFontBlackboard("Castellar")
- MTBBDMunicodeCharactersOrSimulate: \image html jkqtmathtext/jkqtmathtext_bb_unicode_or_simulate.png using \c JKQTMathText::setFontBlackboard("Arial")
.
- \c \\script{...} \c \\textscript{...} \c \\mathscript{...} : draw the contained text in a script font face \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\sc{...} : draw the text in small caps \image html jkqtmathtext/jkqtmathtext_sc.png
- \c \\textscript{...} \c \\mathscript{...} \c {\\script...} : draw the contained text in a script font face \image html jkqtmathtext/jkqtmathtext_fonts.png
.
\subsection JKQTMathTextSuppoertedLaTeXFontPropsFontSizes Font Sizes
JKQTMathText supports these instructions for font size:
- \c {\\tiny...}
- \c {\\ssmall...}
- \c {\\scriptsize...}
- \c {\\footnotesize...}
- \c {\\small...}
- \c {\\normalsize...} switches back to the default font size
- \c {\\large...}
- \c {\\Large...}
- \c {\\LARGE...}
- \c {\\huge...}
- \c {\\Huge...}
- \c {\\userfontsize{pointsize}...}
.
\image html jkqtmathtext/jkqtmathtext_fontsizes.png
JKQTMathText supports these instructions for font size in math mode:
- \c $\\displaystyle...$ switches back to the default font size
- \c $\\textstyle...$ switches back to the default font size
- \c $\\scriptstyle...$
- \c $\\scriptscriptstyle...$
.
\image html jkqtmathtext/jkqtmathtext_mathfontsizes.png
\subsection JKQTMathTextSuppoertedLaTeXUnderlinesEtz Text Decoration: Underline, Overlines, Strikeout, ...
JKQTMathText supports several LaTeX instruction to decorate the text with underlines, overlines, etc:
- \c \\ul{...} , \c \\underline{...} , \c \\uline{...} \c \\underlined{...} : draw the text with underlining \image html jkqtmathtext/jkqtmathtext_ul.png
- \c \\uul{...} : draw the text with double-underlining \image html jkqtmathtext/jkqtmathtext_uul.png
- \c \\dashuline{...} : draw the text with dashed underlining \image html jkqtmathtext/jkqtmathtext_dashuline.png
- \c \\dotuline{...} : draw the text with dotted underlining \image html jkqtmathtext/jkqtmathtext_dotuline.png
- \c \\ol{...} \c \\overline{...} \c \\overlined{...} : draw the text with overlining \image html jkqtmathtext/jkqtmathtext_ol.png
- \c \\ool{...} : draw the text with double-overlining \image html jkqtmathtext/jkqtmathtext_ool.png
- \c \\tt{...} \c \\texttt{...} \c \\mathtt{...} : draw text in typewriter font \image html jkqtmathtext/jkqtmathtext_fonts.png
- \c \\textcolor{color}{...} \c \\color{color} \c \\mathcolor{color}{...} : draw colored text \image html jkqtmathtext/jkqtmathtext_colored.png
- \c \\userfont{font}{...} : draw text in a user-specific font, available on the system \image html jkqtmathtext/jkqtmathtext_userfont.png (generated by <code>default, \\userfont{Arial}{Arial}, \\userfont{Comic Sans MS}{Comic Sans MS}</code> )
- \c \\sout{...} : strike out the text \image html jkqtmathtext/MTDstrike.png
- \c \\cancel{...} : slanted strike out the text \image html jkqtmathtext/MTDcancel.png
- \c \\bcancel{...} : back-strike out the text \image html jkqtmathtext/MTDbcancel.png
- \c \\xcancel{...} : x-strike out the text \image html jkqtmathtext/MTDxcancel.png
- <code>\\vec{x} \\dot{x} \\ddot{x} \\overline{x} \\underline{x} \\hat{x} \\tilde{x} \\uul{x} \\ool{x} \\bar{x} \\arrow{x} \\widehat{x} \\widetilde{x} ...</code>: Decorations over/under symbols \image html jkqtmathtext/jkqtmathtext_mathdeco.png
\image html jkqtmathtext/jkqtmathtext_mathaccents.png
.
\subsection JKQTMathTextSuppoertedLaTeXTextColor Text Color
JKQTMathText supports several standard commands to set the text color:
- \c \\textcolor{color}{...} \c \\mathcolor{color}{...} : draw colored text \image html jkqtmathtext/jkqtmathtext_colored.png
- \c {\\color{color}...} : same as above
.
You can use all color names like (\c black , \c blue , \c yellow , \c transparent , ... see e.g. <a href="https://www.w3.org/TR/SVG11/types.html#ColorKeywords">https://www.w3.org/TR/SVG11/types.html#ColorKeywords</a> or <a href="https://en.wikipedia.org/wiki/Web_colors">https://en.wikipedia.org/wiki/Web_colors</a>) or a color defined via \c #RGB \c #RRGGBB \c #AARRGGBB \c #RRRGGGBBB \c #RRRRGGGGBBBB (where R,G,B are HEX-digits)
\see jkqtp_String2QColor()
\section JKQTMathTextSuppoertedLaTeXBoxes Boxes
@ -69,11 +123,11 @@
- \c \\dashbox{...} , \c \\dbox{...} : draw a dashed box \image html jkqtmathtext/jkqtmathtext_dashbox.png
- \c \\dottedbox{...} : draw a dottted box \image html jkqtmathtext/jkqtmathtext_dottedbox.png
- \c \\ovaldoublebox{...} : draw a double oval box \image html jkqtmathtext/jkqtmathtext_doubleovalbox.png
- \c \\colorbox{bordercolor}{...} : draw a colored box \image html jkqtmathtext/jkqtmathtext_colorbox.png
- \c \\shaded{backgroundcolor}{...} : draw a filled box \image html jkqtmathtext/jkqtmathtext_shaded.png
- \c \\snugshade{...} : draw text with a snug shade around it \image html jkqtmathtext/jkqtmathtext_snugshade.png
- \c \\fcolorbox{bordercolor}{backgroundcolor}{...} : draw a colored, filled box \image html jkqtmathtext/jkqtmathtext_fcolorbox.png
- \c \\colorbox{color}{...} : draw a colored box around text \image html jkqtmathtext/jkqtmathtext_colorbox.png
- \c \\colorbox{bordercolor}{...} : draw a colored box (see \ref JKQTMathTextSuppoertedLaTeXTextColor for accepted colors) \image html jkqtmathtext/jkqtmathtext_colorbox.png
- \c \\shaded{backgroundcolor}{...} : draw a filled box (see \ref JKQTMathTextSuppoertedLaTeXTextColor for accepted colors) \image html jkqtmathtext/jkqtmathtext_shaded.png
- \c \\snugshade{...} : draw text with a snug shade around it (see \ref JKQTMathTextSuppoertedLaTeXTextColor for accepted colors) \image html jkqtmathtext/jkqtmathtext_snugshade.png
- \c \\fcolorbox{bordercolor}{backgroundcolor}{...} : draw a colored, filled box (see \ref JKQTMathTextSuppoertedLaTeXTextColor for accepted colors) \image html jkqtmathtext/jkqtmathtext_fcolorbox.png
- \c \\colorbox{color}{...} : draw a colored box around text (see \ref JKQTMathTextSuppoertedLaTeXTextColor for accepted colors) \image html jkqtmathtext/jkqtmathtext_colorbox.png
.
@ -90,7 +144,9 @@
\section JKQTMathTextSuppoertedLaTeXSymbols Symbols and special characters
These instructions draw different types of characters and symbols:
- \c \\alpha ... : display the according greek letter (see \ref jkqtmathtext_supportedlatexsymbols ) \image html jkqtmathtext/jkqtmathtext_greek.png
- \c \\alpha ... : display the according greek letter in italic style (see \ref jkqtmathtext_supportedlatexsymbols ) \image html jkqtmathtext/jkqtmathtext_greek.png
- \c \\upalpha ... : display the according upright greek letter. This letter is always upright, independent of the surrounding environment (see \ref jkqtmathtext_supportedlatexsymbols ) \image html jkqtmathtext/jkqtmathtext_upgreek.png
- \c \\textalpha ... : display the according greek letter with italic style defined by the current environment (i.e. italic in mathmode or inside \c \\textit{\\alpha} and upright in text mode). (see \ref jkqtmathtext_supportedlatexsymbols ) \image html jkqtmathtext/jkqtmathtext_textgreek.png
- \c \\charDECIMAL and \c \\char\"HEX and \c \\char\'OCTAL : draws a unicode character from its 32-bit codepoint \image html jkqtmathtext/jkqtmathtext_char.png (generated by <code>A: \\char65, circonflex: \\char\"109 accent: \\char\'351</code>)
- \c \\unicode{HEX} and \c \\usym{HEX} : draws a unicode character from its 32-bit codepoint \image html jkqtmathtext/jkqtmathtext_unicode.png (generated by <code>star: \\unicode{2605}, circonflex: \\unicode{109} emoticons: \\usym{1F440} \\usym{1F929}</code>)
- \c \\utfeight{HEX} : draws a unicode character from its UTF-8 encoding \image html jkqtmathtext/jkqtmathtext_utf8.png (generated by <code>star: \\utfeight{e29885} emoticons \\utfeight{F09F9881} \\utfeight{f09f98bb}</code>)
@ -107,8 +163,6 @@
- \c - : draw a hyphen \image html jkqtmathtext/jkqtmathtext_hyphen.png
- \c -- : draw an en-dash \image html jkqtmathtext/jkqtmathtext_endash.png
- \c --- : draw an em-dash \image html jkqtmathtext/jkqtmathtext_emdash.png
- <code>\\vec{x} \\dot{x} \\ddot{x} \\overline{x} \\underline{x} \\hat{x} \\tilde{x} \\uul{x} \\ool{x} \\bar{x} \\arrow{x} \\widehat{x} \\widetilde{x} ...</code>: Decorations over/under symbols \image html jkqtmathtext/jkqtmathtext_mathdeco.png
\image html jkqtmathtext/jkqtmathtext_mathaccents.png
.

View File

@ -39,7 +39,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
<li></li>
</ul></li>
<li>JKQTMathText:<ul>
<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></li>
</ul></li>
</ul>

View File

@ -95,6 +95,9 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>NEW: added support for \\bigl,\\bigr,\\Bigr,... commands for fixed-size but enlarged paramtheses</li>
<li>NEW: added support for \\begin{verbatim}...\\end{verbatim}, \\begin{verbatim*}...\\end{verbatim*}</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: added environment-modifying commands for font sizes: \c \\tiny ... \c \\normalsize ... \c \\Huge </li>
<li>NEW: added environment-modifying commands for text color: \c {\\color{COL}...} </li>
<li>NEW: added environment-modifying commands for text formatting: \c {\\bfseries...}, \c {\\itshape...}, \c {\\bf...}, \c {\\it...}, \c {\\sffamily...}, \c {\\ttfamily...}, ... </li>
</ul></li>
</ul>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -5,9 +5,19 @@ jkqtmathtext_bold.png
jkqtmathtext_italic.png
{\backslash}textit: \textit{italic text}
---
jkqtmathtext_emph.png
{\backslash}emph in text: \emph{emphasized} non-emphasized\\
{\backslash}emph in italic: \textit{\emph{emphasized} non-emphasized}
---
jkqtmathtext_sc.png
{\backslash}textsc: \textsc{SmallCaps text}
---
jkqtmathtext_uppercase.png
{\backslash}uppercase: \uppercase{All upper-Case text}
---
jkqtmathtext_lowercase.png
{\backslash}lowercase: \lowercase{All LOWER-Case text}
---
jkqtmathtext_tt.png
{\backslash}texttt: \textsc{Typewriter text}
---
@ -93,4 +103,48 @@ Schrödinger's equation: $\left[-\frac{\hbar^2}{2m}\frac{\partial^2}{\partial x^
---
schreq_normalmode.png
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)
---
jkqtmathtext_fontsizes.png
\begin{array}{|l|c|}
\hline
\textbf{Commmand} & \textbf{Output} \\
\hline
{\backslash}tiny: & {\tiny sample text} \\
{\backslash}ssmall: & {\ssmall sample text} \\
{\backslash}scriptsize: & {\scriptsize sample text} \\
{\backslash}footnotesize: & {\footnotesize sample text} \\
{\backslash}small: & {\small sample text} \\
{\backslash}normalsize: & {\normalsize sample text} \\
{\backslash}large: & {\large sample text} \\
{\backslash}Large: & {\Large sample text} \\
{\backslash}LARGE: & {\LARGE sample text} \\
{\backslash}huge: & {\huge sample text} \\
{\backslash}Huge: & {\Huge sample text} \\
\hline
{\backslash}userfontsize\{ptsize\}: & {\userfontsize{5} 5pt} {\userfontsize{10} 10pt} {\userfontsize{30} 30pt} {\userfontsize{40} 40pt}\\
\hline
\end{array}
---
jkqtmathtext_mathfontsizes.png
\begin{array}{|l|c|}
\hline
\textbf{Commmand} & \textbf{Output} \\
\hline
default text-mode: & outsize: x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i \\
default math-mode: & outsize: $ x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
{\backslash}displaystyle: & outsize: $\displaystyle x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
{\backslash}textstyle: & outsize: $\textstyle x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
{\backslash}scriptstyle: & outsize: $\scriptstyle x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
{\backslash}scriptscriptstyle: & outsize: $\scriptscriptstyle x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
\hline
\end{array}
---
jkqtmathtext_mathstyle.png
\begin{array}{|l|c|}
\hline
\textbf{Style} & \textbf{Output} \\
\hline
display-style: & outsize: $\displaystyle x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
text-style: & outsize: $\textstyle x^2\ \mathcal{O}(n^2)\ \frac{1}{2}\cdot\sum_{i=0}^\infty k_i$ \\
\hline
\end{array}

View File

@ -11,6 +11,13 @@ hyphen: -
jkqtmathtext_greek.png
$\alpha\beta\gamma\xi\chi\nu\Gamma\Delta\Omega$
---
jkqtmathtext_upgreek.png
$\upalpha\upbeta\upgamma\upxi\upchi\upnu\upGamma\upDelta\upOmega$
---
jkqtmathtext_textgreek.png
text: \textalpha\textbeta\textgamma\textxi\textchi\textnu\textGamma\textDelta\textOmega\\
italic: {\itshape\textalpha\textbeta\textgamma\textxi\textchi\textnu\textGamma\textDelta\textOmega}
---
jkqtmathtext_char.png
A: \char65, circonflex: \char"109 accent: \char'351
---

View File

@ -4,6 +4,7 @@
#include <sstream>
#include "jkqtcommon/jkqtpstringtools.h"
#include "jkqtmathtext/jkqtmathtext.h"
#include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h"
#include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h"
@ -15,7 +16,12 @@
#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h"
#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextwhitespacenode.h"
#include "jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.h"
#include "jkqtmathtext/nodes/jkqtmathtexthorizontallistnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextnoopnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextverbatimnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextverticallistnode.h"
TestForm::TestForm(QWidget *parent) :
QWidget(parent),
@ -41,6 +47,24 @@ TestForm::TestForm(QWidget *parent) :
"\\end{matrix}");
ui->cmbTestset->addItem("text: umlaute", umla);
ui->cmbTestset->addItem("text: umlaute and fonts", "rm: \\textrm{"+testTextUmla+"}, sf: \\textsf{"+testTextUmla+"}, tt: \\texttt{"+testTextUmla+"}, cal: \\textcal{"+testTextUmla+"}, scr: \\textscr{"+testTextUmla+"}, bb: \\textbb{"+testTextUmla+"}, frak: \\textfrak{"+testTextUmla+"}, ");
ui->cmbTestset->addItem("text: font sizes", "\\begin{array}{|lll|llc|}\\hline"
"\\textbf{Commmand} &\\ \\ \\ &\\ \\ \\ & \\textbf{Output}\\\\"
"\\hline"
"{\\backslash}tiny: &&& {\\tiny sample text} \\\\"
"{\\backslash}ssmall: &&& {\\ssmall sample text} \\\\"
"{\\backslash}scriptsize: &&& {\\scriptsize sample text} \\\\"
"{\\backslash}footnotesize: &&& {\\footnotesize sample text} \\\\"
"{\\backslash}small: &&& {\\small sample text} \\\\"
"{\\backslash}normalsize: &&& {\\normalsize sample text} \\\\"
"{\\backslash}large: &&& {\\large sample text} \\\\"
"{\\backslash}Large: &&& {\\Large sample text} \\\\"
"{\\backslash}LARGE: &&& {\\LARGE sample text} \\\\"
"{\\backslash}huge: &&& {\\huge sample text} \\\\"
"{\\backslash}Huge: &&& {\\Huge sample text} \\\\"
"\\hline"
"\\end{array}");
ui->cmbTestset->addItem("text: multi-line", "line 1\\\\\\bf line 2 in bold \\\\line 3 still bold \\it now also italic");
ui->cmbTestset->addItem("text: dashes", "hyphen: - endash: -- emdash: --- \\ \\ \\ endash--within text\\ \\ \\ emdash---within text\\ \\ \\ enemdash-----within text\\ \\ \\ ememdash------within text");
ui->cmbTestset->addItem("math: fonts", "base: $"+testText+"$, rm: $\\mathrm{"+testText+"}$, sf: $\\mathsf{"+testText+"}$, tt: $\\mathtt{"+testText+"}$, cal: $\\mathcal{"+testText+"}$, scr: $\\mathscr{"+testText+"}$, bb: $\\mathbb{"+testText+"}$, frak: $\\mathfrak{"+testText+"}$, ");
ui->cmbTestset->addItem("math: umlaute", "$"+umla_math+"$");
@ -76,6 +100,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("math: std dev", "$\\sigma_x=\\sqrt{\\langle (x-\\langle x\\rangle)^2\\rangle}=\\sqrt{\\frac{1}{N-1}\\cdot\\left( \\sum_{i=1}^N{x_i}^2-\\frac{1}{N}\\cdot\\left(\\sum_{i=1}^Nx_i\\right)^2\\right)}$");
ui->cmbTestset->addItem("math: std dev 2", "$\\sigma_x=\\sqrt{\\langle (x-\\langle x\\rangle)^2\\rangle}=\\sqrt{\\frac{1}{N-1}\\cdot\\left( \\sum_{i=1}^Nx_i^2-\\frac{1}{N}\\cdot\\left(\\sum_{i=1}^Nx_i\\right)^2\\right)}$");
ui->cmbTestset->addItem("math: rotation matrix", "$\\mathrm{\\mathbf{M}}(\\alpha) = \\left(\\begin{matrix}\\cos(\\alpha)+n_x^2\\cdot (1-\\cos(\\alpha)) & n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))-n_z\\cdot \\sin(\\alpha) & n_x\\cdot n_z\\cdot (1-\\cos(\\alpha))+n_y\\cdot \\sin(\\alpha)\\\\n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_z\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_y^2\\cdot (1-\\cos(\\alpha)) & n_y\\cdot n_z\\cdot (1-\\cos(\\alpha))-n_x\\cdot \\sin(\\alpha)\\\\n_z\\cdot n_x\\cdot (1-\\cos(\\alpha))-n_y\\cdot \\sin(\\alpha) & n_z\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_x\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_z^2\\cdot (1-\\cos(\\alpha))\\end{matrix}\\right)$");
ui->cmbTestset->addItem("math: rotation matrix, \\tiny", "$\\mathrm{\\mathbf{M}}(\\alpha) = \\left(\\begin{matrix}\\tiny\\cos(\\alpha)+n_x^2\\cdot (1-\\cos(\\alpha)) & n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))-n_z\\cdot \\sin(\\alpha) & n_x\\cdot n_z\\cdot (1-\\cos(\\alpha))+n_y\\cdot \\sin(\\alpha)\\\\n_x\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_z\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_y^2\\cdot (1-\\cos(\\alpha)) & n_y\\cdot n_z\\cdot (1-\\cos(\\alpha))-n_x\\cdot \\sin(\\alpha)\\\\n_z\\cdot n_x\\cdot (1-\\cos(\\alpha))-n_y\\cdot \\sin(\\alpha) & n_z\\cdot n_y\\cdot (1-\\cos(\\alpha))+n_x\\cdot \\sin(\\alpha) & \\cos(\\alpha)+n_z^2\\cdot (1-\\cos(\\alpha))\\end{matrix}\\right)$");
ui->cmbTestset->addItem("math: like in label at bottom", "$\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)$");
ui->cmbTestset->addItem("text: like in label at bottom)", "\\left(\\left[\\sqrt{2\\pi\\cdot\\int_{-\\infty}^\\infty f(x)\\;\\mathrm{d}x}\\right]\\right)");
ui->cmbTestset->addItem("text 0", "text");
@ -94,6 +119,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("text: \\begin{verbatim*}", "outside\\begin{verbatim*}\ninside \\LaTeX verbatim\n 2nd verbaimline\n\t3rd line\n\\end{verbatim*}");
ui->cmbTestset->addItem("text: \\begin{lstlistings}", "outside\\begin{lstlisting}\nint main() {\n printf(\"Hello World\\n\");\n}\n\\end{lstlisting}");
ui->cmbTestset->addItem("text: flushleft", "\\begin{flushleft}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{flushleft}");
ui->cmbTestset->addItem("text: flushleft, tiny", "\\begin{flushleft}\\tiny text\\\\\\textbf{2^{nd} line of text}\\\\\\color{red}last \\textit{line!} $\\frac{1}{2}$\\end{flushleft}");
ui->cmbTestset->addItem("text: flushright", "\\begin{flushright}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{flushright}");
ui->cmbTestset->addItem("text: center", "\\begin{center}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{center}");
ui->cmbTestset->addItem("text: framed", "\\begin{framed}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{framed}");
@ -476,6 +502,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
JKQTMathTextVerbatimNode* verbN=dynamic_cast<JKQTMathTextVerbatimNode*>(node);
JKQTMathTextPhantomNode* phanN=dynamic_cast<JKQTMathTextPhantomNode*>(node);
JKQTMathTextNoopNode* noopN=dynamic_cast<JKQTMathTextNoopNode*>(node);
JKQTMathTextModifiedEnvironmentInstructionNode* modenvN=dynamic_cast<JKQTMathTextModifiedEnvironmentInstructionNode*>(node);
QTreeWidgetItem* ti=nullptr;
if (parent) ti=new QTreeWidgetItem(parent);
@ -519,12 +546,14 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
name=QString("SubscriptNode");
if (subN->getChild()) ti->addChild(createTree(subN->getChild(), ti));
} else if (instS) {
name=QString("SimpleInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(instS->getInstructionName()).arg(instS->isSubSuperscriptAboveBelowNode()).arg(instS->getParameters().join("/"));
name=QString("SimpleInstructionNode: \'%1\' (params=%2)").arg(instS->getInstructionName()).arg(instS->getParameters().join("/"));
} else if (modenvN) {
name=QString("ModifiedEnvironmentInstructionNode: \'%1\' (params=%2)").arg(modenvN->getInstructionName()).arg(modenvN->getParameters().join("/"));
} else if (inst1N) {
name=QString("ModifiedTextPropsInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(inst1N->getInstructionName()).arg(inst1N->isSubSuperscriptAboveBelowNode()).arg(inst1N->getParameters().join("/"));
name=QString("ModifiedTextPropsInstructionNode: \'%1\' (params=%2)").arg(inst1N->getInstructionName()).arg(inst1N->getParameters().join("/"));
if (inst1N->getChild()) ti->addChild(createTree(inst1N->getChild(), ti));
} else if (inst1B) {
name=QString("BoxInstructionNode: \'%1\' (subsuper=%2, params=%3)").arg(inst1B->getInstructionName()).arg(inst1B->isSubSuperscriptAboveBelowNode()).arg(inst1B->getParameters().join("/"));
name=QString("BoxInstructionNode: \'%1\' (params=%2)").arg(inst1B->getInstructionName()).arg(inst1B->getParameters().join("/"));
if (inst1B->getChild()) ti->addChild(createTree(inst1B->getChild(), ti));
} else if (lstN) {
name=QString("HorizontalListNode");
@ -541,7 +570,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
} else if (verbN) {
name=QString("VerbatimTextNode (align=%1, spacingFactor=%2x, verticalOrientation=%3, text='%4')").arg(JKQTMathTextHorizontalAlignment2String(verbN->getAlignment())).arg(verbN->getLineSpacingFactor()).arg(JKQTMathTextVerticalOrientation2String(verbN->getVerticalOrientation())).arg(jkqtp_backslashEscape(verbN->getText()));
} else if (symN) {
name=QString("SymbolNode: \'%1\' (subsuper=%3)").arg(symN->getSymbolName()).arg(symN->isSubSuperscriptAboveBelowNode());
name=QString("SymbolNode: \'%1\'").arg(symN->getSymbolName());
} else if (spN) {
name=QString("WhitespaceNode :type=%1, count=%2").arg(spN->Type2String(spN->getWhitespaceType())).arg(spN->getWhitespaceCount());
} else if (txtN) {

View File

@ -333,6 +333,8 @@ std::string jkqtp_booltostr(bool data){
# undef rgb
#endif
#define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
#define gray(g) rgb(g,g,g)
#define gray_p(p) gray(static_cast<uint8_t>(g/100.0*255.0))
static const struct RGBData {
const char *name;
@ -496,7 +498,6 @@ const QStringList& jkqtp_listNamedColors() {
sl.reserve(rgbTblSize);
for (int i=0; i<rgbTblSize; i++) {
sl.push_back(rgbTbl[i].name);
}
}
return sl;

View File

@ -210,6 +210,8 @@ JKQTCOMMON_LIB_EXPORT QColor jkqtp_lookupQColorName(const QString& color);
* This function allows to add the alpha-value as \c "<color_name>,<alpha>" as integer betwee 0 and 255
* or as \c "<color_name>,<transparency_percent>%" in the range of 0..100 % (i.e. (1-transparency_percent/100)*255).
* Also \c "<color_name>,a<alpha_percent>%" in the range of 0..100 % (i.e. alpha_percent/100*255).
*
* Finally the default Qt color definitions are supported, i.e. \c #RGB , \c #RRGGBB , \c #AARRGGBB , \c #RRRGGGBBB , \c #RRRRGGGGBBBB
*/
JKQTCOMMON_LIB_EXPORT QColor jkqtp_String2QColor(const QString& color);

View File

@ -15,12 +15,19 @@ isEmpty(JKQTP_MATHTEXT_PRI_INCLUDED) {
$$PWD/jkqtmathtext/nodes/jkqtmathtextfracnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextinstructionnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextlistnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextverticallistnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtexthorizontallistnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextmatrixnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextsubsupernode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextwhitespacenode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextnodetools.h
$$PWD/jkqtmathtext/nodes/jkqtmathtextnodetools.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextnoopnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextverbatimnode.h \
$$PWD/jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.cpp
SOURCES += $$PWD/jkqtmathtext/jkqtmathtext.cpp \
$$PWD/jkqtmathtext/jkqtmathtextlabel.cpp \
@ -31,13 +38,18 @@ isEmpty(JKQTP_MATHTEXT_PRI_INCLUDED) {
$$PWD/jkqtmathtext/nodes/jkqtmathtextdecoratednode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextfracnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextinstructionnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextverticallistnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtexthorizontallistnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextmatrixnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextsubsupernode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextwhitespacenode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextnodetools.cpp
$$PWD/jkqtmathtext/nodes/jkqtmathtextnodetools.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextnoopnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextverbatimnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.cpp \
$$PWD/jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.cpp
include($$PWD/jkqtmathtext/resources/xits.pri)
DEFINES += AUTOLOAD_XITS_FONTS

View File

@ -32,13 +32,18 @@ set(SOURCES_NODES
${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/jkqtmathtextboxinstructionnode.cpp
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextmodifyenvironmentnode.cpp
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextverticallistnode.cpp
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtexthorizontallistnode.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
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextnodetools.cpp
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextwhitespacenode.cpp
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextnoopnode.cpp
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextverbatimnode.cpp
)
set(HEADERS
@ -56,6 +61,10 @@ set(HEADERS_NODES
$<INSTALL_INTERFACE:nodes/jkqtmathtextnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtexttextnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtexttextnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextboxinstructionnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextboxinstructionnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextmodifyenvironmentnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextmodifyenvironmentnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextbracenode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextbracenode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextdecoratednode.h>
@ -66,6 +75,10 @@ set(HEADERS_NODES
$<INSTALL_INTERFACE:nodes/jkqtmathtextinstructionnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextlistnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextlistnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextverticallistnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextverticallistnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtexthorizontallistnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtexthorizontallistnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextmatrixnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextmatrixnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextsqrtnode.h>
@ -78,6 +91,10 @@ set(HEADERS_NODES
$<INSTALL_INTERFACE:nodes/jkqtmathtextnodetools.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextwhitespacenode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextwhitespacenode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextnoopnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextnoopnode.h>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextverbatimnode.h>
$<INSTALL_INTERFACE:nodes/jkqtmathtextverbatimnode.h>
)
if(JKQtPlotter_BUILD_INCLUDE_XITS_FONTS)

View File

@ -23,6 +23,7 @@
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include "jkqtcommon/jkqtpcodestructuring.h"
#include "jkqtcommon/jkqtpstringtools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h"
#include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h"
@ -34,7 +35,12 @@
#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h"
#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextwhitespacenode.h"
#include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
#include "jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.h"
#include "jkqtmathtext/nodes/jkqtmathtexthorizontallistnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextnoopnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextverbatimnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextverticallistnode.h"
#include <cmath>
#include <QFontMetricsF>
#include <QDebug>
@ -100,10 +106,10 @@ JKQTMathText::JKQTMathText(QObject* parent):
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;
matrix_xSeparation_factor=0.75;
matrix_ySeparation_factor=0.6;
matrix_xPadding_factor=0.75;
matrix_yPadding_factor=0.75;
blackboradFontMode=MTBBDMdefault;
@ -191,6 +197,7 @@ JKQTMathText::JKQTMathText(QObject* parent):
currentTokenID=0;
parseString="";
parsingMathEnvironment=false;
parsinginMathTextStyle=false;
}
JKQTMathText::~JKQTMathText() {
@ -1764,7 +1771,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
if (child!=nullptr) nl->addChild(new JKQTMathTextSuperscriptNode(this, child));
if (child2!=nullptr) nl->addChild(child2);
} else if (currentToken==MTTopenbrace) {
nl->addChild(parseLatexString(true));
nl->addChild(new JKQTMathTextBlockNode(parseLatexString(true), this));
} else if (currentToken==MTTclosebrace) {
break;
} else if (currentToken==MTTopenbracket) {
@ -1954,8 +1961,16 @@ JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew
child= new JKQTMathTextWhitespaceNode(currentInstructionName, this);
} else if (JKQTMathTextSymbolNode::hasSymbol(currentInstructionName)) {
child=new JKQTMathTextSymbolNode(this, currentInstructionName);
if (JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(currentInstructionName) && parsingMathEnvironment) {
child->setSubSuperscriptAboveBelowNode(true);
if (JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(currentInstructionName)) {
if (parsingMathEnvironment) {
if (parsinginMathTextStyle) {
child->setSubSuperscriptAboveBelowNode(false);
} else {
child->setSubSuperscriptAboveBelowNode(true);
}
} else {
child->setSubSuperscriptAboveBelowNode(false);
}
}
if (getNew) *getNew=true;
} else if (big_instructions_family.contains(currentInstructionName)) {
@ -1994,6 +2009,22 @@ JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew
error_list.append(tr("error @ ch. %1: expected symbol-encoding instruction or character after '\\%2' command").arg(currentTokenID).arg(currentInstructionName));
}
if (getNew) *getNew=true;
} else if (JKQTMathTextModifiedEnvironmentInstructionNode::supportsInstructionName(currentInstructionName)) {
const size_t Nparams=JKQTMathTextModifiedEnvironmentInstructionNode::countParametersOfInstruction(currentInstructionName);
bool foundError=false;
QStringList params;
if (Nparams>0) {
params=parseStringParams(true, Nparams, &foundError);
}
if (getToken()!=MTTwhitespace) {
if (getNew) *getNew=false;
}
if (!foundError) {
child=new JKQTMathTextModifiedEnvironmentInstructionNode(this, currentInstructionName, params);
JKQTMathTextModifiedEnvironmentInstructionNode::modifyInMathTextStyleEnvironment(currentInstructionName, parsinginMathTextStyle, this, params);
} else {
error_list.append(tr("error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName).arg(Nparams));
}
} else if (JKQTMathTextModifiedTextPropsInstructionNode::supportsInstructionName(currentInstructionName)) {
const size_t Nparams=JKQTMathTextModifiedTextPropsInstructionNode::countParametersOfInstruction(currentInstructionName);
bool foundError=false;
@ -2002,7 +2033,7 @@ JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew
if (getToken()==MTTopenbrace) {
const bool oldParseMath=parsingMathEnvironment;
auto __finalpaint=JKQTPFinally(std::bind([&oldParseMath](bool& parsingMathEnvironment) { parsingMathEnvironment=oldParseMath; }, std::ref(parsingMathEnvironment)));
JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(currentInstructionName, parsingMathEnvironment, params);
JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(currentInstructionName, parsingMathEnvironment, parsinginMathTextStyle, params);
child=new JKQTMathTextModifiedTextPropsInstructionNode(this, currentInstructionName, parseLatexString(true), params);
} else {
@ -2018,8 +2049,7 @@ JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew
const QStringList params=parseStringParams(true, Nparams, &foundError);
if (!foundError) {
child=new JKQTMathTextSimpleInstructionNode(this, currentInstructionName, params);
}
if (foundError){
} else {
error_list.append(tr("error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName).arg(Nparams));
}
} else if (JKQTMathTextBoxInstructionNode::supportsInstructionName(currentInstructionName)) {
@ -2031,7 +2061,7 @@ JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew
if (getToken()==MTTopenbrace) {
const bool oldParseMath=parsingMathEnvironment;
auto __finalpaint=JKQTPFinally(std::bind([&oldParseMath](bool& parsingMathEnvironment) { parsingMathEnvironment=oldParseMath; }, std::ref(parsingMathEnvironment)));
JKQTMathTextBoxInstructionNode::modifyInMathEnvironment(currentInstructionName, parsingMathEnvironment, params);
JKQTMathTextBoxInstructionNode::modifyInMathEnvironment(currentInstructionName, parsingMathEnvironment, parsinginMathTextStyle, params);
child=new JKQTMathTextBoxInstructionNode(this, currentInstructionName, parseLatexString(true), params);
} else {
foundError=true;

View File

@ -985,6 +985,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
QString parseString;
/** \brief used by the parser. indicates whether we are in a math environment */
bool parsingMathEnvironment;
/** \brief used by the parser. indicates whether to use textstyle or displaystyle in math-mode */
bool parsinginMathTextStyle;
public:

View File

@ -452,20 +452,22 @@ JKQTMathTextEnvironment::JKQTMathTextEnvironment() {
fontSizeUnit=POINTS;
bold=false;
italic=false;
smallCaps=false;
capitalization=QFont::MixedCase;
underlined=false;
overline=false;
strike=false;
insideMath=false;
insideMathForceDigitsUpright=true;
insideMathUseTextStyle=false;
}
void JKQTMathTextEnvironment::beginMathMode()
void JKQTMathTextEnvironment::beginMathMode(bool displaystyle)
{
insideMath=true;
insideMathForceDigitsUpright=true;
insideMathUseTextStyle=!displaystyle;
italic=true;
smallCaps=false;
capitalization=QFont::MixedCase;
underlined=false;
overline=false;
strike=false;
@ -476,12 +478,25 @@ void JKQTMathTextEnvironment::endMathMode()
insideMath=false;
insideMathForceDigitsUpright=true;
italic=false;
smallCaps=false;
capitalization=QFont::MixedCase;
underlined=false;
overline=false;
strike=false;
}
bool JKQTMathTextEnvironment::isMathDisplayStyle() const
{
if (insideMath) return !insideMathUseTextStyle;
else {
return false;
}
}
bool JKQTMathTextEnvironment::isMathTextStyle() const
{
return !isMathDisplayStyle();
}
JKQTMathTextFontEncoding JKQTMathTextEnvironment::getFontEncoding(JKQTMathText* parent) const {
switch (font) {
case MTEsans: if (insideMath) {
@ -540,8 +555,7 @@ QFont JKQTMathTextEnvironment::getFont(const JKQTMathText* parent) const {
f.setUnderline(underlined);
f.setOverline(overline);
f.setStrikeOut(strike);
f.setCapitalization(QFont::MixedCase);
if (smallCaps) f.setCapitalization(QFont::SmallCaps);
f.setCapitalization(capitalization);
if (fontSizeUnit==POINTS) f.setPointSizeF(fontSize);
else if (fontSizeUnit==PIXELS) f.setPixelSize(static_cast<int>(fontSize));
f.setStyleStrategy(QFont::NoFontMerging);

View File

@ -283,7 +283,7 @@ struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextEnvironment {
/** \brief is the text currently italic? */
bool italic;
/** \brief is the text currently in small caps? */
bool smallCaps;
QFont::Capitalization capitalization;
/** \brief is the text currently underlined? */
bool underlined;
/** \brief is the text currently overlined? */
@ -294,10 +294,25 @@ struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextEnvironment {
bool insideMath;
/** \brief if \a insideMath \c ==true and this is \c true (the default), then digits are forced to be typeset in upright, otherwise they are typeset as defined by the other properties */
bool insideMathForceDigitsUpright;
/** \brief sets insideMath \c =true and insideMathForceDigitsUpright \c =true */
void beginMathMode();
/** \brief sets insideMath \c =false and insideMathForceDigitsUpright \c =true */
/** \brief if \c true the commands like \c \\frac{}{} are executes as \c \\tfrac{}{} . This implements \c \\textstyle or if \c false \c \\displaystyle
*
* \image html jkqtmathtext/jkqtmathtext_mathstyle.png
*/
bool insideMathUseTextStyle;
/** \brief sets insideMath \c =true and insideMathForceDigitsUpright \c =true and \c insideMathUseTextStyle=!displaystyle*/
void beginMathMode(bool displaystyle=true);
/** \brief sets insideMath \c =false */
void endMathMode();
/** \brief determines whether to use displaystyle or textstyle for math-instructions like \c \\frace{}{} or \c \\int_x
*
* \image html jkqtmathtext/jkqtmathtext_mathstyle.png
*/
bool isMathDisplayStyle() const;
/** \brief determines whether to use displaystyle or textstyle for math-instructions like \c \\frace{}{} or \c \\int_x
*
* \image html jkqtmathtext/jkqtmathtext_mathstyle.png
*/
bool isMathTextStyle() const;
/** \brief build a <a href="https://doc.qt.io/qt-5/qfont.html">QFont</a> object from the settings in this object */

View File

@ -0,0 +1,345 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
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 <http://www.gnu.org/licenses/>.
*/
#include "jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/jkqtmathtext.h"
#include "jkqtcommon/jkqtpcodestructuring.h"
#include "jkqtcommon/jkqtpstringtools.h"
#include <cmath>
#include <QFontMetricsF>
#include <QDebug>
#include <QFontDatabase>
#include <QFontInfo>
#include <QApplication>
#include <QFont>
JKQTMathTextBoxInstructionNode::JKQTMathTextBoxInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
{
fillInstructions();
}
JKQTMathTextBoxInstructionNode::~JKQTMathTextBoxInstructionNode() {
}
QString JKQTMathTextBoxInstructionNode::getTypeName() const
{
return QLatin1String("JKQTMathTextBoxInstructionNode(")+instructionName+")";
}
JKQTMathTextNodeSize JKQTMathTextBoxInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
JKQTMathTextEnvironment ev=currentEv;
const auto& inst=instructions.value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
const double lw=p.widthF();
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
JKQTMathTextNodeSize s;
s.width=cs.width+2.0*(padding+lw/2.0);
s.baselineHeight=cs.baselineHeight+padding+lw/2.0;
s.overallHeight=cs.overallHeight+2.0*(padding+lw/2.0);
s.strikeoutPos=cs.strikeoutPos;
return s;
}
double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;
const auto& inst=instructions.value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
const double lw=p.widthF();
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
const double rr=inst.roundingFactor*fmNonItalic.tightBoundingRect("x").width();
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setBrush(b);
painter.setPen(p);
const QRectF rect(x+lw/2.0, y-cs.baselineHeight-padding-lw/2.0, cs.width+2.0*padding, cs.overallHeight+2.0*padding);
if (rr>0) painter.drawRoundedRect(rect, rr, rr, Qt::AbsoluteSize);
else painter.drawRect(rect);
if (inst.doubleLine) {
painter.setBrush(Qt::NoBrush);
QPen p2=p;
p2.setWidthF(p.widthF()*0.6);
const QRectF recti(x+lw*2.5, y-cs.baselineHeight-lw/2.0-padding+2.0*lw, cs.width+2.0*padding-4.0*lw, cs.overallHeight+2.0*padding-4.0*lw);
if (rr>0) painter.drawRoundedRect(recti, rr, rr, Qt::AbsoluteSize);
else painter.drawRect(recti);
}
}
double xnew = getChild()->draw(painter, x+padding+lw/2.0, y, ev);
return xnew+padding+lw/2.0;
}
bool JKQTMathTextBoxInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
const auto& inst=instructions.value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
//const double lw=p.widthF();
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
//const double rr=inst.roundingFactor*fmNonItalic.tightBoundingRect("x").width();
QString s=QString("padding: %1px").arg(padding);
if (p!=Qt::NoPen) {
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
if (p.widthF()>0 && p.color()!=Qt::transparent) s=s+"border-color: "+p.color().name();
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
if (p.widthF()>0 && p.color()!=Qt::transparent) s=s+QString("border-width: %1px").arg(p.width());
}
if (b!=Qt::NoBrush) {
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
if (b.color()!=Qt::transparent) s=s+"background-color: "+b.color().name();
}
if (s.size()>0) html=html+ QString("<span style=\"%1\">").arg(s);
bool ok=getChild()->toHtml(html, ev, defaultEv);
if (s.size()>0) html=html+"</span>";
return ok;
}
bool JKQTMathTextBoxInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
size_t JKQTMathTextBoxInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
return 0;
}
void JKQTMathTextBoxInstructionNode::modifyInMathEnvironment(const QString &instructionName, bool &insideMath, bool& insideMathTextStyle, const QStringList& params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMath=insideMath;
ev.insideMathUseTextStyle=insideMathTextStyle;
instructions[instructionName].modifier(ev, params);
insideMath=ev.insideMath;
insideMathTextStyle=ev.insideMathUseTextStyle;
}
}
QHash<QString, JKQTMathTextBoxInstructionNode::InstructionProperties> JKQTMathTextBoxInstructionNode::instructions;
void JKQTMathTextBoxInstructionNode::fillInstructions()
{
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
instructions["fbox"] = i;
instructions["framebox"] = i;
instructions["boxed"] = i;
instructions["framed"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.doubleLine=true;
instructions["doublebox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.roundingFactor=0.7;
instructions["ovalbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setWidthF(p.widthF()*1.5);
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.roundingFactor=0.8;
instructions["Ovalbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.roundingFactor=0.7;
i.doubleLine=true;
instructions["ovaldoublebox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setColor(jkqtp_String2QColor(parameters.value(0, p.color().name())));
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/1);
instructions["colorbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setStyle(Qt::DashLine);
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
instructions["dashbox"] = i;
instructions["dashedbox"] = i;
instructions["dbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setStyle(Qt::DotLine);
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
instructions["dottedbox"] = i;
instructions["dotbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::NoPen,
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& parameters, JKQTMathText* /*parent*/){
return QBrush(jkqtp_String2QColor(parameters.value(0, QColor(Qt::transparent).name())), Qt::SolidPattern);
},
InstructionProperties::DefaultPadding,
/*Nparams=*/1);
instructions["shaded"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::NoPen,
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& parameters, JKQTMathText* /*parent*/){
return QBrush(jkqtp_String2QColor(parameters.value(0, QColor(Qt::transparent).name())), Qt::SolidPattern);
},
0,
/*Nparams=*/1);
instructions["snugshade"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
0,
/*Nparams=*/0);
instructions["snugbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setColor(jkqtp_String2QColor(parameters.value(0, p.color().name())));
return p;
},
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& parameters, JKQTMathText* /*parent*/){
return QBrush(jkqtp_String2QColor(parameters.value(1, QColor(Qt::transparent).name())), Qt::SolidPattern);
},
InstructionProperties::DefaultPadding,
/*Nparams=*/2);
instructions["fcolorbox"] = i;
}
}
JKQTMathTextBoxInstructionNode::InstructionProperties::ModifyEnvironmentFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoModification=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/){};
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::DefaultPen=
[](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, JKQTMathText* parent){ return QPen(ev.color, QFontMetricsF(ev.getFont(parent)).lineWidth(), Qt::SolidLine); };
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoPen=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/, JKQTMathText* /*parent*/){ return Qt::NoPen; };
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxBrushFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoBrush=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/, JKQTMathText* /*parent*/){ return Qt::NoBrush; };
double JKQTMathTextBoxInstructionNode::InstructionProperties::DefaultPadding=0.5;
JKQTMathTextBoxInstructionNode::InstructionProperties::InstructionProperties():
InstructionProperties(NoModification, DefaultPen, NoBrush, DefaultPadding, 0)
{
}
JKQTMathTextBoxInstructionNode::InstructionProperties::InstructionProperties(const GetBoxPenFunctor &_pen, const GetBoxBrushFunctor &_brush, double _paddingFactor, size_t _NParams):
InstructionProperties(NoModification, _pen, _brush, _paddingFactor, _NParams)
{
}
JKQTMathTextBoxInstructionNode::InstructionProperties::InstructionProperties(const ModifyEnvironmentFunctor &_modifier, const GetBoxPenFunctor &_pen, const GetBoxBrushFunctor &_brush, double _paddingFactor, size_t _NParams):
NParams(_NParams),
modifier(_modifier),
pen(_pen),
brush(_brush),
paddingFactor(_paddingFactor),
doubleLine(false),
roundingFactor(0.0)
{
}

View File

@ -0,0 +1,131 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTMATHTEXTBOXINSTRUCTIONNODE_H
#define JKQTMATHTEXTBOXINSTRUCTIONNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h"
#include <QPainter>
#include <functional>
class JKQTMathText; // forward
// JKQTMATHTEXT_LIB_EXPORT
/** \brief subclass representing an instruction node which draws a (possibly colored) box around it's contents
* i.e. it represents instructions like \c \\fbox{...}, \c \\colorbox{color}{...}, ...
* \ingroup jkqtmathtext_items
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBoxInstructionNode: public JKQTMathTextInstruction1Node {
public:
explicit JKQTMathTextBoxInstructionNode(JKQTMathText* parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters=QStringList());
virtual ~JKQTMathTextBoxInstructionNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMath to \c true if inside the node is to be parsed in math mode and \c false else
* \see instructions
*/
static void modifyInMathEnvironment(const QString& instructionName, bool& insideMath, bool &insideMathTextStyle, const QStringList &params=QStringList());
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief set all properties in \a ev, as appropriate for the represented instruction */
bool setupMTenvironment(JKQTMathTextEnvironment &ev) const;
/** \brief defines the implementation of an instruction represented by JKQTMathTextModifiedTextPropsInstructionNode */
struct InstructionProperties {
/** \brief this functor implements the instruction */
typedef std::function<void(JKQTMathTextEnvironment& ev, const QStringList& parameters)> ModifyEnvironmentFunctor;
static ModifyEnvironmentFunctor NoModification;
/** \brief this functor returns the QPen to use for the box outline */
typedef std::function<QPen(JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent)> GetBoxPenFunctor;
/** \brief generates a QPen with the lineWidth associated with the QFont of the environment (using QFontMetricsF::lineWidth() ) */
static GetBoxPenFunctor DefaultPen;
/** \brief generates an invisible pen with 0 width */
static GetBoxPenFunctor NoPen;
/** \brief this functor returns the QBrush to use for the box fill */
typedef std::function<QBrush(JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent)> GetBoxBrushFunctor;
/** \brief generates an invisible QBrush */
static GetBoxBrushFunctor NoBrush;
/** \brief default padding factor 0.5 xWidth */
static double DefaultPadding;
/** \brief default constructor, creates a NOP-instruction that does nothing */
InstructionProperties();
/** \brief constructor */
InstructionProperties(const ModifyEnvironmentFunctor& _modifier, const GetBoxPenFunctor& _pen, const GetBoxBrushFunctor& _brush, double _paddingFactor=DefaultPadding, size_t _NParams=0);
/** \brief constructor */
InstructionProperties(const GetBoxPenFunctor& _pen, const GetBoxBrushFunctor& _brush, double _paddingFactor=DefaultPadding, size_t _NParams=0);
/** \brief number of parameters for this node */
size_t NParams;
/** \brief functor that modifies a JKQTMathTextEnvironment */
ModifyEnvironmentFunctor modifier;
/** \brief functor that creates a QPen for the box outline */
GetBoxPenFunctor pen;
/** \brief functor that creates a QBrush for the box fill */
GetBoxBrushFunctor brush;
/** \brief padding of the box, as a factor to xWidth of the current font */
double paddingFactor;
/** \brief draw a double-line */
bool doubleLine;
/** \brief rounding radius (rx=ry) of the box, as a factor to xWidth of the current font */
double roundingFactor;
};
/** \brief fills instructions
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
};
#endif // JKQTMATHTEXTBOXINSTRUCTIONNODE_H

View File

@ -246,8 +246,8 @@ double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JK
const double italic_xcorrection=getNonItalicXCorretion(painter, cs.width, ev, getChild());
const double deco_xoffset=parentMathText->getDecorationWidthReductionXFactor()*width_X/2.0;
const double deco_width=std::max<double>(width_x*0.5,cs.width-2.0*deco_xoffset-italic_xcorrection);
const double deco_vecwidth=width_x*0.18;
const double deco_vecheight=deco_height*0.25;
const double deco_vecwidth=width_x*0.25;
const double deco_vecheight=deco_height*0.5;
const double deco_accentwidth=deco_height/4.0;
const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("j").width():fm.boundingRect("^").width())-italic_xcorrection;
const double decotop_xcenter=x+italic_xcorrection+(cs.width-italic_xcorrection)/2.0;

View File

@ -124,6 +124,11 @@ QString JKQTMathTextFracNode::getTypeName() const
}
JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
FracType fracmode=this->mode;
if (currentEv.isMathTextStyle()) {
if (fracmode==MTFMfrac) fracmode=MTFMtfrac;
if (fracmode==MTFMsfrac) fracmode=MTFMstfrac;
}
const QFont f=currentEv.getFont(parentMathText);
const QFontMetricsF fm(f, painter.device());
JKQTMathTextEnvironment ev1=currentEv;
@ -137,14 +142,14 @@ JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JK
const double braceheight=fm.xHeight()*parentMathText->getUnderbraceBraceSizeXFactor();
const double braceseparation=fm.xHeight()*parentMathText->getUnderbraceSeparationXFactor();
if (mode==JKQTMathTextFracNode::MTFMunderbrace || mode==JKQTMathTextFracNode::MTFMoverbrace||mode==JKQTMathTextFracNode::MTFMunderbracket || mode==JKQTMathTextFracNode::MTFMoverbracket) {
if (fracmode==JKQTMathTextFracNode::MTFMunderbrace || fracmode==JKQTMathTextFracNode::MTFMoverbrace||fracmode==JKQTMathTextFracNode::MTFMunderbracket || fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
ev2.fontSize=ev2.fontSize*parentMathText->getUnderbraceFactor();
} else if (mode==JKQTMathTextFracNode::MTFMunderset || mode==JKQTMathTextFracNode::MTFMoverset) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset || fracmode==JKQTMathTextFracNode::MTFMoverset) {
ev2.fontSize=ev2.fontSize*parentMathText->getUndersetFactor();
} else if (mode==JKQTMathTextFracNode::MTFMfrac || mode==JKQTMathTextFracNode::MTFMsfrac) {
} else if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
ev1.fontSize=ev1.fontSize*getFracScalingFactor();
ev2.fontSize=ev2.fontSize*getFracScalingFactor();
} else if (mode==JKQTMathTextFracNode::MTFMtfrac || mode==JKQTMathTextFracNode::MTFMstfrac) {
} else if (fracmode==JKQTMathTextFracNode::MTFMtfrac || fracmode==JKQTMathTextFracNode::MTFMstfrac) {
ev1.fontSize=ev1.fontSize*getFracScalingFactor()*0.7;
ev2.fontSize=ev2.fontSize*getFracScalingFactor()*0.7;
}
@ -174,19 +179,19 @@ JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JK
size.overallHeight=0;
size.baselineHeight=0;
size.width=0;
if (mode==JKQTMathTextFracNode::MTFMfrac || mode==JKQTMathTextFracNode::MTFMdfrac || mode==JKQTMathTextFracNode::MTFMtfrac || mode==JKQTMathTextFracNode::MTFMstackrel) {
if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMdfrac || fracmode==JKQTMathTextFracNode::MTFMtfrac || fracmode==JKQTMathTextFracNode::MTFMstackrel) {
const double top_ascent=line_ascent+xheight*parentMathText->getFracShiftFactor();
const double bot_ascent=line_ascent-xheight*parentMathText->getFracShiftFactor();
const double newascent=size1.overallHeight+top_ascent;
const double newdescent=size2.overallHeight-bot_ascent;
size.width=qMax(size1.width, size2.width);
if (mode!=JKQTMathTextFracNode::MTFMstackrel) size.width+=xwidth/2.0;
if (fracmode!=JKQTMathTextFracNode::MTFMstackrel) size.width+=xwidth/2.0;
size.strikeoutPos=line_ascent;
size.overallHeight=newascent+newdescent;
size.baselineHeight=newascent;
} else if (mode==JKQTMathTextFracNode::MTFMstfrac || mode==JKQTMathTextFracNode::MTFMsfrac) {
} else if (fracmode==JKQTMathTextFracNode::MTFMstfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
const double top_ascent=line_ascent;
const double newascent=size1.overallHeight+top_ascent;
const double newdescent=qMax(size2.overallHeight-size2.baselineHeight, qheight-xheight);
@ -195,23 +200,23 @@ JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JK
size.overallHeight=newascent+newdescent;
size.baselineHeight=newascent;
} else if (mode==JKQTMathTextFracNode::MTFMunderbrace || mode==JKQTMathTextFracNode::MTFMunderbracket) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderbrace || fracmode==JKQTMathTextFracNode::MTFMunderbracket) {
const double newdescent=descent1+size2.overallHeight+braceheight+2.0*braceseparation;
size.overallHeight=newdescent+size1.baselineHeight;
size.baselineHeight=size1.baselineHeight;
size.width=qMax(size1.width, size2.width)+xwidth;
size.strikeoutPos=line_ascent;
} else if (mode==JKQTMathTextFracNode::MTFMoverbrace || mode==JKQTMathTextFracNode::MTFMoverbracket) {
} else if (fracmode==JKQTMathTextFracNode::MTFMoverbrace || fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
size.overallHeight=size1.overallHeight+size2.overallHeight+braceheight+2.0*braceseparation;
size.baselineHeight=size1.baselineHeight+size2.overallHeight+braceheight+2.0*braceseparation;
size.width=qMax(size1.width, size2.width)+xwidth;
size.strikeoutPos=line_ascent;
} else if (mode==JKQTMathTextFracNode::MTFMunderset) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset) {
size.overallHeight=size1.overallHeight+size2.overallHeight+xheight/6.0;
size.baselineHeight=size1.baselineHeight;
size.width=qMax(size1.width, size2.width)+xwidth;
size.strikeoutPos=line_ascent;
} else if (mode==JKQTMathTextFracNode::MTFMoverset) {
} else if (fracmode==JKQTMathTextFracNode::MTFMoverset) {
size.overallHeight=size1.overallHeight+size1.overallHeight+xheight/6.0;
size.baselineHeight=size1.baselineHeight+size2.overallHeight+xheight/6.0;
size.width=qMax(size1.width, size2.width)+xwidth;
@ -240,6 +245,12 @@ double JKQTMathTextFracNode::getFracScalingFactor() const
}
double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
FracType fracmode=this->mode;
if (currentEv.isMathTextStyle()) {
if (fracmode==MTFMfrac) fracmode=MTFMtfrac;
if (fracmode==MTFMsfrac) fracmode=MTFMstfrac;
}
doDrawBoxes(painter, x, y, currentEv);
const QFont f=currentEv.getFont(parentMathText);
const QFontMetricsF fm(f, painter.device());
@ -255,14 +266,14 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
const double braceheight=fm.xHeight()*parentMathText->getUnderbraceBraceSizeXFactor();
const double braceseparation=fm.xHeight()*parentMathText->getUnderbraceSeparationXFactor();
if (mode==JKQTMathTextFracNode::MTFMunderbrace || mode==JKQTMathTextFracNode::MTFMoverbrace||mode==JKQTMathTextFracNode::MTFMunderbracket || mode==JKQTMathTextFracNode::MTFMoverbracket) {
if (fracmode==JKQTMathTextFracNode::MTFMunderbrace || fracmode==JKQTMathTextFracNode::MTFMoverbrace||fracmode==JKQTMathTextFracNode::MTFMunderbracket || fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
ev2.fontSize=ev2.fontSize*parentMathText->getUnderbraceFactor();
} else if (mode==JKQTMathTextFracNode::MTFMunderset || mode==JKQTMathTextFracNode::MTFMoverset) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset || fracmode==JKQTMathTextFracNode::MTFMoverset) {
ev2.fontSize=ev2.fontSize*parentMathText->getUndersetFactor();
} else if (mode==JKQTMathTextFracNode::MTFMfrac || mode==JKQTMathTextFracNode::MTFMsfrac) {
} else if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
ev1.fontSize=ev1.fontSize*getFracScalingFactor();
ev2.fontSize=ev2.fontSize*getFracScalingFactor();
} else if (mode==JKQTMathTextFracNode::MTFMtfrac || mode==JKQTMathTextFracNode::MTFMstfrac) {
} else if (fracmode==JKQTMathTextFracNode::MTFMtfrac || fracmode==JKQTMathTextFracNode::MTFMstfrac) {
ev1.fontSize=ev1.fontSize*getFracScalingFactor()*0.7;
ev2.fontSize=ev2.fontSize*getFracScalingFactor()*0.7;
}
@ -306,26 +317,26 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
p.setWidthF(qMax(parentMathText->ABS_MIN_LINEWIDTH, linewideth));
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setPen(p);
if (mode==JKQTMathTextFracNode::MTFMfrac || mode==JKQTMathTextFracNode::MTFMdfrac || mode==JKQTMathTextFracNode::MTFMtfrac) {
if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMdfrac || fracmode==JKQTMathTextFracNode::MTFMtfrac) {
deltaWidth=xwidth/2.0;
const QLineF l(x+p.widthF()*2.0, yline, x+maxWidth+deltaWidth-p.widthF()*2.0, yline);
if (l.length()>0) painter.drawLine(l);
child1->draw(painter, x+deltaWidth/2.0+(maxWidth-size1.width)/2.0, yline-xheight*(parentMathText->getFracShiftFactor())-descent1, ev1);
child2->draw(painter, x+deltaWidth/2.0+(maxWidth-size2.width)/2.0, yline+xheight*(parentMathText->getFracShiftFactor())+ascent2, ev2);
} else if (mode==JKQTMathTextFracNode::MTFMstackrel) {
} else if (fracmode==JKQTMathTextFracNode::MTFMstackrel) {
child1->draw(painter, x+(maxWidth-size1.width)/2.0, yline-xheight*(parentMathText->getFracShiftFactor())-descent1, ev1);
child2->draw(painter, x+(maxWidth-size2.width)/2.0, yline+xheight*(parentMathText->getFracShiftFactor())+ascent2, ev2);
} else if (mode==JKQTMathTextFracNode::MTFMstfrac || mode==JKQTMathTextFracNode::MTFMsfrac) {
} else if (fracmode==JKQTMathTextFracNode::MTFMstfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
deltaWidth=xwidth*0.666;
child1->draw(painter, x, yline, ev1);
child2->draw(painter, x+size1.width+deltaWidth, y, ev2);
const QLineF l(x+size1.width+deltaWidth, y-Mheight, x+size1.width, y+(qheight-xheight));
if (l.length()>0) painter.drawLine(l);
} else if (mode==JKQTMathTextFracNode::MTFMunderset) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset) {
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, y+descent1+xheight/6.0+ascent2, ev2);
deltaWidth=xwidth;
} else if (mode==JKQTMathTextFracNode::MTFMunderbrace) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderbrace) {
const double ybrace=y+descent1+braceseparation+braceheight/2.0;
const double ybot=y+descent1+2.0*braceseparation+braceheight+ascent2;
{
@ -337,7 +348,7 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ybot, ev2);
deltaWidth=xwidth;
} else if (mode==JKQTMathTextFracNode::MTFMunderbracket) {
} else if (fracmode==JKQTMathTextFracNode::MTFMunderbracket) {
const double ybrace=y+descent1+braceseparation+braceheight/2.0;
const double ybot=y+descent1+2.0*braceseparation+braceheight+ascent2;
{
@ -355,11 +366,11 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ybot, ev2);
deltaWidth=xwidth;
} else if (mode==JKQTMathTextFracNode::MTFMoverset) {
} else if (fracmode==JKQTMathTextFracNode::MTFMoverset) {
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, y-ascent1-xheight/6.0-descent2, ev2);
deltaWidth=xwidth;
} else if (mode==JKQTMathTextFracNode::MTFMoverbrace) {
} else if (fracmode==JKQTMathTextFracNode::MTFMoverbrace) {
const double ybrace=y-ascent1-braceheight/2.0-braceseparation;
const double ytop=y-ascent1-2.0*braceseparation-braceheight-descent2;
{
@ -375,7 +386,7 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ytop, ev2);
deltaWidth=xwidth;
} else if (mode==JKQTMathTextFracNode::MTFMoverbracket) {
} else if (fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
const double ybrace=y-ascent1-braceheight/2.0-braceseparation;
const double ytop=y-ascent1-2.0*braceseparation-braceheight-descent2;
{
@ -396,7 +407,7 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
}
if (mode==JKQTMathTextFracNode::MTFMstfrac || mode==JKQTMathTextFracNode::MTFMsfrac) return x+size1.width+size2.width+deltaWidth;
if (fracmode==JKQTMathTextFracNode::MTFMstfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) return x+size1.width+size2.width+deltaWidth;
else return x+maxWidth+deltaWidth;
}

View File

@ -19,7 +19,7 @@
#include "jkqtmathtext/nodes/jkqtmathtextlistnode.h"
#include "jkqtmathtext/nodes/jkqtmathtexthorizontallistnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h"
#include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h"
@ -52,15 +52,9 @@ QString JKQTMathTextHorizontalListNode::getTypeName() const
return "MTHorizontalListNode";
}
JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment ev) const {
JKQTMathTextEnvironment currentEv=ev;
JKQTMathTextNodeSize outSize;
const QFont f=currentEv.getFont(parentMathText);
const QFontMetricsF fm(f);
const double subsupershift=fm.xHeight()*parentMathText->getOperatorsubsuperDistanceFactor();
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double spaceWidth=fm.boundingRect(' ').width();
//QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
@ -68,6 +62,14 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
double xnew=0;
//bool wasBrace=false;
for (int i=0; i<nodes.size(); i++) {
const QFont f=currentEv.getFont(parentMathText);
const QFontMetricsF fm(f);
const double subsupershift=fm.xHeight()*parentMathText->getOperatorsubsuperDistanceFactor();
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double spaceWidth=fm.boundingRect(' ').width();
JKQTMathTextSymbolNode::NodeSize prevNodeSize;
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr;
@ -291,6 +293,7 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
if (nodeI_SubScript) ns=nodeI_SubScript->getSizeWithSpecialPlacement(painter, currentEv, prevNodeSizePtrForSubscript);
else if (nodeI_SuperScript) ns=nodeI_SuperScript->getSizeWithSpecialPlacement(painter, currentEv, prevNodeSizePtrForSuperscript);
else ns=nodes[i]->getSize(painter, currentEv);
const double cDescent=ns.getDescent();
//qDebug()<<"### else: ns.baselineHeight="<<ns.baselineHeight<<" baselineHeight="<<baselineHeight<<" oh="<<oh<<" overallHeight="<<overallHeight;
@ -309,6 +312,12 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
xnew+=ns.width;
//qDebug()<<i<<xnew;
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
//wasBrace=dynamic_cast<JKQTMathTextBraceNode*>(nodes[i]);
}
@ -317,18 +326,19 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
return outSize;
}
double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment ev) const {
JKQTMathTextEnvironment currentEv=ev;
doDrawBoxes(painter, x, y, currentEv);
double ynew=y;
double xnew=x;
//qDebug()<<"listNode: "<<currentEv.fontSize;
const QFontMetricsF fm(currentEv.getFont(parentMathText));
const double subsupershift=fm.xHeight()*parentMathText->getOperatorsubsuperDistanceFactor();
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
for (int i=0; i<nodes.size(); i++) {
bool doDraw=true;
const QFontMetricsF fm(currentEv.getFont(parentMathText));
const double subsupershift=fm.xHeight()*parentMathText->getOperatorsubsuperDistanceFactor();
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
JKQTMathTextSymbolNode::NodeSize prevNodeSize;
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
@ -493,6 +503,10 @@ double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double
if (nodeI_SuperScript) xnew=nodeI_SuperScript->drawWithSpecialPlacement(painter, xnew, ynew, currentEv, prevNodeSizePtrForSuperscript);
else if (nodeI_SubScript) xnew=nodeI_SubScript->drawWithSpecialPlacement(painter, xnew+subscript_xcorrection, ynew, currentEv, prevNodeSizePtrForSubscript);
else xnew=nodes[i]->draw(painter, xnew, ynew, currentEv);
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
}
return xnew;
@ -503,12 +517,17 @@ void JKQTMathTextHorizontalListNode::addChild(JKQTMathTextNode *n) {
nodes.append(n);
}
bool JKQTMathTextHorizontalListNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
bool JKQTMathTextHorizontalListNode::toHtml(QString &html, JKQTMathTextEnvironment ev, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment currentEv=ev;
bool ok=true;
for (int i=0; i<nodes.size(); i++) {
QString h="";
ok = ok && nodes[i]->toHtml(h, currentEv, defaultEv);
html=html+h;
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
return ok;
}
@ -565,261 +584,13 @@ JKQTMathTextNode *JKQTMathTextHorizontalListNode::replaceChild(int i, JKQTMathTe
return c;
}
JKQTMathTextVerticalListNode::JKQTMathTextVerticalListNode(JKQTMathText *_parent, JKQTMathTextHorizontalAlignment _alignment, double _linespacingFactor, JKQTMathTextLineSpacingMode spacingMode_, JKQTMathTextVerticalOrientation _verticalOrientation):
JKQTMathTextMultiChildNode(_parent),
alignment(_alignment),
lineSpacingFactor(_linespacingFactor),
verticalOrientation(_verticalOrientation),
spacingMode(spacingMode_)
void JKQTMathTextHorizontalListNode::modifyEnvironment(JKQTMathTextEnvironment &currentEv) const
{
nodes.clear();
// these operations cause sub/sup script to be typeset over/under the operator, not right besides!
}
JKQTMathTextVerticalListNode::~JKQTMathTextVerticalListNode() {
clearChildrenImpl(true);
}
QString JKQTMathTextVerticalListNode::getTypeName() const
{
return "MTVerticalListNode";
}
JKQTMathTextNodeSize JKQTMathTextVerticalListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
return calcLayout(painter, currentEv);
}
JKQTMathTextVerticalListNode::LayoutInfo JKQTMathTextVerticalListNode::calcLayout(QPainter &painter, JKQTMathTextEnvironment currentEv) const
{
LayoutInfo l;
const QFontMetricsF fm(currentEv.getFont(parentMathText));
const double linespacing=fm.lineSpacing()*lineSpacingFactor;
const double fleading=fm.leading();
const double synLeading=fm.lineWidth();
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
if (nodes.size()<=0) {
return l;
}
// from now on we have at least one child node!!!
QList<double> widths, heights, ascents, descents, strikeouts;
double heightSum=0;
QList<double> ysFromFirstLine; // y-position of each line, where the first line is always at y=0 (i.e. ysFromFirstLine[0]==0)
double y=0;
for (int i=0; i<nodes.size(); i++) {
const JKQTMathTextNodeSize loc=nodes[i]->getSize(painter, currentEv);
if (i==0) {
heightSum=loc.baselineHeight;
} else if (i>0) {
double deltaLine=0;
if (spacingMode==MTSMMinimalSpacing) {
deltaLine=descents.last()+lineLeading+loc.baselineHeight;
} else if (spacingMode==MTSMDefaultSpacing) {
deltaLine=qMax(linespacing, descents.last()+lineLeading+loc.baselineHeight);
}
heightSum=heightSum+deltaLine;
y=y+deltaLine;
}
widths<<loc.width;
l.width=qMax(l.width, loc.width);
heights<<loc.overallHeight;
ascents<<loc.baselineHeight;
descents<<(loc.overallHeight-loc.baselineHeight);
strikeouts<<loc.strikeoutPos;
ysFromFirstLine<<y;
}
heightSum+=descents.last();
l.overallHeight=heightSum;
double y0=0;
if (verticalOrientation==MTVOTop) {
l.baselineHeight=0;
l.strikeoutPos=0;
y0=ascents.first();
} else if (verticalOrientation==MTVOFirstLine) {
l.baselineHeight=ascents.first();
l.strikeoutPos=strikeouts.first();
y0=0;
} else if (verticalOrientation==MTVOCentered) {
l.baselineHeight=heightSum/2.0;
l.strikeoutPos=heightSum/4.0;
y0=-heightSum/2.0+ascents.first();
} else if (verticalOrientation==MTVOLastLine) {
l.baselineHeight=heightSum-descents.last();
l.strikeoutPos=strikeouts.last();
y0=-(heightSum-ascents.first()-descents.last());
} else if (verticalOrientation==MTVOBottom) {
l.baselineHeight=heightSum;
l.strikeoutPos=0;
y0=-(heightSum-ascents.first());
}
for (int i=0; i<nodes.size(); i++) {
double x=0;
if (alignment==MTHARight) x=l.width-widths[i];
else if (alignment==MTHACentered) x=(l.width-widths[i])/2.0;
l.X<<QPointF(x,ysFromFirstLine[i]+y0);
}
return l;
}
double JKQTMathTextVerticalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
doDrawBoxes(painter, x, y, currentEv);
const LayoutInfo l=calcLayout(painter, currentEv);
for (int i=0; i<nodes.size(); i++) {
nodes[i]->draw(painter, x+l.X.at(i).x(), y+l.X.at(i).y(), currentEv);
}
return x+l.width;
}
void JKQTMathTextVerticalListNode::addChild(JKQTMathTextNode *n) {
n->setParentNode(this);
nodes.append(n);
}
bool JKQTMathTextVerticalListNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
bool ok=true;
if (alignment==MTHALeft) {
html+="<div align=\"left\">";
} else if (alignment==MTHACentered) {
html+="<div align=\"center\">";
} else if (alignment==MTHARight) {
html+="<div align=\"right\">";
}
for (int i=0; i<nodes.size(); i++) {
QString h="";
ok = ok && nodes[i]->toHtml(h, currentEv, defaultEv);
if (i==0) html=html+h;
else html=html+"<br/>"+h;
}
html+="</div>";
return ok;
}
QList<JKQTMathTextNode *> JKQTMathTextVerticalListNode::getChildren() {
return this->nodes;
}
int JKQTMathTextVerticalListNode::childCount() const
{
return nodes.size();
}
void JKQTMathTextVerticalListNode::clearChildrenImpl(bool deleteChildren)
{
if (deleteChildren) {
for (int i=0; i<nodes.size(); i++) {
delete nodes[i];
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
nodes.clear();
}
void JKQTMathTextVerticalListNode::deleteChild(int i)
{
if (i>=0 && i<nodes.size()) {
delete nodes[i];
nodes.removeAt(i);
}
}
void JKQTMathTextVerticalListNode::clearChildren(bool deleteChildren)
{
clearChildrenImpl(deleteChildren);
}
JKQTMathTextNode *JKQTMathTextVerticalListNode::getChild(int i)
{
return nodes[i];
}
const JKQTMathTextNode *JKQTMathTextVerticalListNode::getChild(int i) const
{
return nodes[i];
}
JKQTMathTextNode *JKQTMathTextVerticalListNode::replaceChild(int i, JKQTMathTextNode *newChild)
{
JKQTMathTextNode* c=nodes[i];
nodes[i]=newChild;
newChild->setParentNode(this);
return c;
}
JKQTMathTextHorizontalAlignment JKQTMathTextVerticalListNode::getAlignment() const
{
return alignment;
}
JKQTMathTextVerticalOrientation JKQTMathTextVerticalListNode::getVerticalOrientation() const
{
return verticalOrientation;
}
double JKQTMathTextVerticalListNode::getLineSpacingFactor() const
{
return lineSpacingFactor;
}
JKQTMathTextLineSpacingMode JKQTMathTextVerticalListNode::getSpacingMode() const
{
return spacingMode;
}
void JKQTMathTextVerticalListNode::setAlignment(JKQTMathTextHorizontalAlignment value)
{
alignment=value;
}
void JKQTMathTextVerticalListNode::setVerticalOrientation(JKQTMathTextVerticalOrientation value)
{
verticalOrientation=value;
}
void JKQTMathTextVerticalListNode::setLineSpacingFactor(double value)
{
lineSpacingFactor=value;
}
void JKQTMathTextVerticalListNode::setSpacingMode(JKQTMathTextLineSpacingMode value)
{
spacingMode=value;
}
JKQTMathTextVerticalListNode::LayoutInfo::LayoutInfo():
JKQTMathTextNodeSize(), X()
{}
JKQTMathTextVerticalListNode::LayoutInfo::LayoutInfo(const JKQTMathTextNodeSize &other):
JKQTMathTextNodeSize(other),
X()
{
}
JKQTMathTextVerticalListNode::LayoutInfo &JKQTMathTextVerticalListNode::LayoutInfo::operator=(const JKQTMathTextNodeSize &other)
{
JKQTMathTextNodeSize::operator=(other);
X.clear();
return *this;
}
JKQTMathTextVerticalListNode::LayoutInfo &JKQTMathTextVerticalListNode::LayoutInfo::operator=(const LayoutInfo &other)
{
JKQTMathTextNodeSize::operator=(dynamic_cast<const JKQTMathTextNodeSize&>(other));
X=other.X;
return *this;
}
JKQTMathTextVerticalListNode::LayoutInfo::LayoutInfo(const LayoutInfo &other):
JKQTMathTextNodeSize(dynamic_cast<const JKQTMathTextNodeSize&>(other)),
X(other.X)
{
}

View File

@ -0,0 +1,109 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTMATHTEXTHONRIZONTALLISTNODE_H
#define JKQTMATHTEXTHONRIZONTALLISTNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include <QPainter>
#include <QFontMetricsF>
class JKQTMathText; // forward
// JKQTMATHTEXT_LIB_EXPORT
/** \brief subclass representing a list of nodes in the syntax tree, layed out horizontally
* \ingroup jkqtmathtext_items
*
* This type of node also implements typesetting sub-/superscript above/below the previous node (if
* JKQTMathTextNode::is() is \c true for that previus node. The drawing is done as defined in the
* following image:
* \image html jkqtmathtext_subsuper_with_limits.png
*
* In addition this node also ensures that subscripts are moved to the left for italic previous
* text or nodes that require such a shift (e.g. \c \\nabla or \c \\int ):
*
* \image html jkqtmathtext/jkqtmathtext_doc_subsuper_italiccorrection.png
*
* \image html jkqtmathtext/jkqtmathtext_doc_subsuper_italiccorrection_boxes.png
*
* This is implemented using JKQTMathTextNodeSize::baselineXCorrection .
*
* In addition this class implements execution of instructions derived from
* JKQTMathTextModifyEnvironmentNodeMixIn.
*
* \see JKQTMathTextVerticalListNode
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextHorizontalListNode: public JKQTMathTextMultiChildNode, public JKQTMathTextModifyEnvironmentNodeMixIn {
public:
explicit JKQTMathTextHorizontalListNode(JKQTMathText* parent);
virtual ~JKQTMathTextHorizontalListNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief add a child node */
void addChild(JKQTMathTextNode* n);
/** \copydoc JKQTMathTextMultiChildNode::getChildren() */
virtual QList<JKQTMathTextNode*> getChildren() override;
/** \copydoc JKQTMathTextMultiChildNode::childCount() */
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() */
virtual const JKQTMathTextNode* getChild(int i) const override;
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) override;
/** \copydoc JKQTMathTextModifyEnvironmentNodeMixIn::modifyEnvironment() */
virtual void modifyEnvironment(JKQTMathTextEnvironment& currentEv) const override;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief list of all nodes within the line */
QList<JKQTMathTextNode*> nodes;
private:
/** \brief internal implementation of clearChildren() that is non-virtual, so can be used in the destructor */
void clearChildrenImpl(bool deleteChildren);
};
#endif // JKQTMATHTEXTHONRIZONTALLISTNODE_H

View File

@ -87,7 +87,7 @@ double JKQTMathTextSimpleInstructionNode::draw(QPainter &painter, double x, doub
const QFontMetricsF fm(f);
const QString txt=executeInstruction();
const QRectF bb=fm.boundingRect(txt);
painter.setPen(currentEv.color);
painter.setFont(f);
painter.drawText(x,y,txt);
return x+bb.width();
@ -199,759 +199,3 @@ JKQTMathTextSimpleInstructionNode::InstructionProperties::InstructionProperties(
JKQTMathTextModifiedTextPropsInstructionNode::JKQTMathTextModifiedTextPropsInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
{
fillInstructions();
}
JKQTMathTextModifiedTextPropsInstructionNode::~JKQTMathTextModifiedTextPropsInstructionNode() {
}
QString JKQTMathTextModifiedTextPropsInstructionNode::getTypeName() const
{
return QLatin1String("JKQTMathTextModifiedTextPropsInstructionNode(")+instructionName+")";
}
JKQTMathTextNodeSize JKQTMathTextModifiedTextPropsInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
JKQTMathTextEnvironment ev=currentEv;
executeInstruction(ev);
return getChild()->getSize(painter, ev);
}
double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;
executeInstruction(ev);
//std::cout<<" MODNODE: "<<getInstructionName().toStdString()<<" ev.mathMode="<<ev.insideMath<<", ev.forceUpright="<<ev.insideMathForceDigitsUpright<<"\n";
return getChild()->draw(painter, x, y, ev);
}
bool JKQTMathTextModifiedTextPropsInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
executeInstruction(ev);
return getChild()->toHtml(html, ev, defaultEv);
}
bool JKQTMathTextModifiedTextPropsInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
size_t JKQTMathTextModifiedTextPropsInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
return 0;
}
void JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(const QString &instructionName, bool &insideMath, const QStringList& params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMath=insideMath;
instructions[instructionName].modifier(ev, params);
insideMath=ev.insideMath;
}
}
void JKQTMathTextModifiedTextPropsInstructionNode::executeInstruction(JKQTMathTextEnvironment &ev) const
{
fillInstructions();
instructions.value(getInstructionName(), InstructionProperties()).modifier(ev, getParameters());
}
QHash<QString, JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties> JKQTMathTextModifiedTextPropsInstructionNode::instructions;
void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
{
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bf"] = i;
instructions["textbf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbf"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=!ev.italic;
}, 0);
instructions["em"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["it"] = i;
instructions["textit"] = i;
instructions["mathit"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters) {
ev.color=jkqtp_String2QColor(parameters.value(0, ev.color.name()));
}, 1);
instructions["textcolor"] = i;
instructions["mathcolor"] = i;
instructions["color"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters) {
ev.customFontName=parameters.value(0, "");
ev.font=MTECustomFont;
}, 1);
instructions["userfont"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.beginMathMode();
}, 0);
instructions["ensuremath"] = i;
instructions["equation"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.smallCaps=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["sc"] = i;
instructions["textsc"] = i;
instructions["mathsc"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.underlined=true;
}, 0);
instructions["ul"] = i;
instructions["underlined"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.overline=true;
}, 0);
instructions["ol"] = i;
instructions["overlined"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.strike=true;
}, 0);
instructions["strike"]= i;
instructions["st"]= i;
instructions["sout"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
}, 0);
instructions["rm"] = i;
instructions["textrm"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathrm"] = i;
instructions["unit"] = i;
instructions["operatorname"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfit"] = i;
instructions["bfit"] = i;
instructions["textbfit"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.endMathMode();
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
}, 0);
instructions["text"] = i;
instructions["mbox"] = i;
instructions["ensuretext"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
ev.bold=true;
}, 0);
instructions["mat"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathcal"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
}, 0);
instructions["cal"] = i;
instructions["textcal"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.italic=false;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfcal"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bbfcal"] = i;
instructions["textfcal"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
}, 0);
instructions["frak"] = i;
instructions["textfrak"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathfrak"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbffrak"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.bold=true;
}, 0);
instructions["bffrak"] = i;
instructions["textbffrak"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEblackboard;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bb"] = i;
instructions["textbb"] = i;
instructions["mathbb"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
}, 0);
instructions["tt"] = i;
instructions["texttt"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathtt"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.bold=true;
}, 0);
instructions["bftt"] = i;
instructions["textbftt"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.italic=false;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbftt"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
}, 0);
instructions["sf"] = i;
instructions["textsf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathsf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["itsf"] = i;
instructions["textitsf"] = i;
instructions["mathitsf"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
}, 0);
instructions["script"] = i;
instructions["scr"] = i;
instructions["textscript"] = i;
instructions["textscr"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathscript"] = i;
instructions["mathscr"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.bold=true;
}, 0);
instructions["bfscript"] = i;
instructions["bfscr"] = i;
instructions["textbfscript"] = i;
instructions["textbfscr"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfscript"] = i;
instructions["mathbfscr"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize/0.8;
}, 0);
instructions["displaystyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*0.8;
}, 0);
instructions["scriptstyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*0.8*0.8;
}, 0);
instructions["scriptscriptstyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*1.2;
}, 0);
instructions["bigsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*1.85;
}, 0);
instructions["Bigsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*2.4;
}, 0);
instructions["biggsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*3.1;
}, 0);
instructions["Biggsize"]= i;
}
}
JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties():
NParams(0),
modifier([](JKQTMathTextEnvironment&, const QStringList&) {})
{
}
JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties(const ModifyEnvironmentFunctor &_modifier, size_t _NParams):
NParams(_NParams),
modifier(_modifier)
{
}
JKQTMathTextBoxInstructionNode::JKQTMathTextBoxInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
{
fillInstructions();
}
JKQTMathTextBoxInstructionNode::~JKQTMathTextBoxInstructionNode() {
}
QString JKQTMathTextBoxInstructionNode::getTypeName() const
{
return QLatin1String("JKQTMathTextBoxInstructionNode(")+instructionName+")";
}
JKQTMathTextNodeSize JKQTMathTextBoxInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
JKQTMathTextEnvironment ev=currentEv;
const auto& inst=instructions.value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
const double lw=p.widthF();
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
JKQTMathTextNodeSize s;
s.width=cs.width+2.0*(padding+lw/2.0);
s.baselineHeight=cs.baselineHeight+padding+lw/2.0;
s.overallHeight=cs.overallHeight+2.0*(padding+lw/2.0);
s.strikeoutPos=cs.strikeoutPos;
return s;
}
double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;
const auto& inst=instructions.value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
const double lw=p.widthF();
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
const double rr=inst.roundingFactor*fmNonItalic.tightBoundingRect("x").width();
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setBrush(b);
painter.setPen(p);
const QRectF rect(x+lw/2.0, y-cs.baselineHeight-padding-lw/2.0, cs.width+2.0*padding, cs.overallHeight+2.0*padding);
if (rr>0) painter.drawRoundedRect(rect, rr, rr, Qt::AbsoluteSize);
else painter.drawRect(rect);
if (inst.doubleLine) {
painter.setBrush(Qt::NoBrush);
QPen p2=p;
p2.setWidthF(p.widthF()*0.6);
const QRectF recti(x+lw*2.5, y-cs.baselineHeight-lw/2.0-padding+2.0*lw, cs.width+2.0*padding-4.0*lw, cs.overallHeight+2.0*padding-4.0*lw);
if (rr>0) painter.drawRoundedRect(recti, rr, rr, Qt::AbsoluteSize);
else painter.drawRect(recti);
}
}
double xnew = getChild()->draw(painter, x+padding+lw/2.0, y, ev);
return xnew+padding+lw/2.0;
}
bool JKQTMathTextBoxInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
const auto& inst=instructions.value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
//const double lw=p.widthF();
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
//const double rr=inst.roundingFactor*fmNonItalic.tightBoundingRect("x").width();
QString s=QString("padding: %1px").arg(padding);
if (p!=Qt::NoPen) {
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
if (p.widthF()>0 && p.color()!=Qt::transparent) s=s+"border-color: "+p.color().name();
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
if (p.widthF()>0 && p.color()!=Qt::transparent) s=s+QString("border-width: %1px").arg(p.width());
}
if (b!=Qt::NoBrush) {
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
if (b.color()!=Qt::transparent) s=s+"background-color: "+b.color().name();
}
if (s.size()>0) html=html+ QString("<span style=\"%1\">").arg(s);
bool ok=getChild()->toHtml(html, ev, defaultEv);
if (s.size()>0) html=html+"</span>";
return ok;
}
bool JKQTMathTextBoxInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
size_t JKQTMathTextBoxInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
return 0;
}
void JKQTMathTextBoxInstructionNode::modifyInMathEnvironment(const QString &instructionName, bool &insideMath, const QStringList& params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMath=insideMath;
instructions[instructionName].modifier(ev, params);
insideMath=ev.insideMath;
}
}
QHash<QString, JKQTMathTextBoxInstructionNode::InstructionProperties> JKQTMathTextBoxInstructionNode::instructions;
void JKQTMathTextBoxInstructionNode::fillInstructions()
{
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
instructions["fbox"] = i;
instructions["framebox"] = i;
instructions["boxed"] = i;
instructions["framed"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.doubleLine=true;
instructions["doublebox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.roundingFactor=0.7;
instructions["ovalbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setWidthF(p.widthF()*1.5);
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.roundingFactor=0.8;
instructions["Ovalbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
i.roundingFactor=0.7;
i.doubleLine=true;
instructions["ovaldoublebox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setColor(jkqtp_String2QColor(parameters.value(0, p.color().name())));
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/1);
instructions["colorbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setStyle(Qt::DashLine);
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
instructions["dashbox"] = i;
instructions["dashedbox"] = i;
instructions["dbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setStyle(Qt::DotLine);
return p;
},
InstructionProperties::NoBrush,
InstructionProperties::DefaultPadding,
/*Nparams=*/0);
instructions["dottedbox"] = i;
instructions["dotbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::NoPen,
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& parameters, JKQTMathText* /*parent*/){
return QBrush(jkqtp_String2QColor(parameters.value(0, QColor(Qt::transparent).name())), Qt::SolidPattern);
},
InstructionProperties::DefaultPadding,
/*Nparams=*/1);
instructions["shaded"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::NoPen,
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& parameters, JKQTMathText* /*parent*/){
return QBrush(jkqtp_String2QColor(parameters.value(0, QColor(Qt::transparent).name())), Qt::SolidPattern);
},
0,
/*Nparams=*/1);
instructions["snugshade"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
InstructionProperties::DefaultPen,
InstructionProperties::NoBrush,
0,
/*Nparams=*/0);
instructions["snugbox"] = i;
}
{
InstructionProperties i(InstructionProperties::NoModification,
[](JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent){
QPen p=InstructionProperties::DefaultPen(ev, parameters, parent);
p.setColor(jkqtp_String2QColor(parameters.value(0, p.color().name())));
return p;
},
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& parameters, JKQTMathText* /*parent*/){
return QBrush(jkqtp_String2QColor(parameters.value(1, QColor(Qt::transparent).name())), Qt::SolidPattern);
},
InstructionProperties::DefaultPadding,
/*Nparams=*/2);
instructions["fcolorbox"] = i;
}
}
JKQTMathTextBoxInstructionNode::InstructionProperties::ModifyEnvironmentFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoModification=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/){};
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::DefaultPen=
[](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, JKQTMathText* parent){ return QPen(ev.color, QFontMetricsF(ev.getFont(parent)).lineWidth(), Qt::SolidLine); };
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoPen=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/, JKQTMathText* /*parent*/){ return Qt::NoPen; };
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxBrushFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoBrush=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/, JKQTMathText* /*parent*/){ return Qt::NoBrush; };
double JKQTMathTextBoxInstructionNode::InstructionProperties::DefaultPadding=0.5;
JKQTMathTextBoxInstructionNode::InstructionProperties::InstructionProperties():
InstructionProperties(NoModification, DefaultPen, NoBrush, DefaultPadding, 0)
{
}
JKQTMathTextBoxInstructionNode::InstructionProperties::InstructionProperties(const GetBoxPenFunctor &_pen, const GetBoxBrushFunctor &_brush, double _paddingFactor, size_t _NParams):
InstructionProperties(NoModification, _pen, _brush, _paddingFactor, _NParams)
{
}
JKQTMathTextBoxInstructionNode::InstructionProperties::InstructionProperties(const ModifyEnvironmentFunctor &_modifier, const GetBoxPenFunctor &_pen, const GetBoxBrushFunctor &_brush, double _paddingFactor, size_t _NParams):
NParams(_NParams),
modifier(_modifier),
pen(_pen),
brush(_brush),
paddingFactor(_paddingFactor),
doubleLine(false),
roundingFactor(0.0)
{
}

View File

@ -120,151 +120,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSimpleInstructionNode: public JKQTMath
};
/** \brief subclass representing an instruction node which modifies the current font (as defined in JKQTMathTextEnvironment),
* i.e. it represents instructions like \c \\textbf{...}, \c \\ul{underlinedText}, ...
* \ingroup jkqtmathtext_items
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedTextPropsInstructionNode: public JKQTMathTextInstruction1Node {
public:
explicit JKQTMathTextModifiedTextPropsInstructionNode(JKQTMathText* parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters=QStringList());
virtual ~JKQTMathTextModifiedTextPropsInstructionNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMath to \c true if inside the node is to be parsed in math mode and \c false else
* \see instructions
*/
static void modifyInMathEnvironment(const QString& instructionName, bool& insideMath, const QStringList &params=QStringList());
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief defines the implementation of an instruction represented by JKQTMathTextModifiedTextPropsInstructionNode */
struct InstructionProperties {
/** \brief this functor implements the instruction */
typedef std::function<void(JKQTMathTextEnvironment& ev, const QStringList& parameters)> ModifyEnvironmentFunctor;
/** \brief default constructor, creates a NOP-instruction that does nothing */
InstructionProperties();
/** \brief constructor which gets a functor \a _modifier and a number of required parameters \a _NParams */
InstructionProperties(const ModifyEnvironmentFunctor& _modifier, size_t _NParams=0);
/** \brief number of parameters for this node */
size_t NParams;
/** \brief functor that modifies a JKQTMathTextEnvironment */
ModifyEnvironmentFunctor modifier;
};
/** \brief fills instructions
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
/** \brief executes the instruction on \a ev */
void executeInstruction(JKQTMathTextEnvironment& ev) const;
};
/** \brief subclass representing an instruction node which draws a (possibly colored) box around it's contents
* i.e. it represents instructions like \c \\fbox{...}, \c \\colorbox{color}{...}, ...
* \ingroup jkqtmathtext_items
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBoxInstructionNode: public JKQTMathTextInstruction1Node {
public:
explicit JKQTMathTextBoxInstructionNode(JKQTMathText* parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters=QStringList());
virtual ~JKQTMathTextBoxInstructionNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
*/
static void modifyInMathEnvironment(const QString& instructionName, bool& insideMath);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMath to \c true if inside the node is to be parsed in math mode and \c false else
* \see instructions
*/
static void modifyInMathEnvironment(const QString& instructionName, bool& insideMath, const QStringList &params=QStringList());
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief set all properties in \a ev, as appropriate for the represented instruction */
bool setupMTenvironment(JKQTMathTextEnvironment &ev) const;
/** \brief defines the implementation of an instruction represented by JKQTMathTextModifiedTextPropsInstructionNode */
struct InstructionProperties {
/** \brief this functor implements the instruction */
typedef std::function<void(JKQTMathTextEnvironment& ev, const QStringList& parameters)> ModifyEnvironmentFunctor;
static ModifyEnvironmentFunctor NoModification;
/** \brief this functor returns the QPen to use for the box outline */
typedef std::function<QPen(JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent)> GetBoxPenFunctor;
/** \brief generates a QPen with the lineWidth associated with the QFont of the environment (using QFontMetricsF::lineWidth() ) */
static GetBoxPenFunctor DefaultPen;
/** \brief generates an invisible pen with 0 width */
static GetBoxPenFunctor NoPen;
/** \brief this functor returns the QBrush to use for the box fill */
typedef std::function<QBrush(JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parent)> GetBoxBrushFunctor;
/** \brief generates an invisible QBrush */
static GetBoxBrushFunctor NoBrush;
/** \brief default padding factor 0.5 xWidth */
static double DefaultPadding;
/** \brief default constructor, creates a NOP-instruction that does nothing */
InstructionProperties();
/** \brief constructor */
InstructionProperties(const ModifyEnvironmentFunctor& _modifier, const GetBoxPenFunctor& _pen, const GetBoxBrushFunctor& _brush, double _paddingFactor=DefaultPadding, size_t _NParams=0);
/** \brief constructor */
InstructionProperties(const GetBoxPenFunctor& _pen, const GetBoxBrushFunctor& _brush, double _paddingFactor=DefaultPadding, size_t _NParams=0);
/** \brief number of parameters for this node */
size_t NParams;
/** \brief functor that modifies a JKQTMathTextEnvironment */
ModifyEnvironmentFunctor modifier;
/** \brief functor that creates a QPen for the box outline */
GetBoxPenFunctor pen;
/** \brief functor that creates a QBrush for the box fill */
GetBoxBrushFunctor brush;
/** \brief padding of the box, as a factor to xWidth of the current font */
double paddingFactor;
/** \brief draw a double-line */
bool doubleLine;
/** \brief rounding radius (rx=ry) of the box, as a factor to xWidth of the current font */
double roundingFactor;
};
/** \brief fills instructions
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
};
#endif // JKQTMATHTEXTINSTRUCTIONNODE_H

View File

@ -23,176 +23,9 @@
#ifndef JKQTMATHTEXTLISTNODE_H
#define JKQTMATHTEXTLISTNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include <QPainter>
#include <QFontMetricsF>
class JKQTMathText; // forward
// JKQTMATHTEXT_LIB_EXPORT
/** \brief subclass representing a list of nodes in the syntax tree, layed out horizontally
* \ingroup jkqtmathtext_items
*
* This type of node also implements typesetting sub-/superscript above/below the previous node (if
* JKQTMathTextNode::is() is \c true for that previus node. The drawing is done as defined in the
* following image:
* \image html jkqtmathtext_subsuper_with_limits.png
*
* In addition this node also ensures that subscripts are moved to the left for italic previous
* text or nodes that require such a shift (e.g. \c \\nabla or \c \\int ):
*
* \image html jkqtmathtext/jkqtmathtext_doc_subsuper_italiccorrection.png
*
* \image html jkqtmathtext/jkqtmathtext_doc_subsuper_italiccorrection_boxes.png
*
* This is implemented using JKQTMathTextNodeSize::baselineXCorrection .
*
* \see JKQTMathTextVerticalListNode
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextHorizontalListNode: public JKQTMathTextMultiChildNode {
public:
explicit JKQTMathTextHorizontalListNode(JKQTMathText* parent);
virtual ~JKQTMathTextHorizontalListNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief add a child node */
void addChild(JKQTMathTextNode* n);
/** \copydoc JKQTMathTextMultiChildNode::getChildren() */
virtual QList<JKQTMathTextNode*> getChildren() override;
/** \copydoc JKQTMathTextMultiChildNode::childCount() */
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() */
virtual const JKQTMathTextNode* getChild(int i) const override;
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) override;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
QList<JKQTMathTextNode*> nodes;
private:
/** \brief internal implementation of clearChildren() that is non-virtual, so can be used in the destructor */
void clearChildrenImpl(bool deleteChildren);
};
/** \brief subclass representing a list of nodes in the syntax tree, layed out vertically
* \ingroup jkqtmathtext_items
*
* Each child can be thought of as a line, so this node represents a list of lines.
* The layout of the lines can left-aligned, right-aligned or centered.
*
* \image html jkqtmathtext_verticallist.png
*
* \image html jkqtmathtext_verticalalignment.png
*
* \image html jkqtmathtext_horizontalalignment.png
*
* \see JKQTMathTextHorizontalListNode
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextVerticalListNode: public JKQTMathTextMultiChildNode {
public:
explicit JKQTMathTextVerticalListNode(JKQTMathText* parent, JKQTMathTextHorizontalAlignment _alignment=MTHACentered, double _linespacingFactor=1.0, JKQTMathTextLineSpacingMode spacingMode_=MTSMDefaultSpacing, JKQTMathTextVerticalOrientation _verticalOrientation=MTVOFirstLine);
virtual ~JKQTMathTextVerticalListNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief add a child node */
void addChild(JKQTMathTextNode* n);
/** \copydoc JKQTMathTextMultiChildNode::getChildren() */
virtual QList<JKQTMathTextNode*> getChildren() override;
/** \copydoc JKQTMathTextMultiChildNode::childCount() */
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() */
virtual const JKQTMathTextNode* getChild(int i) const override;
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) override;
/** \copydoc alignment */
JKQTMathTextHorizontalAlignment getAlignment() const;
/** \copydoc verticalOrientation */
JKQTMathTextVerticalOrientation getVerticalOrientation() const;
/** \copydoc lineSpacingFactor */
double getLineSpacingFactor() const;
/** \copydoc spacingMode */
JKQTMathTextLineSpacingMode getSpacingMode() const;
/** \copydoc alignment */
void setAlignment(JKQTMathTextHorizontalAlignment value) ;
/** \copydoc verticalOrientation */
void setVerticalOrientation(JKQTMathTextVerticalOrientation value) ;
/** \copydoc lineSpacingFactor */
void setLineSpacingFactor(double value);
/** \copydoc spacingMode */
void setSpacingMode(JKQTMathTextLineSpacingMode value) ;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief describes the layout of the whole node */
struct LayoutInfo: public JKQTMathTextNodeSize {
LayoutInfo();
LayoutInfo(const LayoutInfo& other);
LayoutInfo(const JKQTMathTextNodeSize& other);
LayoutInfo& operator=(const LayoutInfo& other);
LayoutInfo& operator=(const JKQTMathTextNodeSize& other);
/** \brief drawing position for each line */
QList<QPointF> X;
};
/** \brief calclates the layout of the whole block/node */
LayoutInfo calcLayout(QPainter& painter, JKQTMathTextEnvironment currentEv) const;
/** \brief list of child nodes, each representing one line */
QList<JKQTMathTextNode*> nodes;
/** \brief alignment scheme used to lay out all lines
*
* \image html jkqtmathtext_horizontalalignment.png
*/
JKQTMathTextHorizontalAlignment alignment;
/** \brief spacing of the separate lines, as factor of the default line-spacing [Default: 1].
*
* This property can be used to move the lines closer together or farther apart.
*
* \image html jkqtmathtext_verticallist.png
*/
double lineSpacingFactor;
/** \brief vertical orientation of the baseline of the whole block (with respect to the single lines)
*
* \image html jkqtmathtext_verticalorientation.png
*/
JKQTMathTextVerticalOrientation verticalOrientation;
/** \brief defines how the layout algorithm (see calcLayout() ) lays out the single lines */
JKQTMathTextLineSpacingMode spacingMode;
private:
/** \brief internal implementation of clearChildren() that is non-virtual, so can be used in the destructor */
void clearChildrenImpl(bool deleteChildren);
};
#include "jkqtmathtext/nodes/jkqtmathtextverticallistnode.h"
#include "jkqtmathtext/nodes/jkqtmathtexthorizontallistnode.h"
#endif // JKQTMATHTEXTLISTNODE_H

View File

@ -20,6 +20,7 @@
#include "jkqtmathtext/nodes/jkqtmathtextmatrixnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextnoopnode.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/jkqtmathtext.h"
#include "jkqtcommon/jkqtpcodestructuring.h"
@ -315,9 +316,9 @@ JKQTMathTextMatrixNode::LayoutInfo JKQTMathTextMatrixNode::calcLayout(QPainter &
{
LayoutInfo l;
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
JKQTMathTextEnvironment ev1=currentEv;
const QFontMetricsF fm(ev1.getFont(parentMathText), painter.device());
const double strikepos=fm.strikeOutPos();
const double xwidth=fm.boundingRect("x").width();
const double lw=fm.lineWidth()*1.5;
@ -347,13 +348,17 @@ JKQTMathTextMatrixNode::LayoutInfo JKQTMathTextMatrixNode::calcLayout(QPainter &
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());
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(children[i].at(j));
if (modEnvNode) {
modEnvNode->modifyEnvironment(ev1);
}
}
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;
l.overallHeight=static_cast<double>(lines-1)*YSeparation+l.topPadding+l.bottomPadding;
l.width=static_cast<double>(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+strikepos;
@ -406,6 +411,11 @@ double JKQTMathTextMatrixNode::draw(QPainter& painter, double x, double y, JKQTM
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);
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(children[i].at(j));
if (modEnvNode) {
modEnvNode->modifyEnvironment(ev1);
}
}
if (i<lines-1) {

View File

@ -0,0 +1,833 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
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 <http://www.gnu.org/licenses/>.
*/
#include "jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/jkqtmathtext.h"
#include "jkqtcommon/jkqtpcodestructuring.h"
#include "jkqtcommon/jkqtpstringtools.h"
#include <cmath>
#include <QFontMetricsF>
#include <QDebug>
#include <QFontDatabase>
#include <QFontInfo>
#include <QApplication>
#include <QFont>
JKQTMathTextModifiedTextPropsInstructionNode::JKQTMathTextModifiedTextPropsInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
{
fillInstructions();
}
JKQTMathTextModifiedTextPropsInstructionNode::~JKQTMathTextModifiedTextPropsInstructionNode() {
}
QString JKQTMathTextModifiedTextPropsInstructionNode::getTypeName() const
{
return QLatin1String("JKQTMathTextModifiedTextPropsInstructionNode(")+instructionName+")";
}
JKQTMathTextNodeSize JKQTMathTextModifiedTextPropsInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
JKQTMathTextEnvironment ev=currentEv;
executeInstruction(ev);
return getChild()->getSize(painter, ev);
}
double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;
executeInstruction(ev);
//std::cout<<" MODNODE: "<<getInstructionName().toStdString()<<" ev.mathMode="<<ev.insideMath<<", ev.forceUpright="<<ev.insideMathForceDigitsUpright<<"\n";
return getChild()->draw(painter, x, y, ev);
}
bool JKQTMathTextModifiedTextPropsInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
executeInstruction(ev);
return getChild()->toHtml(html, ev, defaultEv);
}
bool JKQTMathTextModifiedTextPropsInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
size_t JKQTMathTextModifiedTextPropsInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
return 0;
}
void JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(const QString &instructionName, bool &insideMath, bool& insideMathTextStyle, const QStringList& params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMath=insideMath;
ev.insideMathUseTextStyle=insideMathTextStyle;
instructions[instructionName].modifier(ev, params);
insideMath=ev.insideMath;
insideMathTextStyle=ev.insideMathUseTextStyle;
}
}
void JKQTMathTextModifiedTextPropsInstructionNode::executeInstruction(JKQTMathTextEnvironment &ev) const
{
fillInstructions();
instructions.value(getInstructionName(), InstructionProperties()).modifier(ev, getParameters());
}
QHash<QString, JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties> JKQTMathTextModifiedTextPropsInstructionNode::instructions;
void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
{
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=false;
ev.insideMathForceDigitsUpright=true;
ev.italic=false;
ev.underlined=false;
ev.overline=false;
ev.strike=false;
ev.font=MTEroman;
}, 0);
instructions["textnormal"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["textbf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbf"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["textit"] = i;
instructions["mathit"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=!ev.italic;
}, 0);
instructions["emph"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.italic=false;
}, 0);
instructions["textup"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters) {
ev.color=jkqtp_String2QColor(parameters.value(0, ev.color.name()));
}, 1);
instructions["textcolor"] = i;
instructions["mathcolor"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters) {
ev.customFontName=parameters.value(0, "");
ev.font=MTECustomFont;
}, 1);
instructions["userfont"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.beginMathMode();
}, 0);
instructions["ensuremath"] = i;
instructions["equation"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.capitalization=QFont::SmallCaps;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["textsc"] = i;
instructions["mathsc"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.capitalization=QFont::AllUppercase;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["uppercase"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.capitalization=QFont::AllLowercase;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["lowercase"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.underlined=true;
}, 0);
instructions["ul"] = i;
instructions["underlined"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.overline=true;
}, 0);
instructions["ol"] = i;
instructions["overlined"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.strike=true;
}, 0);
instructions["strike"]= i;
instructions["st"]= i;
instructions["sout"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
}, 0);
instructions["textrm"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathrm"] = i;
instructions["unit"] = i;
instructions["operatorname"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=true;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfit"] = i;
instructions["textbfit"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.endMathMode();
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
}, 0);
instructions["text"] = i;
instructions["mbox"] = i;
instructions["ensuretext"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
ev.bold=true;
}, 0);
instructions["mat"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathcal"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
}, 0);
instructions["textcal"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.italic=false;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfcal"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["textfcal"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
}, 0);
instructions["textfrak"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathfrak"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbffrak"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.bold=true;
}, 0);
instructions["textbffrak"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEblackboard;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["textbb"] = i;
instructions["mathbb"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
}, 0);
instructions["texttt"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathtt"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.bold=true;
}, 0);
instructions["textbftt"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.italic=false;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbftt"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
}, 0);
instructions["textsf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathsf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["textitsf"] = i;
instructions["mathitsf"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
}, 0);
instructions["textscript"] = i;
instructions["textscr"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathscript"] = i;
instructions["mathscr"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.bold=true;
}, 0);
instructions["textbfscript"] = i;
instructions["textbfscr"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.bold=true;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["mathbfscript"] = i;
instructions["mathbfscr"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*1.2;
}, 0);
instructions["bigsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*1.85;
}, 0);
instructions["Bigsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*2.4;
}, 0);
instructions["biggsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*3.1;
}, 0);
instructions["Biggsize"]= i;
}
}
JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties():
NParams(0),
modifier([](JKQTMathTextEnvironment&, const QStringList&) {})
{
}
JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties(const ModifyEnvironmentFunctor &_modifier, size_t _NParams):
NParams(_NParams),
modifier(_modifier)
{
}
JKQTMathTextModifiedEnvironmentInstructionNode::JKQTMathTextModifiedEnvironmentInstructionNode(JKQTMathText *parent_, const QString &name_, const QStringList &parameters_):
JKQTMathTextNonDrawingBaseNode(parent_), JKQTMathTextModifyEnvironmentNodeMixIn(),
instructionName(name_),
parameters(parameters_)
{
fillInstructions();
}
JKQTMathTextModifiedEnvironmentInstructionNode::~JKQTMathTextModifiedEnvironmentInstructionNode()
{
}
QString JKQTMathTextModifiedEnvironmentInstructionNode::getTypeName() const
{
return "MTModifyEnvironmentInstructionNode";
}
const QString &JKQTMathTextModifiedEnvironmentInstructionNode::getInstructionName() const
{
return instructionName;
}
const QStringList &JKQTMathTextModifiedEnvironmentInstructionNode::getParameters() const
{
return parameters;
}
void JKQTMathTextModifiedEnvironmentInstructionNode::modifyEnvironment(JKQTMathTextEnvironment &currentEv) const
{
fillInstructions();
instructions.value(getInstructionName(), InstructionProperties()).modifier(currentEv, getParameters(), parentMathText);
}
bool JKQTMathTextModifiedEnvironmentInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
size_t JKQTMathTextModifiedEnvironmentInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
return 0;
}
void JKQTMathTextModifiedEnvironmentInstructionNode::modifyInMathTextStyleEnvironment(const QString &instructionName, bool &insideMathTextStyle, JKQTMathText* parentMathText, const QStringList &params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMathUseTextStyle=insideMathTextStyle;
instructions[instructionName].modifier(ev, params, parentMathText);
insideMathTextStyle=ev.insideMathUseTextStyle;
}
}
QHash<QString, JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties> JKQTMathTextModifiedEnvironmentInstructionNode::instructions;
void JKQTMathTextModifiedEnvironmentInstructionNode::fillInstructions()
{
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.bold=false;
ev.insideMathForceDigitsUpright=true;
ev.italic=false;
ev.underlined=false;
ev.overline=false;
ev.strike=false;
ev.font=MTEroman;
ev.fontSize=parentMathText->getFontSize();
ev.capitalization=QFont::MixedCase;
ev.color=parentMathText->getFontColor();
}, 0);
instructions["normalfont"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.bold=false;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["md"] = i;
instructions["mdseries"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bf"] = i;
instructions["bfseries"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["it"] = i;
instructions["itshape"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["up"] = i;
instructions["upshape"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.italic=!ev.italic;
}, 0);
instructions["em"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters, const JKQTMathText* parentMathText) {
ev.color=jkqtp_String2QColor(parameters.value(0, ev.color.name()));
}, 1);
instructions["color"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters, const JKQTMathText* parentMathText) {
ev.customFontName=parameters.value(0, "");
ev.font=MTECustomFont;
}, 1);
instructions["setfont"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.capitalization=QFont::SmallCaps;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["sc"] = i;
instructions["scshape"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEroman;
ev.italic=false;
}, 0);
instructions["rm"] = i;
instructions["rmfamily"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.bold=true;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bfit"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
}, 0);
instructions["cal"] = i;
instructions["calfamily"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEcaligraphic;
ev.bold=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bbfcal"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
}, 0);
instructions["frak"] = i;
instructions["frakfamily"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEfraktur;
ev.bold=true;
}, 0);
instructions["bffrak"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEblackboard;
ev.italic=false;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["bb"] = i;
instructions["bbfamily"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
}, 0);
instructions["tt"] = i;
instructions["ttfamily"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEtypewriter;
ev.bold=true;
}, 0);
instructions["bftt"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
}, 0);
instructions["sf"] = i;
instructions["sffamily"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEsans;
ev.italic=true;
ev.insideMathForceDigitsUpright=false;
}, 0);
instructions["itsf"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
}, 0);
instructions["script"] = i;
instructions["scr"] = i;
instructions["scriptseries"] = i;
instructions["scrseries"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.font=JKQTMathTextEnvironmentFont::MTEscript;
ev.bold=true;
}, 0);
instructions["bfscript"] = i;
instructions["bfscr"] = i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize();
ev.insideMathUseTextStyle=false;
}, 0);
instructions["displaystyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize();
ev.insideMathUseTextStyle=true;
}, 0);
instructions["textstyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*0.75;
ev.insideMathUseTextStyle=true;
}, 0);
instructions["scriptstyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*0.5;
ev.insideMathUseTextStyle=true;
}, 0);
instructions["scriptscriptstyle"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*6.0/11.0;
}, 0);
instructions["tiny"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*7.0/11.0;
}, 0);
instructions["ssmall"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*8.0/11.0;
}, 0);
instructions["scriptsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*9.0/11.0;
}, 0);
instructions["footnotesize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*10.0/11.0;
}, 0);
instructions["small"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*11.0/11.0;
}, 0);
instructions["normalsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*12.0/11.0;
}, 0);
instructions["large"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*14.4/11.0;
}, 0);
instructions["Large"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*17.28/11.0;
}, 0);
instructions["LARGE"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*20.74/11.0;
}, 0);
instructions["huge"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
ev.fontSize=parentMathText->getFontSize()*24.88/11.0;
}, 0);
instructions["Huge"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& parameters, const JKQTMathText* parentMathText) {
ev.fontSize=parameters.value(0, QString::number(ev.fontSize)).toDouble();
ev.fontSizeUnit=JKQTMathTextEnvironment::POINTS;
}, 1);
instructions["userfontsize"]= i;
instructions["fontsize"]= i;
}
}
JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties::InstructionProperties():
NParams(0),
modifier([](JKQTMathTextEnvironment&, const QStringList&, const JKQTMathText*) {})
{
}
JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties::InstructionProperties(const ModifyEnvironmentFunctor &_modifier, size_t _NParams):
NParams(_NParams),
modifier(_modifier)
{
}

View File

@ -0,0 +1,170 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTMATHTEXTMODIFYTEXTPROPSINSTRUCTIONNODE_H
#define JKQTMATHTEXTMODIFYTEXTPROPSINSTRUCTIONNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h"
#include <QPainter>
#include <functional>
class JKQTMathText; // forward
// JKQTMATHTEXT_LIB_EXPORT
/** \brief subclass representing an instruction node which modifies the current
* font (as defined in JKQTMathTextEnvironment), for it's child node,
* i.e. it represents instructions like \c \\textbf{...}, \c \\ul{underlinedText}, ...
* \ingroup jkqtmathtext_items
*
* \note Instructions that modify the text for any further nodes WITHIN the
* current block are represented by JKQTMathTextModifiedEnvironmentInstructionNode
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedTextPropsInstructionNode: public JKQTMathTextInstruction1Node {
public:
explicit JKQTMathTextModifiedTextPropsInstructionNode(JKQTMathText* parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters=QStringList());
virtual ~JKQTMathTextModifiedTextPropsInstructionNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMath to \c true if inside the node is to be parsed in math mode and \c false else
* \see instructions
*/
static void modifyInMathEnvironment(const QString& instructionName, bool& insideMath, bool &insideMathTextStyle, const QStringList &params=QStringList());
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief defines the implementation of an instruction represented by JKQTMathTextModifiedTextPropsInstructionNode */
struct InstructionProperties {
/** \brief this functor implements the instruction */
typedef std::function<void(JKQTMathTextEnvironment& ev, const QStringList& parameters)> ModifyEnvironmentFunctor;
/** \brief default constructor, creates a NOP-instruction that does nothing */
InstructionProperties();
/** \brief constructor which gets a functor \a _modifier and a number of required parameters \a _NParams */
InstructionProperties(const ModifyEnvironmentFunctor& _modifier, size_t _NParams=0);
/** \brief number of parameters for this node */
size_t NParams;
/** \brief functor that modifies a JKQTMathTextEnvironment */
ModifyEnvironmentFunctor modifier;
};
/** \brief fills instructions
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
/** \brief executes the instruction on \a ev */
void executeInstruction(JKQTMathTextEnvironment& ev) const;
};
/** \brief subclass representing an instruction node which modify the
* current JKQTMathTextEnvironment, in the current block. This
* implements functions like \c \\bf or \c \\color{COL}
* \ingroup jkqtmathtext_items
*
* \see JKQTMathTextModifyEnvironmentNodeMixIn
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedEnvironmentInstructionNode: public JKQTMathTextNonDrawingBaseNode, public JKQTMathTextModifyEnvironmentNodeMixIn {
public:
explicit JKQTMathTextModifiedEnvironmentInstructionNode(JKQTMathText* parent_, const QString& instructionName_, const QStringList& parameters_=QStringList());
virtual ~JKQTMathTextModifiedEnvironmentInstructionNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc instructionName */
const QString& getInstructionName() const;
/** \copydoc parameters */
const QStringList& getParameters() const;
/** \copydoc JKQTMathTextModifyEnvironmentNodeMixIn::modifyEnvironment() */
virtual void modifyEnvironment(JKQTMathTextEnvironment& currentEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMathTextStyle to \c true if textstyle is set inside math
* \see instructions
*/
static void modifyInMathTextStyleEnvironment(const QString& instructionName, bool &insideMathTextStyle, JKQTMathText *parentMathText, const QStringList &params=QStringList());
protected:
/** \brief instruction name */
QString instructionName;
/** \brief additional string-parameters */
QStringList parameters;
/** \brief defines the implementation of an instruction represented by JKQTMathTextModifiedTextPropsInstructionNode */
struct InstructionProperties {
/** \brief this functor implements the instruction */
typedef std::function<void(JKQTMathTextEnvironment& ev, const QStringList& parameters, JKQTMathText* parentMathText)> ModifyEnvironmentFunctor;
/** \brief default constructor, creates a NOP-instruction that does nothing */
InstructionProperties();
/** \brief constructor which gets a functor \a _modifier and a number of required parameters \a _NParams */
InstructionProperties(const ModifyEnvironmentFunctor& _modifier, size_t _NParams=0);
/** \brief number of parameters for this node */
size_t NParams;
/** \brief functor that modifies a JKQTMathTextEnvironment */
ModifyEnvironmentFunctor modifier;
};
/** \brief fills instructions
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
};
#endif // JKQTMATHTEXTMODIFYTEXTPROPSINSTRUCTIONNODE_H

View File

@ -374,33 +374,35 @@ void JKQTMathTextMultiChildNode::setDrawBoxes(bool draw)
}
JKQTMathTextNoopNode::JKQTMathTextNoopNode(JKQTMathText *parent):
JKQTMathTextNonDrawingBaseNode::JKQTMathTextNonDrawingBaseNode(JKQTMathText *parent):
JKQTMathTextNode(parent)
{
}
JKQTMathTextNoopNode::~JKQTMathTextNoopNode()
JKQTMathTextNonDrawingBaseNode::~JKQTMathTextNonDrawingBaseNode()
{
}
QString JKQTMathTextNoopNode::getTypeName() const
{
return "MTNoopNode";
}
bool JKQTMathTextNoopNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const
{
return true;
}
double JKQTMathTextNoopNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
double JKQTMathTextNonDrawingBaseNode::draw(QPainter &/*painter*/, double x, double /*y*/, JKQTMathTextEnvironment /*currentEv*/) const
{
return x;
}
JKQTMathTextNodeSize JKQTMathTextNoopNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
bool JKQTMathTextNonDrawingBaseNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/) const
{
return true;
}
JKQTMathTextNodeSize JKQTMathTextNonDrawingBaseNode::getSizeInternal(QPainter &/*painter*/, JKQTMathTextEnvironment /*currentEv*/) const
{
return JKQTMathTextNodeSize();
}

View File

@ -282,23 +282,47 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDualChildNode: public JKQTMathTextMult
/** \brief subclass representing a node that outputs nothing
/** \brief base class for all derived classes that do not draw anything
* \ingroup jkqtmathtext_items
*
* This class finalizes draw() with no drawing actions and and getSizeInternal(), which
* return a size 0.
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNoopNode: public JKQTMathTextNode {
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNonDrawingBaseNode: public JKQTMathTextNode {
public:
explicit JKQTMathTextNoopNode(JKQTMathText* parent);
virtual ~JKQTMathTextNoopNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
explicit JKQTMathTextNonDrawingBaseNode(JKQTMathText* parent);
virtual ~JKQTMathTextNonDrawingBaseNode() override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override final;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override final;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override final;
};
/** \brief mixin extending a node that does not produce any output,
* but provides a function modifyEnvironment() that modifies the current
* JKQTMathTextEnvironment. Deriving classes are used to represent
* instructions like \c \\bf or \c \\color{...} that alter the text
* formatting for all further nodes in the current block.
* \ingroup jkqtmathtext_items
*
* Classes derived from this require a parent node that executes the additional method
* modifyEnvironment(). In the context of JKQTMathText, this is done by JKQTMathTextHorizontalListNode .
* Therefor the effect of the node end with the last nod in the parent list node.
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifyEnvironmentNodeMixIn {
public:
inline virtual ~JKQTMathTextModifyEnvironmentNodeMixIn() {};
/** \brief modifies the fiven JKQTMathTextEnvironment \a currrentEv */
virtual void modifyEnvironment(JKQTMathTextEnvironment& currentEv) const=0;
protected:
};
#endif // JKQTMATHTEXTNODE_H

View File

@ -0,0 +1,81 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
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 <http://www.gnu.org/licenses/>.
*/
#include "jkqtmathtext/nodes/jkqtmathtextnoopnode.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include "jkqtmathtext/jkqtmathtext.h"
JKQTMathTextNoopNode::JKQTMathTextNoopNode(JKQTMathText *parent):
JKQTMathTextNonDrawingBaseNode(parent)
{
}
JKQTMathTextNoopNode::~JKQTMathTextNoopNode()
{
}
QString JKQTMathTextNoopNode::getTypeName() const
{
return "MTNoopNode";
}
JKQTMathTextBlockNode::JKQTMathTextBlockNode(JKQTMathTextNode *_child, JKQTMathText *parent):
JKQTMathTextSingleChildNode(_child, parent)
{
}
JKQTMathTextBlockNode::~JKQTMathTextBlockNode()
{
}
QString JKQTMathTextBlockNode::getTypeName() const
{
return "MTBlockNode";
}
double JKQTMathTextBlockNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
{
return child->draw(painter, x, y, currentEv);
}
bool JKQTMathTextBlockNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const
{
return child->toHtml(html, currentEv, defaultEv);
}
JKQTMathTextNodeSize JKQTMathTextBlockNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
{
return child->getSize(painter, currentEv);
}

View File

@ -0,0 +1,82 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTMATHTEXTNOOPNODE_H
#define JKQTMATHTEXTNOOPNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include <QPainter>
class JKQTMathText; // forward
/** \brief subclass representing a node that outputs nothing
* \ingroup jkqtmathtext_items
*
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNoopNode: public JKQTMathTextNonDrawingBaseNode {
public:
explicit JKQTMathTextNoopNode(JKQTMathText* parent);
virtual ~JKQTMathTextNoopNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
protected:
};
/** \brief subclass representing a \c {...} block
* \ingroup jkqtmathtext_items
*
* This is necessray becaus JKQTMathtextHorizontalListNode
* implements JKQTMathTextModifyEnvironmentNodeMixIn, but a
* \c {...} block does not hand on its modified JKQTMathTextEnvironment.
*
* This node simply hands on all calls to its child.
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBlockNode: public JKQTMathTextSingleChildNode {
public:
explicit JKQTMathTextBlockNode(JKQTMathTextNode *_child, JKQTMathText* parent);
virtual ~JKQTMathTextBlockNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
};
#endif // JKQTMATHTEXTNOOPNODE_H

View File

@ -432,6 +432,12 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UnicodeSymbol(co
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor));
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolStd(const QString &symbol)
{
QString html=symbol;
return UprightSymbolStd(symbol, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UnicodeSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol), html);
@ -447,6 +453,13 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolStd
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolUnicode(const QString &symbol)
{
QString html=symbol;
return UprightSymbolUnicode(symbol, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolUnicode(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol, ItalicOff), html, ItalicOff);
@ -529,14 +542,14 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["backslash"]=SimpleTextSymbol("\\");
symbols["benzene"]=UprightSymbolUnicode(QChar(0x232C));
symbols["benzenr"]=UprightSymbolUnicode(QChar(0x23E3));
symbols["blacksquare"]=UprightSymbolUnicode(QChar(0x220E)).addHtml("&squ;");
symbols["blacksquare"]=UprightSymbolUnicode(QChar(0x220E)).addUprightHtml("&squ;");
{ auto s=UprightSymbolUnicode(QChar(0x231E));
symbols["blcorner"]=s; symbols["llcorner"]=s; }
{ auto s=UprightSymbolUnicode(QChar(0x231F));
symbols["brcorner"]=s; symbols["lrcorner"]=s; }
{ auto s=UprightSymbolUnicode(QChar(0x2022)).addUprightHtml("&bull;").addUprightWinSymbol(QChar(0xB7));
symbols["bullet"]=s; symbols["textbullet"]=s; }
symbols["cdots"]=UprightSymbolUnicode(QChar(0x22EF)).addHtml("&middot;&middot;&middot;").addStd(QString(3, QChar(0xB7)));
symbols["cdots"]=UprightSymbolUnicode(QChar(0x22EF)).addUprightHtml("&middot;&middot;&middot;").addUprightStd(QString(3, QChar(0xB7)));
{ auto s=UnicodeSymbol(QChar(0x2103)).addUprightStd("°C").addUprightHtml("&deg;C");
symbols["celsius"]=s; symbols["degC"]=s; symbols["degreeCelsius"]=s; }
symbols["ell"]=UprightSymbolUnicode(QChar(0x2113), "&ell;");
@ -584,13 +597,13 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["hbar"]=UprightSymbolUnicode(QChar(0x210F)).addUprightHtml("&hbar;").addStd("h", ItalicOn|DrawLeftHBar).addGlobalFlags(SubscriptCorrection);
symbols["hexagon"]=UprightSymbolUnicode(QChar(0x2394));
symbols["ii"] = SymbolFullProps(SymbolProps("i", Upright|BoldOff), "i", Upright|BoldOff);
symbols["infty"]=UnicodeSymbol(QChar(0x221E)).addHtml("&infin;").addWinSymbol(QChar(0xA5)).addStd("8", RotateSymbol90);
symbols["infty"]=UprightSymbolUnicode(QChar(0x221E)).addUprightHtml("&infin;").addUprightWinSymbol(QChar(0xA5)).addUprightStd("8", RotateSymbol90);
symbols["langle"]=UprightSymbolUnicode(QChar(0x2329)).addWinSymbol(QChar(0xE1));
symbols["lceil"]=UprightSymbolUnicode(QChar(0x2308)).addHtml("&LeftCeiling;").addWinSymbol(QChar(0xE9));
symbols["lfloor"]=UprightSymbolUnicode(QChar(0x230A)).addHtml("&LeftFloor;").addWinSymbol(QChar(0xEB));
symbols["lceil"]=UprightSymbolUnicode(QChar(0x2308)).addUprightHtml("&LeftCeiling;").addUprightWinSymbol(QChar(0xE9));
symbols["lfloor"]=UprightSymbolUnicode(QChar(0x230A)).addUprightHtml("&LeftFloor;").addUprightWinSymbol(QChar(0xEB));
symbols["lightning"]=UnicodeSymbol(QChar(0x21AF));
symbols["male"]=UnicodeSymbol(QChar(0x2642)).addHtml("&male;");
symbols["measuredangle"]=UprightSymbolUnicode(QChar(0x2221)).addHtml("&measuredangle;");
symbols["measuredangle"]=UprightSymbolUnicode(QChar(0x2221)).addUprightHtml("&measuredangle;");
symbols["micro"] = SimpleTextSymbol(QChar(0xB5), "&micro;");
symbols["ohm"]=UprightSymbolUnicode(QChar(0x2126)).addUprightHtml("&Omega;").addUprightWinSymbol(QChar(0x57));
symbols["partial"]=UprightSymbolUnicode(QChar(0x2202)).addUprightHtml("&part;").addUprightWinSymbol(QChar(0xB6));
@ -601,14 +614,14 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["prime"]=UnicodeSymbol(QChar(0x2032)).addHtml("&prime;").addStd("'");
symbols["arcminute"]=UnicodeSymbol(QChar(0x2032)).addHtml("&prime;").addStd("'");
symbols["arcsecond"]=UnicodeSymbol(QChar(0x2033)).addHtml("&dprime;").addStd("'");
symbols["rangle"]=UprightSymbolUnicode(QChar(0x232A)).addWinSymbol(QChar(0xF1));
symbols["rceil"]=UprightSymbolUnicode(QChar(0x2309)).addHtml("&RightCeiling;").addWinSymbol(QChar(0xF9));
symbols["rangle"]=UprightSymbolUnicode(QChar(0x232A)).addUprightWinSymbol(QChar(0xF1));
symbols["rceil"]=UprightSymbolUnicode(QChar(0x2309)).addUprightHtml("&RightCeiling;").addUprightWinSymbol(QChar(0xF9));
{ auto s=SimpleTextSymbol(QChar(0xAE), "&reg;");
symbols["registered"]=s; symbols["textregistered"]=s; symbols["circledR"]=s; }
symbols["rfloor"]=UprightSymbolUnicode(QChar(0x230B)).addHtml("&RightFloor;").addWinSymbol(QChar(0xFB));
symbols["rightangle"]=UprightSymbolUnicode(QChar(0x221F)).addHtml("&angrt;");
symbols["smile"]=UprightSymbolUnicode(QChar(0x2323)).addHtml("&smile;");
symbols["sphericalangle"]=UprightSymbolUnicode(QChar(0x2222)).addHtml("&angsph;");
symbols["rfloor"]=UprightSymbolUnicode(QChar(0x230B)).addUprightHtml("&RightFloor;").addUprightWinSymbol(QChar(0xFB));
symbols["rightangle"]=UprightSymbolUnicode(QChar(0x221F)).addUprightHtml("&angrt;");
symbols["smile"]=UprightSymbolUnicode(QChar(0x2323)).addUprightHtml("&smile;");
symbols["sphericalangle"]=UprightSymbolUnicode(QChar(0x2222)).addUprightHtml("&angsph;");
symbols["star"]=UprightSymbolUnicode(QChar(0x22C6));
symbols["tcohm"]=UnicodeSymbol(QChar(0x2126));
{ auto s=UnicodeSymbol(QChar(0x2014), "&#11840;");

View File

@ -65,6 +65,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \copydoc symbolName */
QString getSymbolName() const;
/** \brief return type for getSymbolSize(), extends JKQTMathTextNodeSize with information about x-correction for sub- and superscript */
@ -91,7 +92,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
static bool hasSymbol(const QString& symbolName);
/** \brief return a list of all defined symbols */
static QStringList getSymbols();
/** \brief checks whether the given symbol name codes for an instruction that has SymbolFullProps::SubSuperscriptBelowAboveSymbol , i.e. JKQTMathTextNode::isSubSuperscriptAboveBelowNode() \c ==true */
/** \brief checks whether the given symbol name codes for an instruction that has SymbolFullProps::SubSuperscriptBelowAboveSymbol , does not neccessarily return the same value as JKQTMathTextNode::isSubSuperscriptAboveBelowNode() */
static bool isSubSuperscriptBelowAboveSymbol(const QString& symbolName);
/** \brief checks whether the given symbol has global flags SymbolFullProps::ExtendWidthInMathmode or SymbolFullProps::SmallExtendWidthInMathmode defined */
static bool isExtendedWidthSymbol(const QString& symbolName);
@ -283,9 +284,13 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
/** \brief constructs a SymbolProps for a symbol with encoding in UnicodeFull-fonts a */
static SymbolFullProps UnicodeSymbol(const QString& symbol, SymbolFlags _flags=AsOutside, double _fontScalingFactor=1.0, double _yShiftFactor=0.0);
/** \brief constructs a SymbolProps for a symbol with encoding in Standard-fonts a */
static SymbolFullProps UprightSymbolStd(const QString& symbol, const QString& html=QString());
static SymbolFullProps UprightSymbolStd(const QString& symbol);
/** \brief constructs a SymbolProps for a symbol with encoding in UnicodeFull-fonts a */
static SymbolFullProps UprightSymbolUnicode(const QString& symbol, const QString& html=QString());
static SymbolFullProps UprightSymbolUnicode(const QString& symbol);
/** \brief constructs a SymbolProps for a symbol with encoding in Standard-fonts a */
static SymbolFullProps UprightSymbolStd(const QString& symbol, const QString& html);
/** \brief constructs a SymbolProps for a symbol with encoding in UnicodeFull-fonts a */
static SymbolFullProps UprightSymbolUnicode(const QString& symbol, const QString& html);
/** \brief constructs a SymbolProps for a math-operator symbol like \c \\pm ... in unicode-full-encoding, i.e. ItalicOff, BoldOff, ExtendWidthInMathmode */
static SymbolFullProps MathOperatorSymbolUnicode(const QString& unicode);
/** \brief constructs a SymbolProps for a narrow math-operator symbol like \c \\pm ... in unicode-full-encoding, i.e. ItalicOff, BoldOff, SmallExtendWidthInMathmode */

View File

@ -381,210 +381,6 @@ QString JKQTMathTextTextNode::textTransform(const QString &text, const JKQTMathT
JKQTMathTextVerbatimNode::JKQTMathTextVerbatimNode(JKQTMathText *_parent, const QString& _text, bool visibleWhitespace_, JKQTMathTextHorizontalAlignment _alignment, double _linespacingFactor, JKQTMathTextVerticalOrientation _verticalOrientation, size_t tabSize_):
JKQTMathTextTextBaseNode(_parent, _text),
alignment(_alignment),
lineSpacingFactor(_linespacingFactor),
verticalOrientation(_verticalOrientation),
visibleWhitespace(visibleWhitespace_),
tabSize(tabSize_)
{
}
QString JKQTMathTextVerbatimNode::getTypeName() const
{
return QLatin1String("JKQTMathTextVerbatimNode");
}
JKQTMathTextHorizontalAlignment JKQTMathTextVerbatimNode::getAlignment() const
{
return alignment;
}
JKQTMathTextVerticalOrientation JKQTMathTextVerbatimNode::getVerticalOrientation() const
{
return verticalOrientation;
}
double JKQTMathTextVerbatimNode::getLineSpacingFactor() const
{
return lineSpacingFactor;
}
bool JKQTMathTextVerbatimNode::getVisibleWhitespace() const
{
return visibleWhitespace;
}
size_t JKQTMathTextVerbatimNode::getTabSize() const
{
return tabSize;
}
double JKQTMathTextVerbatimNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
{
transformEnvironment(currentEv);
const LayoutInfo l=calcLayout(painter, currentEv);
doDrawBoxes(painter, x, y, l);
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
f.setFixedPitch(true);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setFont(f);
for (int i=0; i<l.lines.size(); i++) {
painter.drawText(QPointF(x+l.X.at(i).x(), y+l.X.at(i).y()), l.lines.at(i));
}
return x+l.width;
}
bool JKQTMathTextVerbatimNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const
{
transformEnvironment(currentEv);
const bool isMultiLine=text.count('\n')>0;
html+=currentEv.toHtmlStart(defaultEv, parentMathText);
if (isMultiLine) {
if (alignment==MTHALeft) {
html+="<div align=\"left\">";
} else if (alignment==MTHACentered) {
html+="<div align=\"center\">";
} else if (alignment==MTHARight) {
html+="<div align=\"right\">";
}
}
html+="<pre>";
html+=textTransform(text, currentEv).toHtmlEscaped();
html+="</pre>";
if (isMultiLine) html+="</div>";
html+=currentEv.toHtmlAfter(defaultEv, parentMathText);
return true;
}
JKQTMathTextNodeSize JKQTMathTextVerbatimNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
{
transformEnvironment(currentEv);
return calcLayout(painter, currentEv);
}
void JKQTMathTextVerbatimNode::transformEnvironment(JKQTMathTextEnvironment &currentEv) const
{
currentEv.font=MTEtypewriter;
}
JKQTMathTextVerbatimNode::LayoutInfo JKQTMathTextVerbatimNode::calcLayout(QPainter &painter, const JKQTMathTextEnvironment& currentEv) const
{
LayoutInfo l;
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
f.setFixedPitch(true);
const QFontMetricsF fm(f);
const double linespacing=fm.lineSpacing()*lineSpacingFactor;
const double fleading=fm.leading();
const double synLeading=fm.lineWidth();
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
if (text.size()<=0) {
return l;
}
l.lines=textTransform(text, currentEv).split('\n');
// from now on we have at least one child node!!!
QList<double> widths, heights, ascents, descents, strikeouts;
double heightSum=0;
QList<double> ysFromFirstLine; // y-position of each line, where the first line is always at y=0 (i.e. ysFromFirstLine[0]==0)
double y=0;
for (int i=0; i<l.lines.size(); i++) {
if (i==0) {
heightSum=fm.ascent();
} else if (i>0) {
const double deltaLine=qMax(linespacing, descents.last()+lineLeading+fm.ascent());
heightSum=heightSum+deltaLine;
y=y+deltaLine;
}
widths<<fm.boundingRect(l.lines[i]).width();
l.width=qMax(l.width, widths.last());
heights<<fm.height();
ascents<<fm.ascent();
descents<<fm.descent();
strikeouts<<fm.strikeOutPos();
ysFromFirstLine<<y;
}
heightSum+=descents.last();
l.overallHeight=heightSum;
double y0=0;
if (verticalOrientation==MTVOTop) {
l.baselineHeight=0;
l.strikeoutPos=0;
y0=ascents.first();
} else if (verticalOrientation==MTVOFirstLine) {
l.baselineHeight=ascents.first();
l.strikeoutPos=strikeouts.first();
y0=0;
} else if (verticalOrientation==MTVOCentered) {
l.baselineHeight=heightSum/2.0;
l.strikeoutPos=heightSum/4.0;
y0=-heightSum/2.0+ascents.first();
} else if (verticalOrientation==MTVOLastLine) {
l.baselineHeight=heightSum-descents.last();
l.strikeoutPos=strikeouts.last();
y0=-(heightSum-ascents.first()-descents.last());
} else if (verticalOrientation==MTVOBottom) {
l.baselineHeight=heightSum;
l.strikeoutPos=0;
y0=-(heightSum-ascents.first());
}
for (int i=0; i<l.lines.size(); i++) {
double x=0;
if (alignment==MTHARight) x=l.width-widths[i];
else if (alignment==MTHACentered) x=(l.width-widths[i])/2.0;
l.X<<QPointF(x,ysFromFirstLine[i]+y0);
}
return l;
}
QString JKQTMathTextVerbatimNode::textTransform(const QString &text, const JKQTMathTextEnvironment &currentEv) const
{
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
const QFontMetricsF fm(f);
QString spRep=QChar(0xB7);
if (!fm.inFont(spRep[0])) {
spRep=QChar(0x2423);
}
QString tabRep=QString(tabSize,QChar(0x2192));
if (!fm.inFont(tabRep[0])) {
spRep=QString(tabSize,QChar(0xAC));
}
QString res=JKQTMathTextTextBaseNode::textTransform(text, currentEv);
if (res.startsWith('\n')) res=res.right(res.size()-1);
if (res.endsWith('\n')) res=res.left(res.size()-1);
if (visibleWhitespace) {
res.replace(' ', spRep);
res.replace('\t', tabRep);
return res;
} else {
res.replace('\t', QString(tabSize, ' '));
return res;
}
return res;
}
JKQTMathTextVerbatimNode::LayoutInfo::LayoutInfo():
JKQTMathTextNodeSize(), lines(), X()
{
}
JKQTMathTextTextNode::LayoutInfo::LayoutInfo():
JKQTMathTextNodeSize(),
textpart(), fontMode(), textpartXPos()

View File

@ -118,83 +118,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextTextBaseN
};
/** \brief subclass representing a verbatim (plain-text) node with support for line-breaks in the syntax tree
* \ingroup jkqtmathtext_items
*
* The layout of the lines can left-aligned, right-aligned or centered.
*
* \image html jkqtmathtext_verticallist.png
*
* \image html jkqtmathtext_verticalalignment.png
*
* \image html jkqtmathtext_horizontalalignment.png
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextVerbatimNode: public JKQTMathTextTextBaseNode {
public:
explicit JKQTMathTextVerbatimNode(JKQTMathText* parent, const QString& text, bool visibleWhitespace=false, JKQTMathTextHorizontalAlignment _alignment=MTHALeft, double _linespacingFactor=1.0, JKQTMathTextVerticalOrientation _verticalOrientation=MTVOFirstLine, size_t tabSize_=4);
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc alignment */
JKQTMathTextHorizontalAlignment getAlignment() const;
/** \copydoc verticalOrientation */
JKQTMathTextVerticalOrientation getVerticalOrientation() const;
/** \copydoc lineSpacingFactor */
double getLineSpacingFactor() const;
/** \copydoc visibleWhitespace */
bool getVisibleWhitespace() const;
/** \copydoc tabSize */
size_t getTabSize() const;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
protected:
/** \brief alignment scheme used to lay out all lines
*
* \image html jkqtmathtext_horizontalalignment.png
*/
JKQTMathTextHorizontalAlignment alignment;
/** \brief spacing of the separate lines, as factor of the default line-spacing [Default: 1].
*
* This property can be used to move the lines closer together or farther apart.
*
* \image html jkqtmathtext_verticallist.png
*/
double lineSpacingFactor;
/** \brief vertical orientation of the baseline of the whole block (with respect to the single lines)
*
* \image html jkqtmathtext_verticalorientation.png
*/
JKQTMathTextVerticalOrientation verticalOrientation;
/** \brief when \c true, whitespaces are displayed with a visible character */
bool visibleWhitespace;
/** \brief number of whitespaces, each tab character stands for */
size_t tabSize;
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief sets all necessary settings in \a currentEv for drawing this node */
virtual void transformEnvironment(JKQTMathTextEnvironment& currentEv) const;
/** \brief describes the layout of the whole node */
struct LayoutInfo: public JKQTMathTextNodeSize {
LayoutInfo();
/** \brief the text from JKQTMathTextVerbatimNode::text, split into lines */
QStringList lines;
/** \brief drawing position for each line */
QList<QPointF> X;
};
/** \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;
/** \brief transforms the \a text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */
virtual QString textTransform(const QString& text, const JKQTMathTextEnvironment& currentEv) const override;
};
#endif // JKQTMATHTEXTTEXTNODE_H

View File

@ -0,0 +1,239 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
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 <http://www.gnu.org/licenses/>.
*/
#include "jkqtmathtext/nodes/jkqtmathtextverbatimnode.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include "jkqtmathtext/jkqtmathtext.h"
#include "jkqtcommon/jkqtpcodestructuring.h"
#include "jkqtcommon/jkqtpstringtools.h"
#include <cmath>
#include <QFontMetricsF>
#include <QDebug>
#include <QFontDatabase>
#include <QFontInfo>
#include <QApplication>
#include <QFont>
JKQTMathTextVerbatimNode::JKQTMathTextVerbatimNode(JKQTMathText *_parent, const QString& _text, bool visibleWhitespace_, JKQTMathTextHorizontalAlignment _alignment, double _linespacingFactor, JKQTMathTextVerticalOrientation _verticalOrientation, size_t tabSize_):
JKQTMathTextTextBaseNode(_parent, _text),
alignment(_alignment),
lineSpacingFactor(_linespacingFactor),
verticalOrientation(_verticalOrientation),
visibleWhitespace(visibleWhitespace_),
tabSize(tabSize_)
{
}
QString JKQTMathTextVerbatimNode::getTypeName() const
{
return QLatin1String("JKQTMathTextVerbatimNode");
}
JKQTMathTextHorizontalAlignment JKQTMathTextVerbatimNode::getAlignment() const
{
return alignment;
}
JKQTMathTextVerticalOrientation JKQTMathTextVerbatimNode::getVerticalOrientation() const
{
return verticalOrientation;
}
double JKQTMathTextVerbatimNode::getLineSpacingFactor() const
{
return lineSpacingFactor;
}
bool JKQTMathTextVerbatimNode::getVisibleWhitespace() const
{
return visibleWhitespace;
}
size_t JKQTMathTextVerbatimNode::getTabSize() const
{
return tabSize;
}
double JKQTMathTextVerbatimNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
{
transformEnvironment(currentEv);
const LayoutInfo l=calcLayout(painter, currentEv);
doDrawBoxes(painter, x, y, l);
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
f.setFixedPitch(true);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setFont(f);
for (int i=0; i<l.lines.size(); i++) {
painter.drawText(QPointF(x+l.X.at(i).x(), y+l.X.at(i).y()), l.lines.at(i));
}
return x+l.width;
}
bool JKQTMathTextVerbatimNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const
{
transformEnvironment(currentEv);
const bool isMultiLine=text.count('\n')>0;
html+=currentEv.toHtmlStart(defaultEv, parentMathText);
if (isMultiLine) {
if (alignment==MTHALeft) {
html+="<div align=\"left\">";
} else if (alignment==MTHACentered) {
html+="<div align=\"center\">";
} else if (alignment==MTHARight) {
html+="<div align=\"right\">";
}
}
html+="<pre>";
html+=textTransform(text, currentEv).toHtmlEscaped();
html+="</pre>";
if (isMultiLine) html+="</div>";
html+=currentEv.toHtmlAfter(defaultEv, parentMathText);
return true;
}
JKQTMathTextNodeSize JKQTMathTextVerbatimNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
{
transformEnvironment(currentEv);
return calcLayout(painter, currentEv);
}
void JKQTMathTextVerbatimNode::transformEnvironment(JKQTMathTextEnvironment &currentEv) const
{
currentEv.font=MTEtypewriter;
}
JKQTMathTextVerbatimNode::LayoutInfo JKQTMathTextVerbatimNode::calcLayout(QPainter &painter, const JKQTMathTextEnvironment& currentEv) const
{
LayoutInfo l;
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
f.setFixedPitch(true);
const QFontMetricsF fm(f);
const double linespacing=fm.lineSpacing()*lineSpacingFactor;
const double fleading=fm.leading();
const double synLeading=fm.lineWidth();
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
if (text.size()<=0) {
return l;
}
l.lines=textTransform(text, currentEv).split('\n');
// from now on we have at least one child node!!!
QList<double> widths, heights, ascents, descents, strikeouts;
double heightSum=0;
QList<double> ysFromFirstLine; // y-position of each line, where the first line is always at y=0 (i.e. ysFromFirstLine[0]==0)
double y=0;
for (int i=0; i<l.lines.size(); i++) {
if (i==0) {
heightSum=fm.ascent();
} else if (i>0) {
const double deltaLine=qMax(linespacing, descents.last()+lineLeading+fm.ascent());
heightSum=heightSum+deltaLine;
y=y+deltaLine;
}
widths<<fm.boundingRect(l.lines[i]).width();
l.width=qMax(l.width, widths.last());
heights<<fm.height();
ascents<<fm.ascent();
descents<<fm.descent();
strikeouts<<fm.strikeOutPos();
ysFromFirstLine<<y;
}
heightSum+=descents.last();
l.overallHeight=heightSum;
double y0=0;
if (verticalOrientation==MTVOTop) {
l.baselineHeight=0;
l.strikeoutPos=0;
y0=ascents.first();
} else if (verticalOrientation==MTVOFirstLine) {
l.baselineHeight=ascents.first();
l.strikeoutPos=strikeouts.first();
y0=0;
} else if (verticalOrientation==MTVOCentered) {
l.baselineHeight=heightSum/2.0;
l.strikeoutPos=heightSum/4.0;
y0=-heightSum/2.0+ascents.first();
} else if (verticalOrientation==MTVOLastLine) {
l.baselineHeight=heightSum-descents.last();
l.strikeoutPos=strikeouts.last();
y0=-(heightSum-ascents.first()-descents.last());
} else if (verticalOrientation==MTVOBottom) {
l.baselineHeight=heightSum;
l.strikeoutPos=0;
y0=-(heightSum-ascents.first());
}
for (int i=0; i<l.lines.size(); i++) {
double x=0;
if (alignment==MTHARight) x=l.width-widths[i];
else if (alignment==MTHACentered) x=(l.width-widths[i])/2.0;
l.X<<QPointF(x,ysFromFirstLine[i]+y0);
}
return l;
}
QString JKQTMathTextVerbatimNode::textTransform(const QString &text, const JKQTMathTextEnvironment &currentEv) const
{
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
const QFontMetricsF fm(f);
QString spRep=QChar(0xB7);
if (!fm.inFont(spRep[0])) {
spRep=QChar(0x2423);
}
QString tabRep=QString(tabSize,QChar(0x2192));
if (!fm.inFont(tabRep[0])) {
spRep=QString(tabSize,QChar(0xAC));
}
QString res=JKQTMathTextTextBaseNode::textTransform(text, currentEv);
if (res.startsWith('\n')) res=res.right(res.size()-1);
if (res.endsWith('\n')) res=res.left(res.size()-1);
if (visibleWhitespace) {
res.replace(' ', spRep);
res.replace('\t', tabRep);
return res;
} else {
res.replace('\t', QString(tabSize, ' '));
return res;
}
return res;
}
JKQTMathTextVerbatimNode::LayoutInfo::LayoutInfo():
JKQTMathTextNodeSize(), lines(), X()
{
}

View File

@ -0,0 +1,123 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTMATHTEXTVERBATIMNODE_H
#define JKQTMATHTEXTVERBATIMNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
#include <QPainter>
class JKQTMathText; // forward
// JKQTMATHTEXT_LIB_EXPORT
/** \brief subclass representing a verbatim (plain-text) node with support for line-breaks in the syntax tree
* \ingroup jkqtmathtext_items
*
* The layout of the lines can left-aligned, right-aligned or centered.
*
* \image html jkqtmathtext_verticallist.png
*
* \image html jkqtmathtext_verticalalignment.png
*
* \image html jkqtmathtext_horizontalalignment.png
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextVerbatimNode: public JKQTMathTextTextBaseNode {
public:
explicit JKQTMathTextVerbatimNode(JKQTMathText* parent, const QString& text, bool visibleWhitespace=false, JKQTMathTextHorizontalAlignment _alignment=MTHALeft, double _linespacingFactor=1.0, JKQTMathTextVerticalOrientation _verticalOrientation=MTVOFirstLine, size_t tabSize_=4);
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc alignment */
JKQTMathTextHorizontalAlignment getAlignment() const;
/** \copydoc verticalOrientation */
JKQTMathTextVerticalOrientation getVerticalOrientation() const;
/** \copydoc lineSpacingFactor */
double getLineSpacingFactor() const;
/** \copydoc visibleWhitespace */
bool getVisibleWhitespace() const;
/** \copydoc tabSize */
size_t getTabSize() const;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
protected:
/** \brief alignment scheme used to lay out all lines
*
* \image html jkqtmathtext_horizontalalignment.png
*/
JKQTMathTextHorizontalAlignment alignment;
/** \brief spacing of the separate lines, as factor of the default line-spacing [Default: 1].
*
* This property can be used to move the lines closer together or farther apart.
*
* \image html jkqtmathtext_verticallist.png
*/
double lineSpacingFactor;
/** \brief vertical orientation of the baseline of the whole block (with respect to the single lines)
*
* \image html jkqtmathtext_verticalorientation.png
*/
JKQTMathTextVerticalOrientation verticalOrientation;
/** \brief when \c true, whitespaces are displayed with a visible character */
bool visibleWhitespace;
/** \brief number of whitespaces, each tab character stands for */
size_t tabSize;
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief sets all necessary settings in \a currentEv for drawing this node */
virtual void transformEnvironment(JKQTMathTextEnvironment& currentEv) const;
/** \brief describes the layout of the whole node */
struct LayoutInfo: public JKQTMathTextNodeSize {
LayoutInfo();
/** \brief the text from JKQTMathTextVerbatimNode::text, split into lines */
QStringList lines;
/** \brief drawing position for each line */
QList<QPointF> X;
};
/** \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;
/** \brief transforms the \a text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */
virtual QString textTransform(const QString& text, const JKQTMathTextEnvironment& currentEv) const override;
};
#endif // JKQTMATHTEXTVERBATIMNODE_H

View File

@ -0,0 +1,312 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
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 <http://www.gnu.org/licenses/>.
*/
#include "jkqtmathtext/nodes/jkqtmathtextverticallistnode.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 <cmath>
#include <QFontMetricsF>
#include <QDebug>
#include <QFontDatabase>
#include <QFontInfo>
#include <QApplication>
#include <QFont>
JKQTMathTextVerticalListNode::JKQTMathTextVerticalListNode(JKQTMathText *_parent, JKQTMathTextHorizontalAlignment _alignment, double _linespacingFactor, JKQTMathTextLineSpacingMode spacingMode_, JKQTMathTextVerticalOrientation _verticalOrientation):
JKQTMathTextMultiChildNode(_parent),
alignment(_alignment),
lineSpacingFactor(_linespacingFactor),
verticalOrientation(_verticalOrientation),
spacingMode(spacingMode_)
{
nodes.clear();
// these operations cause sub/sup script to be typeset over/under the operator, not right besides!
}
JKQTMathTextVerticalListNode::~JKQTMathTextVerticalListNode() {
clearChildrenImpl(true);
}
QString JKQTMathTextVerticalListNode::getTypeName() const
{
return "MTVerticalListNode";
}
JKQTMathTextNodeSize JKQTMathTextVerticalListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
return calcLayout(painter, currentEv);
}
JKQTMathTextVerticalListNode::LayoutInfo JKQTMathTextVerticalListNode::calcLayout(QPainter &painter, JKQTMathTextEnvironment ev) const
{
JKQTMathTextEnvironment currentEv=ev;
LayoutInfo l;
if (nodes.size()<=0) {
return l;
}
// from now on we have at least one child node!!!
QList<double> widths, heights, ascents, descents, strikeouts;
double heightSum=0;
QList<double> ysFromFirstLine; // y-position of each line, where the first line is always at y=0 (i.e. ysFromFirstLine[0]==0)
double y=0;
for (int i=0; i<nodes.size(); i++) {
const QFontMetricsF fm(currentEv.getFont(parentMathText));
const double linespacing=fm.lineSpacing()*lineSpacingFactor;
const double fleading=fm.leading();
const double synLeading=fm.lineWidth();
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
const JKQTMathTextNodeSize loc=nodes[i]->getSize(painter, currentEv);
if (i==0) {
heightSum=loc.baselineHeight;
} else if (i>0) {
double deltaLine=0;
if (spacingMode==MTSMMinimalSpacing) {
deltaLine=descents.last()+lineLeading+loc.baselineHeight;
} else if (spacingMode==MTSMDefaultSpacing) {
deltaLine=qMax(linespacing, descents.last()+lineLeading+loc.baselineHeight);
}
heightSum=heightSum+deltaLine;
y=y+deltaLine;
}
widths<<loc.width;
l.width=qMax(l.width, loc.width);
heights<<loc.overallHeight;
ascents<<loc.baselineHeight;
descents<<(loc.overallHeight-loc.baselineHeight);
strikeouts<<loc.strikeoutPos;
ysFromFirstLine<<y;
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
heightSum+=descents.last();
l.overallHeight=heightSum;
double y0=0;
if (verticalOrientation==MTVOTop) {
l.baselineHeight=0;
l.strikeoutPos=0;
y0=ascents.first();
} else if (verticalOrientation==MTVOFirstLine) {
l.baselineHeight=ascents.first();
l.strikeoutPos=strikeouts.first();
y0=0;
} else if (verticalOrientation==MTVOCentered) {
l.baselineHeight=heightSum/2.0;
l.strikeoutPos=heightSum/4.0;
y0=-heightSum/2.0+ascents.first();
} else if (verticalOrientation==MTVOLastLine) {
l.baselineHeight=heightSum-descents.last();
l.strikeoutPos=strikeouts.last();
y0=-(heightSum-ascents.first()-descents.last());
} else if (verticalOrientation==MTVOBottom) {
l.baselineHeight=heightSum;
l.strikeoutPos=0;
y0=-(heightSum-ascents.first());
}
for (int i=0; i<nodes.size(); i++) {
double x=0;
if (alignment==MTHARight) x=l.width-widths[i];
else if (alignment==MTHACentered) x=(l.width-widths[i])/2.0;
l.X<<QPointF(x,ysFromFirstLine[i]+y0);
}
return l;
}
double JKQTMathTextVerticalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment ev) const {
JKQTMathTextEnvironment currentEv=ev;
doDrawBoxes(painter, x, y, currentEv);
const LayoutInfo l=calcLayout(painter, currentEv);
for (int i=0; i<nodes.size(); i++) {
nodes[i]->draw(painter, x+l.X.at(i).x(), y+l.X.at(i).y(), currentEv);
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
return x+l.width;
}
void JKQTMathTextVerticalListNode::addChild(JKQTMathTextNode *n) {
n->setParentNode(this);
nodes.append(n);
}
bool JKQTMathTextVerticalListNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
bool ok=true;
if (alignment==MTHALeft) {
html+="<div align=\"left\">";
} else if (alignment==MTHACentered) {
html+="<div align=\"center\">";
} else if (alignment==MTHARight) {
html+="<div align=\"right\">";
}
for (int i=0; i<nodes.size(); i++) {
QString h="";
ok = ok && nodes[i]->toHtml(h, currentEv, defaultEv);
if (i==0) html=html+h;
else html=html+"<br/>"+h;
JKQTMathTextModifyEnvironmentNodeMixIn* modEnvNode=dynamic_cast<JKQTMathTextModifyEnvironmentNodeMixIn*>(nodes[i]);
if (modEnvNode) {
modEnvNode->modifyEnvironment(currentEv);
}
}
html+="</div>";
return ok;
}
QList<JKQTMathTextNode *> JKQTMathTextVerticalListNode::getChildren() {
return this->nodes;
}
int JKQTMathTextVerticalListNode::childCount() const
{
return nodes.size();
}
void JKQTMathTextVerticalListNode::clearChildrenImpl(bool deleteChildren)
{
if (deleteChildren) {
for (int i=0; i<nodes.size(); i++) {
delete nodes[i];
}
}
nodes.clear();
}
void JKQTMathTextVerticalListNode::deleteChild(int i)
{
if (i>=0 && i<nodes.size()) {
delete nodes[i];
nodes.removeAt(i);
}
}
void JKQTMathTextVerticalListNode::clearChildren(bool deleteChildren)
{
clearChildrenImpl(deleteChildren);
}
JKQTMathTextNode *JKQTMathTextVerticalListNode::getChild(int i)
{
return nodes[i];
}
const JKQTMathTextNode *JKQTMathTextVerticalListNode::getChild(int i) const
{
return nodes[i];
}
JKQTMathTextNode *JKQTMathTextVerticalListNode::replaceChild(int i, JKQTMathTextNode *newChild)
{
JKQTMathTextNode* c=nodes[i];
nodes[i]=newChild;
newChild->setParentNode(this);
return c;
}
JKQTMathTextHorizontalAlignment JKQTMathTextVerticalListNode::getAlignment() const
{
return alignment;
}
JKQTMathTextVerticalOrientation JKQTMathTextVerticalListNode::getVerticalOrientation() const
{
return verticalOrientation;
}
double JKQTMathTextVerticalListNode::getLineSpacingFactor() const
{
return lineSpacingFactor;
}
JKQTMathTextLineSpacingMode JKQTMathTextVerticalListNode::getSpacingMode() const
{
return spacingMode;
}
void JKQTMathTextVerticalListNode::setAlignment(JKQTMathTextHorizontalAlignment value)
{
alignment=value;
}
void JKQTMathTextVerticalListNode::setVerticalOrientation(JKQTMathTextVerticalOrientation value)
{
verticalOrientation=value;
}
void JKQTMathTextVerticalListNode::setLineSpacingFactor(double value)
{
lineSpacingFactor=value;
}
void JKQTMathTextVerticalListNode::setSpacingMode(JKQTMathTextLineSpacingMode value)
{
spacingMode=value;
}
JKQTMathTextVerticalListNode::LayoutInfo::LayoutInfo():
JKQTMathTextNodeSize(), X()
{}
JKQTMathTextVerticalListNode::LayoutInfo::LayoutInfo(const JKQTMathTextNodeSize &other):
JKQTMathTextNodeSize(other),
X()
{
}
JKQTMathTextVerticalListNode::LayoutInfo &JKQTMathTextVerticalListNode::LayoutInfo::operator=(const JKQTMathTextNodeSize &other)
{
JKQTMathTextNodeSize::operator=(other);
X.clear();
return *this;
}
JKQTMathTextVerticalListNode::LayoutInfo &JKQTMathTextVerticalListNode::LayoutInfo::operator=(const LayoutInfo &other)
{
JKQTMathTextNodeSize::operator=(dynamic_cast<const JKQTMathTextNodeSize&>(other));
X=other.X;
return *this;
}
JKQTMathTextVerticalListNode::LayoutInfo::LayoutInfo(const LayoutInfo &other):
JKQTMathTextNodeSize(dynamic_cast<const JKQTMathTextNodeSize&>(other)),
X(other.X)
{
}

View File

@ -0,0 +1,150 @@
/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTMATHTEXTVERTCALLISTNODE_H
#define JKQTMATHTEXTVERTCALLISTNODE_H
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
#include <QPainter>
#include <QFontMetricsF>
class JKQTMathText; // forward
// JKQTMATHTEXT_LIB_EXPORT
/** \brief subclass representing a list of nodes in the syntax tree, layed out vertically
* \ingroup jkqtmathtext_items
*
* Each child can be thought of as a line, so this node represents a list of lines.
* The layout of the lines can left-aligned, right-aligned or centered.
*
* \image html jkqtmathtext_verticallist.png
*
* \image html jkqtmathtext_verticalalignment.png
*
* \image html jkqtmathtext_horizontalalignment.png
*
* \see JKQTMathTextHorizontalListNode
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextVerticalListNode: public JKQTMathTextMultiChildNode {
public:
explicit JKQTMathTextVerticalListNode(JKQTMathText* parent, JKQTMathTextHorizontalAlignment _alignment=MTHACentered, double _linespacingFactor=1.0, JKQTMathTextLineSpacingMode spacingMode_=MTSMDefaultSpacing, JKQTMathTextVerticalOrientation _verticalOrientation=MTVOFirstLine);
virtual ~JKQTMathTextVerticalListNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief add a child node */
void addChild(JKQTMathTextNode* n);
/** \copydoc JKQTMathTextMultiChildNode::getChildren() */
virtual QList<JKQTMathTextNode*> getChildren() override;
/** \copydoc JKQTMathTextMultiChildNode::childCount() */
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() */
virtual const JKQTMathTextNode* getChild(int i) const override;
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) override;
/** \copydoc alignment */
JKQTMathTextHorizontalAlignment getAlignment() const;
/** \copydoc verticalOrientation */
JKQTMathTextVerticalOrientation getVerticalOrientation() const;
/** \copydoc lineSpacingFactor */
double getLineSpacingFactor() const;
/** \copydoc spacingMode */
JKQTMathTextLineSpacingMode getSpacingMode() const;
/** \copydoc alignment */
void setAlignment(JKQTMathTextHorizontalAlignment value) ;
/** \copydoc verticalOrientation */
void setVerticalOrientation(JKQTMathTextVerticalOrientation value) ;
/** \copydoc lineSpacingFactor */
void setLineSpacingFactor(double value);
/** \copydoc spacingMode */
void setSpacingMode(JKQTMathTextLineSpacingMode value) ;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief describes the layout of the whole node */
struct LayoutInfo: public JKQTMathTextNodeSize {
LayoutInfo();
LayoutInfo(const LayoutInfo& other);
LayoutInfo(const JKQTMathTextNodeSize& other);
LayoutInfo& operator=(const LayoutInfo& other);
LayoutInfo& operator=(const JKQTMathTextNodeSize& other);
/** \brief drawing position for each line */
QList<QPointF> X;
};
/** \brief calclates the layout of the whole block/node */
LayoutInfo calcLayout(QPainter& painter, JKQTMathTextEnvironment currentEv) const;
/** \brief list of child nodes, each representing one line */
QList<JKQTMathTextNode*> nodes;
/** \brief alignment scheme used to lay out all lines
*
* \image html jkqtmathtext_horizontalalignment.png
*/
JKQTMathTextHorizontalAlignment alignment;
/** \brief spacing of the separate lines, as factor of the default line-spacing [Default: 1].
*
* This property can be used to move the lines closer together or farther apart.
*
* \image html jkqtmathtext_verticallist.png
*/
double lineSpacingFactor;
/** \brief vertical orientation of the baseline of the whole block (with respect to the single lines)
*
* \image html jkqtmathtext_verticalorientation.png
*/
JKQTMathTextVerticalOrientation verticalOrientation;
/** \brief defines how the layout algorithm (see calcLayout() ) lays out the single lines */
JKQTMathTextLineSpacingMode spacingMode;
private:
/** \brief internal implementation of clearChildren() that is non-virtual, so can be used in the destructor */
void clearChildrenImpl(bool deleteChildren);
};
#endif // JKQTMATHTEXTVERTCALLISTNODE_H