diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index d679e6ccbc..0cf39bc20c 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -80,6 +80,8 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: added support for \c \\char\"HEX , \c \\char\'OCTAL and \c \\charDECIMAL for inserting any uicode character code
NEW: added support for \\bigl,\\bigr,\\Bigr,... commands for fixed-size but enlarged paramtheses
NEW: added support for \\begin{verbatim}...\\end{verbatim}, \\begin{verbatim*}...\\end{verbatim*}
+ NEW: additional method JKQTMathtext::getSizeDetail() that returns all size-properties as a convenient struct, also added matching varinat JKQTMathTextNode::getSize()
+ NEW: additional method JKQTMathtext::drawIntoPixmap(), JKQTMathtext::drawIntoPicture(), JKQTMathtext::drawIntoImage() which returns a QPixmap, QPicture and QImage respectively that contains the render result of the currently parsed markup
diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp
index 0fba7928b2..9c59429b1e 100644
--- a/lib/jkqtmathtext/jkqtmathtext.cpp
+++ b/lib/jkqtmathtext/jkqtmathtext.cpp
@@ -979,6 +979,11 @@ QStringList JKQTMathText::getErrorList() const {
return this->error_list;
}
+bool JKQTMathText::hadErrors() const
+{
+ return error_list.size()>0;
+}
+
void JKQTMathText::addToErrorList(const QString &error)
{
error_list.append(error);
@@ -2141,23 +2146,25 @@ double JKQTMathText::getAscent(QPainter& painter) {
}
void JKQTMathText::getSizeDetail(QPainter& painter, double& width, double& ascent, double& descent, double& strikeoutPos) {
- width=0;
- ascent=0;
- descent=0;
- strikeoutPos=0;
+ JKQTMathTextNodeSize s=getSizeDetail(painter);
+ width=s.width;
+ ascent=s.baselineHeight;
+ descent=s.getDescent();
+ strikeoutPos=s.strikeoutPos;
+}
+
+JKQTMathTextNodeSize JKQTMathText::getSizeDetail(QPainter &painter)
+{
+ JKQTMathTextNodeSize s;
if (getNodeTree()!=nullptr) {
JKQTMathTextEnvironment ev;
ev.color=fontColor;
ev.fontSize=fontSize;
ev.fontSizeUnit=fontSizeUnits;
- double overallHeight=0;
- getNodeTree()->getSize(painter, ev, width, ascent, overallHeight, strikeoutPos);
- descent=overallHeight-ascent;
- ascent=ascent*1.1;
- descent=qMax(ascent*0.1, descent*1.1);
- strikeoutPos=strikeoutPos*1.1;
+ s=getNodeTree()->getSize(painter, ev);
}
+ return s;
}
void JKQTMathText::draw(QPainter &painter, QPointF x, bool drawBoxes)
@@ -2218,6 +2225,110 @@ void JKQTMathText::draw(QPainter& painter, unsigned int flags, QRectF rect, bool
}
}
+QPixmap JKQTMathText::drawIntoPixmap(bool drawBoxes, QColor backgroundColor, int sizeincrease, qreal devicePixelRatio)
+{
+ // 1. generate dummy QPixmap that is needed to use a QPainter
+ // we need the dummy, because we first need to determine the size of the render output
+ // for which we need a QPainter.
+ QPixmap pix(1,1);
+ pix.setDevicePixelRatio(devicePixelRatio);
+ {
+ QPainter painter;
+
+ // 2. now we determine the size and additional parameters,
+ // such as the ascent(or "baseline height")
+ painter.begin(&pix);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ const JKQTMathTextNodeSize size=getSizeDetail(painter);
+ const QSize pixsize=size.getIntSize()+QSize(2*sizeincrease,2*sizeincrease);
+ painter.end();
+
+ // 3. finally we can generate a QPixmap with the appropriate
+ // size to contain the full rendering. We fill it with the
+ // color white and finally paint the math markup/LaTeX string
+ pix=QPixmap(pixsize);
+ pix.setDevicePixelRatio(devicePixelRatio);
+ pix.fill(backgroundColor);
+ painter.begin(&pix);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ draw(painter, Qt::AlignVCenter|Qt::AlignHCenter, QRect(QPoint(0,0),pixsize), drawBoxes);
+ painter.end();
+ }
+ return pix;
+}
+
+QImage JKQTMathText::drawIntoImage(bool drawBoxes, QColor backgroundColor, int sizeincrease, qreal devicePixelRatio, unsigned int resolution_dpi)
+{
+ // 1. generate dummy QPixmap that is needed to use a QPainter
+ // we need the dummy, because we first need to determine the size of the render output
+ // for which we need a QPainter.
+ QImage img(1,1,QImage::Format_ARGB32);
+ img.setDevicePixelRatio(devicePixelRatio);
+ img.setDotsPerMeterX(resolution_dpi*(10000/254));
+ img.setDotsPerMeterY(resolution_dpi*(10000/254));
+ {
+ QPainter painter;
+
+ // 2. now we determine the size and additional parameters,
+ // such as the ascent(or "baseline height")
+ painter.begin(&img);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ const JKQTMathTextNodeSize size=getSizeDetail(painter);
+ const QSize pixsize=size.getIntSize()+QSize(2*sizeincrease,2*sizeincrease);
+ painter.end();
+
+ // 3. finally we can generate a QPixmap with the appropriate
+ // size to contain the full rendering. We fill it with the
+ // color white and finally paint the math markup/LaTeX string
+ img=QImage(pixsize,QImage::Format_ARGB32);
+ img.setDevicePixelRatio(devicePixelRatio);
+ img.fill(backgroundColor);
+ painter.begin(&img);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ draw(painter, Qt::AlignVCenter|Qt::AlignHCenter, QRect(QPoint(0,0),pixsize), drawBoxes);
+ painter.end();
+ }
+ return img;
+}
+QPicture JKQTMathText::drawIntoPicture(bool drawBoxes)
+{
+ // 1. generate dummy QPixmap that is needed to use a QPainter
+ // we need the dummy, because we first need to determine the size of the render output
+ // for which we need a QPainter.
+ QPicture pic;
+ {
+ QPainter painter;
+
+ // 2. now we determine the size and additional parameters,
+ // such as the ascent(or "baseline height")
+ painter.begin(&pic);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ const JKQTMathTextNodeSize size=getSizeDetail(painter);
+ painter.end();
+
+ // 3. finally we can generate a QPixmap with the appropriate
+ // size to contain the full rendering. We fill it with the
+ // color white and finally paint the math markup/LaTeX string
+ painter.begin(&pic);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ draw(painter, 0, size.baselineHeight, drawBoxes);
+ painter.end();
+ }
+ return pic;
+}
+
JKQTMathTextNode *JKQTMathText::getNodeTree() const {
if (useUnparsed) return unparsedNode;
diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h
index 60bb5843ce..caa32e2f26 100644
--- a/lib/jkqtmathtext/jkqtmathtext.h
+++ b/lib/jkqtmathtext/jkqtmathtext.h
@@ -54,8 +54,55 @@ class JKQTMathTextNode; // forward
\see See \ref jkqtmathtext_supportedlatex for a description of the supported LaTeX subset
and \ref jkqtmathtext_renderingmodel for a description of the rendering model.
+
\section JKQTMathTextUsage Usage
- \subsection JKQTMathTextUsageDirect Direct Usage
+
+ \subsection JKQTMathTextUsageDirect Drawing Functions
+ The class provides different variants of the drawing function draw() that paints using an
+ externlly provided QPainter. These variants
+ either paint into a QRect, or starting from a single location (x,y).
+
+ The QRect-variants can align the render result inside the rectangle, whereas the
+ location-variants draw from a position that is on the left-hand side of the output's baseline:
+
+ \image html jkqtmathtext/jkqtmathtext_node_geo.png
+
+
+
+ \subsection JKQTMathTextUsageConvenience Convenience Functions
+
+ Alternatively you can use these methods to directly generate a QPixmap or QPicture:
+ - drawIntoPixmap()
+ - drawIntoImage()
+ - drawIntoPicture()
+ .
+
+
+ \subsection JKQTMathTextSizing Determining the size of an equation
+
+ In addition there are also functions that allow to calculate the size of the equation,
+ before drawing it (just like the functions in QFontMetrics
+ or QFontMetricsF):
+ - getSizeDetail()
+ - getSize()
+ - getAscent(), getDescent()
+ .
+
+
+ \subsection JKQTMathTextUsageQLabel Usage within a QLabel class JKQTMathTextLabel
+
+ Finally, there is also a QLabel-derived class JKQTMathTextLabel which can be used for drawing a LaTeX string onto a Qt form.
+
+ \see JKQTMathTextLabel
+
+
+ \subsection JKQTMathTextErrorHandling Error Handling
+
+ 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().
+ Also parse() will return \c false if an error occured while parsing.
+
+ \subsection JKQTMathTextUsageExample Example Code
This small piece of C++ code may serve as an example of the usage and capabilities of the class:
\code
// create a JKQTMathText object.
@@ -68,46 +115,44 @@ class JKQTMathTextNode; // forward
// 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)$");
+ // draw the result into a QPixmap
+ QPixmap result=mathText.drawIntoPixmap();
+ \endcode
+
+ Alternatively you can also use this class with a QPainter:
+
+ \code
// use the draw() methods to draw the equation using a QPainter (here onto a QPixmap)
QPainter painter;
- QPixmap pix(600,400);
- painter.begin(&pix);
+
+ // first we determine the size of the render output:
+ const JKQTMathTextNodeSize size=getSizeDetail(painter);
+
+ // now we can us that size information to render:
mathText.draw(painter, Qt::AlignCenter, QRectF(0,0,pix.width(), pix.height()), false);
- painter.end();
\endcode
-
- \subsection JKQTMathTextSizing Determining the size of an equation
-
- In addition there are also functions that allow to calculate the size of the equation, before drawing it (just like the functions in QFontMetrics and QFontMetricsF):
- - getSizeDetail()
- - getSize()
- - getAscent(), getDescent()
- .
-
- \subsection JKQTMathTextErrorHandling Error Handling
-
- 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().
- Also parse() will return \c false if an error occured while parsing.
+
+
+
+
+ \section JKQTMathTextToHTML Convert to HTML
+
+ 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!
- \subsection JKQTMathTextUsageQLabel Usage within a QLabel class JKQTMathTextLabel
-
- Finally, there is also a QLabel-derived class JKQTMathTextLabel which can be used for drawing a LaTeX string onto a Qt form.
-
- \see JKQTMathTextLabel
-
-
- \section JKQTMathTextExamples Examples
+ \section JKQTMathTextExamples Example Projects
Examples for the usage of this class can be found here:
- \ref JKQTMathTextSimpleExample
+ - \ref JKQTMathTextRenderCmdLineTool
- \ref JKQTMathTextTestApp
.
- \section JKQTMathTextSuppoertedFonts Font Handling
-
+ \section JKQTMathTextInternalDetails Implementation Details
+ \subsection JKQTMathTextSuppoertedFonts Font Handling
+
Several fonts are defined as properties to the class:
- A "roman" (MTEroman / MTEmathRoman) font used as the standard font ( setFontRoman() and for use in math mode setFontMathRoman() )
- A "sans-serif" (MTEsans / MTEmathSans) font which may be activated with \c \\sf ... ( setFontSans() and for use in math mode setFontMathSans() )
@@ -142,13 +187,7 @@ class JKQTMathTextNode; // forward
- if the character is not found, it is looked for in the fallback fonts MTEFallbackSymbols
- as a last resort, some symbols can be created otherwise, so if neither of the two options above
contain the required symbol, the symbol might be synthesized otherwise, or a rectangle with the size of "X" is drawn instead
-
-
- \section JKQTMathTextToHTML Convert to HTML
-
- 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 {
@@ -176,6 +215,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
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 return the detailes sizes of the text */
+ JKQTMathTextNodeSize getSizeDetail(QPainter& painter);
/** \brief draw a representation to the object at the specified position \a x , \a y
*
* \param painter the QPainter to use for drawing
@@ -202,13 +243,41 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
* \param painter the QPainter to use for drawing
* \param rect rectangle to draw the text/expression into (see sketch below)
* \param flags alignment within \a rect (see below), use e.g. Qt::AlignHCenter | Qt::AlignVCenter to center the expression inside \a rect
+ * The flags (dark-red is the rectangle \a rect) are interpreted in the following way:
+ * \image html jkqtmathtext/jkqtmathtext_draw_flags.png
* \param drawBoxes if \c true boxes defining the size of each node are drawn, example output: \image html jkqtmathtext/jkqtmathtext_drawboxes.png
*
- * These options are interpreted for \a flags (dark-red is the rectangle \a rect):
- * \image html jkqtmathtext/jkqtmathtext_draw_flags.png
+ *
+ *
+ * \see drawIntoPixmap(), drawIntoPicture(), getSize(), getSizeDetail()
*/
void draw(QPainter& painter, unsigned int flags, QRectF rect, bool drawBoxes=false);
+ /** \brief render the last parse result into a QPixmap
+ *
+ * \param drawBoxes if \c true boxes defining the size of each node are drawn, example output: \image html jkqtmathtext/jkqtmathtext_drawboxes.png
+ * \param backgroundColor fill color for the returnes QPixmap
+ * \param sizeincrease margin around the tight size of the rendering result for the returned QPixmap
+ * \param devicePixelRatio the devicePixelRatio of the returned QPixmap
+ */
+ QPixmap drawIntoPixmap(bool drawBoxes=false, QColor backgroundColor=QColor(Qt::white), int sizeincrease=0, qreal devicePixelRatio=1.0);
+
+ /** \brief render the last parse result into a QImage
+ *
+ * \param drawBoxes if \c true boxes defining the size of each node are drawn, example output: \image html jkqtmathtext/jkqtmathtext_drawboxes.png
+ * \param backgroundColor fill color for the returnes QPixmap
+ * \param sizeincrease margin around the tight size of the rendering result for the returned QPixmap
+ * \param devicePixelRatio the devicePixelRatio of the returned QImage
+ * \param resolution_dpi resolution in dots/inch
+ */
+ QImage drawIntoImage(bool drawBoxes=false, QColor backgroundColor=QColor(Qt::white), int sizeincrease=0, qreal devicePixelRatio=1.0, unsigned int resolution_dpi=96);
+
+ /** \brief render the last parse result into a QPicture
+ *
+ * \param drawBoxes if \c true boxes defining the size of each node are drawn, example output: \image html jkqtmathtext/jkqtmathtext_drawboxes.png
+ */
+ QPicture drawIntoPicture(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);
@@ -533,6 +602,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
bool isUsingUnparsed() const;
/** \copydoc error_list */
QStringList getErrorList() const;
+ /** \brief returns \c true when errors were registered in the system \see error_list */
+ bool hadErrors() const;
/** \copydoc error_list */
void addToErrorList(const QString& error);
@@ -697,14 +768,23 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
double sqrt_width_Xfactor;
/** \brief height-increase of the sqrt-symbol, as factor of the child's height */
double sqrt_height_factor;
- /** \brief a list that will be filled with error messages while parsing, if any error occur */
+ /** \brief a list that will be filled with error messages while parsing, if any error occur
+ *
+ * This list of errors is (mostly) filled during a call to parse(). During rendering (e.g. with draw() )
+ * only very few errors will be detected, as most errors are caused by wrong markup.
+ *
+ * A call to parse() also clears this list.
+ *
+ * \see getErrorList(), hadErrors() and addToErrorList()
+ *
+ */
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 */
+ /** \brief if true, the unparsedNode is drawn \see unparsedNode */
bool useUnparsed;
/** \brief returns the syntax tree of JKQTMathTextNode's that was created by the last parse call */
@@ -717,7 +797,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
MTTinstruction, /*!< \brief an instruction, started by \c "\", e.g. \c "\\textbf", ... */
MTTinstructionNewline, /*!< \brief a newline instruction \c "\\" */
MTTinstructionVerbatim, /*!< \brief a verbatim instruction, e.g. \c \\verb!verbatimtext! was found: currentTokenName will contain the text enclode by the verbatim delimiters */
- MTTinstructionVerbatimVisibleSpace, /*!< \brief a verbatim instruction that generates visible whitespaces, e.g. \c \\begin{verbatim}...\end{verbatim} was found: currentTokenName will contain the text enclode by the verbatim delimiters */
+ MTTinstructionVerbatimVisibleSpace, /*!< \brief a verbatim instruction that generates visible whitespaces, e.g. \c \\begin{verbatim}...\\end{verbatim} was found: currentTokenName will contain the text enclode by the verbatim delimiters */
MTTinstructionBegin, /*!< \brief a \c '\\begin{...}' instruction, currentTokenName is the name of the environment */
MTTinstructionEnd, /*!< \brief a \c '\\end{...}' instruction, currentTokenName is the name of the environment */
MTTunderscore, /*!< \brief the character \c "_" */
@@ -734,7 +814,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
MTTemdash, /*!< \brief the em-dash character sequence \c "---" in text-mode */
};
- /** \biref convert a tokenType into a string, e.g. for debugging output */
+ /** \brief convert a tokenType into a string, e.g. for debugging output */
static QString tokenType2String(tokenType type);
/** \brief tokenizer for the LaTeX parser */
diff --git a/lib/jkqtmathtext/jkqtmathtexttools.h b/lib/jkqtmathtext/jkqtmathtexttools.h
index 754e9a1803..f2eac41ee6 100644
--- a/lib/jkqtmathtext/jkqtmathtexttools.h
+++ b/lib/jkqtmathtext/jkqtmathtexttools.h
@@ -315,7 +315,7 @@ struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNodeSize {
/** \brief calculate the overall size in floating-point precision */
inline QSizeF getSize() const { return QSizeF(width, overallHeight); }
/** \brief calculate the overall size in floating-point precision */
- inline QSize getIntSize() const { return QSize(qCeil(width), qCeil(overallHeight)); }
+ inline QSize getIntSize() const { return QSize(qCeil(width+1.0), qCeil(overallHeight+1.0)); }
};
/** \brief summarizes all information available on a font for a specific MTenvironmentFont