JKQtPlotter/lib/jkqtmathtext/jkqtmathtext.h

660 lines
40 KiB
C
Raw Normal View History

/*
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
2018-12-14 05:33:42 +08:00
with contributions from: Razi Alavizadeh
2015-07-12 22:34:27 +08:00
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 JKQTMATHTEXT_H
#define JKQTMATHTEXT_H
#include <QObject>
#include <QSettings>
#include <QPainter>
#include <QString>
#include <QSet>
#include <QFile>
#include "jkqtmathtext/jkqtmathtext_imexport.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include <QWidget>
#include <QLabel>
#include <QHash>
class JKQTMathTextNode; // forward
/*! \brief this class parses a LaTeX string and can then draw the contained text/equation onto a <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
\ingroup jkqtmathtext_render
2019-01-19 16:40:52 +08:00
JKQTMathText is a self-contained LaTeX-renderer for Qt. It is used to renderer
labels in JKQTPlotter/JKQTBasePlotter, but can be used independently.
2019-01-19 23:54:31 +08:00
The class does not depend on any library, except Qt.
In particular it actually parses a LaTeX string and draws it in pure C++. It does NOT rely
on an installed LaTeX for the rendering!
\section JKQTMathTextUsage Usage
\subsection JKQTMathTextUsageDirect Direct Usage
2019-01-19 23:54:31 +08:00
This small piece of C++ code may serve as an example of the usage and capabilities of the class:
2019-01-19 16:40:52 +08:00
\code
// create a JKQTMathText object.
JKQTMathText mathText;
2019-01-19 16:40:52 +08:00
// configure its properties to influence the rendering (e.g. fonts to use, font size, ...)
mathText.useXITS();
mathText.setFontSize(20);
2019-01-19 16:40:52 +08:00
// parse some LaTeX code (the Schroedinger's equation)
mathText.parse("$\\left[-\\frac{\\hbar^2}{2m}\\frac{\\partial^2}{\\partial x^2}+V(x)\\right]\\Psi(x)=\\mathrm{i}\\hbar\\frac{\\partial}{\\partial t}\\Psi(x)$");
// use the draw() methods to draw the equation using a QPainter (here onto a QPixmap)
QPainter painter;
QPixmap pix(600,400);
painter.begin(&pix);
mathText.draw(painter, Qt::AlignCenter, QRectF(0,0,pix.width(), pix.height()), false);
painter.end();
\endcode
2019-01-19 23:54:31 +08:00
\subsection JKQTMathTextSizing Determining the size of an equation
2019-01-19 23:54:31 +08:00
In addition there are also functions that allow to calculate the size of the equation, before drawing it (just like the functions in <a href="http://doc.qt.io/qt-5/qfontmetrics.html">QFontMetrics</a> and <a href="http://doc.qt.io/qt-5/qfontmetricsf.html">QFontMetricsF</a>):
- getSizeDetail()
- getSize()
- getAscent(), getDescent()
.
\subsection JKQTMathTextErrorHandling Error Handling
2019-01-19 23:54:31 +08:00
The class is designed to be as robust as possible and will still return some output, even if the equation contains some errors.
Nevertheless, several errors are detected while parsing. You can get a list of error messages using getErrorList() after calling parse().
2019-01-19 23:54:31 +08:00
Also parse() will return \c false if an error occured while parsing.
\subsection JKQTMathTextUsageQLabel Usage within a QLabel class JKQTMathTextLabel
2019-01-19 23:54:31 +08:00
Finally, there is also a QLabel-derived class JKQTMathTextLabel which can be used for drawing a LaTeX string onto a Qt form.
2019-01-19 23:54:31 +08:00
\see JKQTMathTextLabel
2019-01-19 23:54:31 +08:00
\section JKQTMathTextExamples Examples
2019-01-19 23:54:31 +08:00
Examples for the usage of this class can be found here:
- \ref JKQTMathTextSimpleExample
2019-01-19 23:54:31 +08:00
.
\section JKQTMathTextSuppoertedLaTeX Supported LaTeX Subset
\subsection JKQTMathTextSuppoertedLaTeXSimple Simple Instructions
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...} .
- \c $ : enter/leave math mode
- \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 \\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 \\ul{...} \c \\underline{...} \c \\underlined{...} : draw the text with underlining \image html jkqtmathtext/jkqtmathtext_ul.png
- \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
- \c \\ol{...} \c \\overline{...} \c \\overlined{...} : draw the text with overlining \image html jkqtmathtext/jkqtmathtext_ol.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 \\boxed{...} : draw text with a box around it \image html jkqtmathtext/jkqtmathtext_boxed.png
- \c \\colorbox{color}{...} : draw a colored box around text \image html jkqtmathtext/jkqtmathtext_colorbox.png
- \c \\alpha ... : display the according greek letter \image html jkqtmathtext/jkqtmathtext_greek.png
- \c ^{...} \c _{...} : display the contents of braces in superscript/subscript \image html jkqtmathtext/jkqtmathtext_supersub.png
<br>Special subscript/superscript typesetting applies, when the sub/super follows \c \\sum \c \\Prod ...: \image html jkqtmathtext/jkqtmathtext_specialsubsuper.png
- \c \\{ / \\} : display opening/closing brace
- \c \\_ : display underscore
- \c \\sum \c \\prod \c \\int ... : plot special symbol. Note that depending on the fontEncoding the available
symbols may differ (there are not all symbols defined in the MS Windows Symbol
font!). Best coverage should be given by Unicode font encoding with a good
unicode font installed!<br>\image html jkqtmathtext/jkqtmathtext_symbols.png
- <code>\\vec{x} \\dot{x} \\ddot{x} \\overline{x} \\underline{x} \\hat{x} \\tilde{x} \\uul{x} \\ool{x} \\bar{x} \\arrow{x} </code>: Decorations over/under symbols \image html jkqtmathtext/jkqtmathtext_mathdeco.png
- <code>\\verb{don't parse this _aaa\\LaTeX} </code>: interpret enclosed text as verbose \image html jkqtmathtext/jkqtmathtext_verb.png
.
\subsection JKQTMathTextSuppoertedLaTeXBraces Braces ...
Braces in math mode are adjusted in size, so they are a small bit (factor \c brace_factor ) larger than the contents.
To enable this you have to write braces with \c \\left and \c \\right. These types of braces are defined (slight
differences to LaTeX standard):
- \c \\left( \c \\right) : default meaning (), \image html jkqtmathtext/jkqtmathtext_brace_round.png
- \c \\left[ \c \\right] : default meaning [], \image html jkqtmathtext/jkqtmathtext_brace_rect.png
- \c \\left\\{ \c \\right\\} : default meaning {}, \image html jkqtmathtext/jkqtmathtext_brace_curly.png
- \c \\left< \c \\right> : "averaging" braces , \image html jkqtmathtext/jkqtmathtext_brace_tri.png
- \c \c \\left\\lfloor \c \\right\\rfloor : floor braces , \image html jkqtmathtext/jkqtmathtext_brace_floor.png
- \c \\left~ \c \\right~ \c \\left\\lceil \c \\right\\rceil : ceil braces , \image html jkqtmathtext/jkqtmathtext_brace_ceil.png
- \c \\left| \c \\right| : absolute value braces | |, \image html jkqtmathtext/jkqtmathtext_brace_oneline.png
- \code \left\| \right\| \endcode : norm braces || ||, \image html jkqtmathtext/jkqtmathtext_brace_dblline.png
- You can use \c \\left. or \c \\right. to have only right or only left brace
.
\subsection JKQTMathTextSuppoertedLaTeXUnderOver Undersetting, Oversetting, Underbraces, Overbraces ...
There are also instructions that allow to under/overset braces, arrows, ...:
- <code>$\\underbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/jkqtmathtext_brace_underbrace.png
- <code>$\\overbrace{x+x+...+x}{k\\ \\mathrm{times}}$</code> \image html jkqtmathtext/jkqtmathtext_brace_overbrace.png
- <code>$\\overset{main}{over}$</code> \image html jkqtmathtext/jkqtmathtext_brace_overset.png
- <code>$\\underset{main}{under}$</code> \image html jkqtmathtext/jkqtmathtext_brace_underset.png
.
\subsection JKQTMathTextSuppoertedLaTeXMatrix Matrix/Array Type Instructions
Several Matrix/Array-typed LaTeX instructions are supported:
- <code>$\\frac{...}{...}$</code>, <code>$\\tfrac{...}{...}$</code> (70% smaller font), <code>$\\dfrac{...}{...}$</code> \image html jkqtmathtext/jkqtmathtext_brace_frac.png
- <code>$\\sfrac{...}{...}$</code> \image html jkqtmathtext/MTFMsfrac.png
- <code>$\\stfrac{...}{...}$</code> (70% smaller font) \image html jkqtmathtext/MTFMstfrac.png
- <code>$\\stackrel{...}{...}$ $\\binom{...}{...}$</code> \image html jkqtmathtext/jkqtmathtext_brace_stackrel.png
- <code>$\\begin{cases} ... & ... \\\\ ... & ... \\end{cases}$</code> \image html jkqtmathtext/jkqtmathtext_brace_begincases.png
- <code>$\\begin{array} a & b & ...\\\\ c & d & ...\\end{array}$</code> <code>$\\begin{matrix} a & b & ...\\\\ c & d & ...\\end{matrix}$</code> \image html jkqtmathtext/jkqtmathtext_array.png
- <code>$\\begin{pmatrix} a & b & ...\\\\ c & d & ...\\end{pmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_pmatrix.png
- <code>$\\begin{bmatrix} a & b & ...\\\\ c & d & ...\\end{bmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_bmatrix.png
- <code>$\\begin{Bmatrix} a & b & ...\\\\ c & d & ...\\end{Bmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_bbmatrix.png
- <code>$\\begin{vmatrix} a & b & ...\\\\ c & d & ...\\end{vmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_vmatrix.png
- <code>$\\begin{Vmatrix} a & b & ...\\\\ c & d & ...\\end{Vmatrix}$</code> \image html jkqtmathtext/jkqtmathtext_vvmatrix.png
.
\section JKQTMathTextSuppoertedFonts Font Handling
2019-01-19 23:54:31 +08:00
Several fonts are defined as properties to the class:
- A "roman" font used as the standard font ( setFontRoman() )
- A "sans-serif" font which may be activated with \c \\sf ... ( setFontSans() )
- A "typewriter" font which may be activated with \c \\tt ... ( setFontTypewriter() )
- A "script" font which may be activated with \c \\script ... ( setFontScript() )
- A greek font which is used to display greek letters \c \\alpha ... ( setSymbolfontGreek() )
- A symbol font used to display special (math) symbols. ( setSymbolfontSymbol() )
- A "roman" font used as the standard font in math mode ( setFontMathRoman() )
- A "sans-serif" used as sans serif font in math mode ( setFontMathSans() )
- A "blackboard" font used to display double stroked characters ( setFontBlackboard() )
- A "caligraphic" font used to display caligraphic characters ( setFontCaligraphic() )
.
2019-01-19 23:54:31 +08:00
These fonts are generic font classes, which font is actually used can be configured in JKQTMathText class with the \c set...() functions mentioned above. You can also use these functions to set the fonts used for math rendering in math-mode:
- useSTIX() use the STIX fonts from <a href="https://www.stixfonts.org/">https://www.stixfonts.org/</a> in math-mode<br>\image html jkqtmathtext/jkqtmathparser_stix.png
- useXITS() use the XITS fonts from <a href="https://github.com/alif-type/xits">https://github.com/alif-type/xits</a> in math-mode. These are included by default in this library and also activated by default.<br>\image html jkqtmathtext/jkqtmathparser_xits.png
- useASANA() use the ASANA fonts from <a href="https://ctan.org/tex-archive/fonts/Asana-Math/">https://ctan.org/tex-archive/fonts/Asana-Math/</a> in math-mode<br>\image html jkqtmathtext/jkqtmathparser_asana.png
- useAnyUnicode() use generic Unicode fonts, e.g. "Arial" and "Times New Roman" in math-mode. You should use fonts that contain as many of the mathematical symbols as possible to ensure good rendering results.<br>using "Times New Roman": \image html jkqtmathtext/jkqtmathparser_timesnewroman.png
<br>using "Arial": \image html jkqtmathtext/jkqtmathparser_arial.png
<br>using "Courier New": \image html jkqtmathtext/jkqtmathparser_couriernew.png
<br>using "Comic Sans MS": \image html jkqtmathtext/jkqtmathparser_comicsans.png
2019-01-19 23:24:19 +08:00
.
2019-01-19 16:40:52 +08:00
2019-01-19 23:54:31 +08:00
Math-mode is activated by enclosing your equation in \c $...$ or \c \\[...\\] . This mode is optimized for mathematical equations. Here is an example of the difference:
- <b>math-mode (XITS fonts are used, whitespaces are mostly not drawn directly, symbol spacing is different)</b> \c $...$: <br>\image html jkqtmathtext/schreq_mathmode.png
- <b>normal mode (Times new Roman is used, whitespaces are evaluated directly)</b>: <br>\image html jkqtmathtext/schreq_normalmode.png
2019-01-19 23:54:31 +08:00
.
2019-01-19 16:40:52 +08:00
\section JKQTMathTextToHTML Convert to HTML
2019-01-19 23:54:31 +08:00
The method toHtml() may be used to get a HTML representation of the LaTeX string, if possible (only for simple LaTeX equations!). Whether
the transformation was possible is returned as a call by value argument!
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
Q_OBJECT
public:
/** \brief minimum linewidth allowed in a JKQTMathText (given in pt) */
static const double ABS_MIN_LINEWIDTH;
/** \brief class constructor */
JKQTMathText(QObject * parent = nullptr);
/** \brief class destructor */
~JKQTMathText();
/** \brief load the object settings from the given QSettings object with the given name prefix */
void loadSettings(const QSettings& settings, const QString& group=QString("mathtext/"));
/** \brief store the object settings to the given QSettings object with the given name prefix */
void saveSettings(QSettings& settings, const QString& group=QString("mathtext/")) const;
/** \brief parse the given enhanced string. If \c addSpaceBeforeAndAfter==true a little bit of space is added before and after the text. Returns \c true on success. */
bool parse(const QString &text, bool addSpaceBeforeAndAfter=false);
/** \brief get the size of the drawn representation. returns an invalid size if no text has been parsed. */
QSizeF getSize(QPainter& painter);
/** \brief return the descent, i.e. the distance from the baseline to the lowest part of the representation */
double getDescent(QPainter& painter);
/** \brief return the ascentt, i.e. the distance from the baseline to the highest part of the representation */
double getAscent(QPainter& painter);
/** \brief return the detailes sizes of the text */
void getSizeDetail(QPainter& painter, double& width, double& ascent, double& descent, double& strikeoutPos);
/** \brief draw a representation to the <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> object at the specified position */
void draw(QPainter& painter, double x, double y, bool drawBoxes=false);
/** \brief overloaded version of draw(QPainter& painter, double x, double y).
*
* This version draws the text inside the given rectangle according to the specified flags.
*/
2019-05-01 20:58:19 +08:00
void draw(QPainter& painter, unsigned int flags, QRectF rect, bool drawBoxes=false);
/** \brief convert LaTeX to HTML. returns \c ok=true on success and \c ok=false else. */
QString toHtml(bool* ok=nullptr, double fontPointSize=10);
2020-09-21 19:47:54 +08:00
/** \copydoc fontColor */
void setFontColor(const QColor & __value);
2020-09-21 19:47:54 +08:00
/** \copydoc fontColor */
QColor getFontColor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc fontSize */
void setFontSize(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc fontSize */
double getFontSize() const;
/** \brief add a font pair to the table with font replacements
*
* e.g. if it is known that a certain font is not good for rendering, you can add an alternative with this function.
* These are automatically applied, when setting a new font name!
*
* \param nonUseFont the font not to use
* \param useFont replacement font for nonUseFont
*
* The entry in the encodings for this font is kept empty (or even deleted), so the default encoding of the font to be replaced is used!
*/
void addReplacementFont(const QString& nonUseFont, const QString& useFont);
/** \brief add a font pair to the table with font replacements
*
* e.g. if it is known that a certain font is not good for rendering, you can add an alternative with this function.
* These are automatically applied, when setting a new font name!
*
* \param nonUseFont the font not to use
* \param useFont replacement font for nonUseFont
* \param useFontEncoding encoding of the replacement font
*/
void addReplacementFont(const QString& nonUseFont, const QString& useFont, JKQTMathTextFontEncoding useFontEncoding);
/** \brief retrieves a replacement for the given font name \a nonUseFont, including its encoding. Returns the given default values \a defaultFont and/or \a defaultFontEncoding if one of the two is not found */
QPair<QString, JKQTMathTextFontEncoding> getReplacementFont(const QString &nonUseFont, const QString &defaultFont, JKQTMathTextFontEncoding defaultFontEncoding) const;
/** \brief font subclasses, used by getFontData() */
enum class FontSubclass {
Text,
Default=Text,
Symbols,
Greek,
};
/** \brief retrieve the font and encoding to be used for \a font, which might optionally be typeset inside a math environment, specified by in_math_environment, possibly for the given font subclass \a subclass */
QPair<QString, JKQTMathTextFontEncoding> getFontData(JKQTMathTextEnvironmentFont font, bool in_math_environment=false, FontSubclass subclass=FontSubclass::Default) const;
/*! \brief calls setFontRoman(), or calls useXITS() if \a __value \c =="XITS". calls useSTIX() if \a __value \c =="STIX", ...
\see setFontRoman(), useXITS(), useSTIX() for more information */
void setFontRomanOrSpecial(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
/*! \brief calls setFontRoman(), or calls useXITS() if \a __value \c =="XITS". calls useSTIX() if \a __value \c =="STIX", ...
\see setFontRoman(), useXITS(), useSTIX() for more information */
void setFontRomanOrSpecial(const JKQTMathTextFontSpecifier & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEroman */
void setFontRoman(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEroman */
QString getFontRoman() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEsans */
void setFontSans(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEsans */
QString getFontSans() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEtypewriter */
void setFontTypewriter(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEtypewriter */
QString getFontTypewriter() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEscript */
void setFontScript(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEscript */
QString getFontScript() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEfraktur */
void setFontFraktur(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEfraktur */
QString getFontFraktur() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEcaligraphic */
void setFontCaligraphic(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEcaligraphic */
QString getFontCaligraphic() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEblackboard */
void setFontBlackboard(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief blackboard font is simulated by using roman with outlines only */
void setFontBlackboardSimulated(bool doSimulate);
2020-09-21 19:47:54 +08:00
/** \brief is blackboard font simulated by using roman with outlines only */
bool isFontBlackboardSimulated() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEblackboard */
QString getFontBlackboard() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for greek letters in the logical font \a font */
void setSymbolfontGreek(JKQTMathTextEnvironmentFont font, const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for integrals in all logical fonts */
void setSymbolfontGreek(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for greek letters in the logical font \a font */
QString getSymbolfontGreek(JKQTMathTextEnvironmentFont font) const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for symbols in the logical font \a font */
void setSymbolfontSymbol(JKQTMathTextEnvironmentFont font, const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for integrals in all logical fonts */
void setSymbolfontSymbol(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for symbols in the logical font \a font */
QString getSymbolfontSymbol(JKQTMathTextEnvironmentFont font) const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the symbol font to be used for symbols in the logical font \a font */
JKQTMathTextFontEncoding getSymbolfontEncodingSymbol(JKQTMathTextEnvironmentFont font) const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the greek letter font to be used for symbols in the logical font \a font */
JKQTMathTextFontEncoding getSymbolfontEncodingGreek(JKQTMathTextEnvironmentFont font) const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the script font */
JKQTMathTextFontEncoding getFontEncodingScript() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the Fraktur font */
JKQTMathTextFontEncoding getFontEncodingFraktur() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the typewriter font */
JKQTMathTextFontEncoding getFontEncodingTypewriter() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the sans-serif font */
JKQTMathTextFontEncoding getFontEncodingSans() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the roman font */
JKQTMathTextFontEncoding getFontEncodingRoman() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the blackboard font */
JKQTMathTextFontEncoding getFontEncodingBlackboard() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the caligraphic font */
JKQTMathTextFontEncoding getFontEncodingCaligraphic() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEmathRoman */
void setFontMathRoman(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEroman */
QString getFontMathRoman() const;
2020-09-21 19:47:54 +08:00
/** \brief set the font \a fontName and it's encoding \a encoding to be used for text in the logical font MTEmathSans */
void setFontMathSans(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
2020-09-21 19:47:54 +08:00
/** \brief retrieves the font to be used for text in the logical font MTEsans */
QString getFontMathSans() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the math-mode sans-serif font */
JKQTMathTextFontEncoding getFontEncodingMathSans() const;
2020-09-21 19:47:54 +08:00
/** \brief retrieves the encoding used for the math-mode roman font */
JKQTMathTextFontEncoding getFontEncodingMathRoman() const;
2019-01-19 16:40:52 +08:00
/** \brief configures the class to use the STIX fonts in mathmode
*
* use STIX (1.x/2.x) fonts from <a href="https://www.stixfonts.org/">https://www.stixfonts.org/</a> in math-mode
*
* \image html jkqtmathtext/stix.png
2019-01-19 16:40:52 +08:00
*/
bool useSTIX(bool mathModeOnly=true);
2019-01-19 16:40:52 +08:00
/** \brief configures the class to use the XITS fonts in mathmode
*
* use XITS fonts from <a href="https://github.com/alif-type/xits">https://github.com/alif-type/xits</a> in math-mode.
* These are included by default in this library and also activated by default.
*
* \image html jkqtmathtext/xits.png
*
* \note The XITS fonts can be compiled into JKQTPlotter, when the CMake-option \c is set to ON (default: ON).
* Then the XITS fonts are added as Qt-Ressources to the library binary.
* If this is not the case, you have to provide the XITS fonts on the target system by other means, if you want
* to use them.
2019-01-19 16:40:52 +08:00
*/
bool useXITS(bool mathModeOnly=true);
2019-01-19 16:40:52 +08:00
/** \brief configures the class to use the ASANA fonts in mathmode
*
* use the ASANA fonts from <a href="https://ctan.org/tex-archive/fonts/Asana-Math/">https://ctan.org/tex-archive/fonts/Asana-Math/</a> in math-mode
*
* \image html jkqtmathtext/asana.png
2019-01-19 16:40:52 +08:00
*/
bool useASANA(bool mathModeOnly=true);
/** \brief sets \a timesFont (with its encoding \a encodingTimes ) for serif-text and \a sansFont (with its encoding \a encodingSans ) for both mathmode and textmode fonts
2019-01-19 16:40:52 +08:00
*
* use generic Unicode fonts, e.g. "Arial" and "Times New Roman" in math-mode.
* You should use fonts that contain as many of the mathematical symbols as possible to ensure good rendering results.
*
* <code>setAnyUnicode("Times New Roman", "Times New Roman")</code>:<br>\image html jkqtmathtext/jkqtmathparser_timesnewroman.png <br><br>
* <code>setAnyUnicode("Arial", "Arial")</code>:<br>\image html jkqtmathtext/jkqtmathparser_arial.png <br><br>
* <code>setAnyUnicode("Courier New", "Courier New")</code>:<br>\image html jkqtmathtext/jkqtmathparser_couriernew.png <br><br>
* <code>setAnyUnicode("Comic Sans MS", "Comic Sans MS")</code>:<br>\image html jkqtmathtext/jkqtmathparser_comicsans.png <br><br>
*
2019-01-19 16:40:52 +08:00
*/
void useAnyUnicode(QString timesFont=QString(""), const QString& sansFont=QString(""), JKQTMathTextFontEncoding encodingTimes=JKQTMathTextFontEncoding::MTFEunicode, JKQTMathTextFontEncoding encodingSans=JKQTMathTextFontEncoding::MTFEunicode);
2020-09-21 19:47:54 +08:00
/** \copydoc brace_factor */
void setBraceFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc brace_factor */
double getBraceFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc subsuper_size_factor */
void setSubsuperSizeFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc subsuper_size_factor */
double getSubsuperSizeFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc italic_correction_factor */
void setItalicCorrectionFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc italic_correction_factor */
double getItalicCorrectionFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc operatorsubsuper_size_factor */
void setOperatorsubsuperSizeFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc operatorsubsuper_size_factor */
double getOperatorsubsuperSizeFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc mathoperator_width_factor */
void setMathoperatorWidthFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc mathoperator_width_factor */
double getMathoperatorWidthFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc super_shift_factor */
void setSuperShiftFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc super_shift_factor */
double getSuperShiftFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc sub_shift_factor */
void setSubShiftFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc sub_shift_factor */
double getSubShiftFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc brace_shrink_factor */
void setBraceShrinkFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc brace_shrink_factor */
double getBraceShrinkFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc underbrace_factor */
void setUnderbraceFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc underbrace_factor */
double getUnderbraceFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc undersetFactor */
void setUndersetFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc undersetFactor */
double getUndersetFactor() const;
/** \copydoc frac_factor */
void setFracFactor(double __value);
/** \copydoc frac_factor */
double getFracFactor() const;
/** \copydoc frac_nested_factor */
void setFracNestedFactor(double __value);
/** \copydoc frac_nested_factor */
double getFracNestedFactor() const;
/** \copydoc frac_shift_factor */
void setFracShiftFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc frac_shift_factor */
double getFracShiftFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc brace_y_shift_factor */
void setBraceYShiftFactor(double __value);
2020-09-21 19:47:54 +08:00
/** \copydoc brace_y_shift_factor */
double getBraceYShiftFactor() const;
/** \copydoc decoration_height_factor */
void setDecorationHeightFactor(double __value);
/** \copydoc decoration_height_factor */
double getDecorationHeightFactor() const;
/** \copydoc decoration_width_reduction_Xfactor */
void setDecorationWidthReductionXFactor(double __value);
/** \copydoc decoration_width_reduction_Xfactor */
double getDecorationWidthReductionXFactor() const;
2020-09-21 19:47:54 +08:00
/** \copydoc useUnparsed */
void setUseUnparsed(bool __value);
2020-09-21 19:47:54 +08:00
/** \copydoc useUnparsed */
bool isUsingUnparsed() const;
/** \copydoc error_list */
QStringList getErrorList() const;
/** \copydoc error_list */
void addToErrorList(const QString& error);
protected:
/** \brief table with font replacements to use (e.g. if it is known that a certain font is not good for rendering, you can add
* an alternative using addReplacementFont(). These are automatically applied, when setting a new font name! */
QMap<QString, QString> fontReplacements;
/** \brief acompanies fontReplacements and collects the encodings of the replacement fonts, if no entry is present, the default encoding is used, as given to the setter! */
QMap<QString, JKQTMathTextFontEncoding> fontEncodingReplacements;
/** \brief font color */
QColor fontColor;
/** \brief base font size in points */
double fontSize;
/** \brief stores information about the different fonts used by LaTeX markup */
QHash<JKQTMathTextEnvironmentFont, JKQTMathTextFontDefinition> fontDefinitions;
/** \brief if enabled, the blackboard-characters are simulated by using font outlines only */
bool blackboardSimulated;
/** \brief resizing factor for braces in math mode */
double brace_factor;
/** \brief shrinking the width of braces in math mode 0: reduce to 0 pixel width, 1: leave unchanged*/
double brace_shrink_factor;
/** \brief resizing factor for font size in sub-/superscript */
double subsuper_size_factor;
/** \brief fraction of a whitespace by which to shift a sub-/superscript left/right when the previous text is italic */
double italic_correction_factor;
/** \brief like subsuper_size_factor, but for operators (\C \\sum , \c \\int , ...) where the text is placed above/below the symbol */
double operatorsubsuper_size_factor;
/** \brief factor, used to extend the size of an operator in math mode
*
* The next image demonstrates the effect of this property, which adds extra space
* around certain math operators in math mode:
*
* \image html jkqtmathparser_mathoperator_width_factor.png
*/
double mathoperator_width_factor;
/** \brief relative shift of text in superscript to normal text:
* 0= baseline kept, 1: baseline shifted to top of normal text
*
* \image html jkqtmathtext_superscriptnode_getSizeInternal.png
*/
double super_shift_factor;
/** \brief relative shift of text in subscript to normal text:
* 0= baseline kept, 1: baseline shifted to bottom of normal text
*
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png
*/
double sub_shift_factor;
/** \brief scaling factor for font size of nominator and denominator of a fraction
*
* \image html jkqtmathtext_frac_factor.png
*/
double frac_factor;
/** \brief scaling factor for font size of nominator and denominator of a nested fraction
*
* \image html jkqtmathtext_frac_factor.png
*/
double frac_nested_factor;
/** \brief shift of denominator/nummerator away from central line of a frac
*
* \image html jkqtmathtext_fracnode_geo.png
*/
double frac_shift_factor;
/** \brief scaling factor for font of underbrace/overbrace text */
double underbrace_factor;
/** \brief scaling factor for font of underset/overset text */
double underset_factor;
/** \brief fraction of the brace ascent that the brace is shifted downwards, when scaled */
double brace_y_shift_factor;
/** \brief size of the decorations (dot, tilde, ...), as fraction of the baselineheight
*
* \image html jkqtmathtext/decoration_sizing.png
*/
double decoration_height_factor;
/** \brief a decoration has a size, which is slightly smaller than the text- width. the width is reduced by \c decoration_width_reduction_Xfactor*width("X") and the position is centered around the child-box. Also an italic correction is applied:
*
* \image html jkqtmathtext/decoration_sizing.png
*/
double decoration_width_reduction_Xfactor;
/** \brief a list that will be filled with error messages while parsing, if any error occur */
QStringList error_list;
/** \brief the result of parsing the last string supplied to the object via parse() */
JKQTMathTextNode* parsedNode;
/** \brief a tree containing the unparsed text as a single node */
JKQTMathTextNode* unparsedNode;
/** \brief if true, the unparsedNode is drawn */
bool useUnparsed;
/** \brief returns the syntax tree of JKQTMathTextNode's that was created by the last parse call */
JKQTMathTextNode* getNodeTree() const;
/** \brief the token types that may arrise in the string */
enum tokenType {
MTTnone, /*!< \brief no token */
MTTtext, /*!< \brief a piece of general text */
MTTinstruction, /*!< \brief an instruction, started by \c "\\", e.g. \c "\textbf", ... */
MTTunderscore, /*!< \brief the character \c "_" */
MTThat, /*!< \brief the character \c "^" */
MTTdollar, /*!< \brief the character \c "$" */
MTTopenbrace, /*!< \brief the character \c "{" */
MTTclosebrace, /*!< \brief the character \c "}" */
MTTopenbracket, /*!< \brief the character \c "[" */
MTTclosebracket, /*!< \brief the character \c "]" */
MTTwhitespace, /*!< \brief some whitespace */
MTTampersand /*!< \brief the character \c "&" */
};
/** \brief tokenizer for the LaTeX parser */
tokenType getToken();
/** \brief parse a LaTeX string
*
* \param get if \c true this calls getToken()
* \param quitOnClosingBrace if unequal MTBTAny, this returns if the given closing brace is found
* \param quitOnEnvironmentEnd wuit if \end{quitOnEnvironmentEnd} is found
* \param quitOnClosingBracket if \c true, quits on encountering a MTTclosebracket token
*/
JKQTMathTextNode* parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace=JKQTMathTextBraceType::MTBTAny, const QString& quitOnEnvironmentEnd=QString(""), bool quitOnClosingBracket=false);
/** \brief parse a LaTeX math environment */
JKQTMathTextNode* parseMath(bool get);
/** \brief used by the tokenizer. type of the current token */
tokenType currentToken;
/** \brief used by the tokenizer. Name of the current token, id applicable */
QString currentTokenName;
/** \brief used by the tokenizer. Points to the currently read character in parseString */
int currentTokenID;
/** \brief used by the tokenizer. The string to be parsed */
QString parseString;
/** \brief used by the parser. indicates whether we are in a math environment */
bool parsingMathEnvironment;
public:
2020-09-21 19:47:54 +08:00
/** \copydoc parsedNode */
JKQTMathTextNode *getParsedNode() const;
};
#endif // JKQTMATHTEXT_H