JKQTMathText: IMPROVED/REWORKED rendering of blackboard font: now several different rendering modes can be selected using JKQTMathText::setFontBlackboradMode()

This commit is contained in:
jkriege2 2022-08-10 12:12:30 +02:00
parent 94b4e69b5b
commit 5283a1a995
20 changed files with 363 additions and 114 deletions

View File

@ -34,7 +34,12 @@
- \c \\textfrak{...} \c \\mathfrak{...} : draw the contained text in fraktur font face \image html jkqtmathtext/jkqtmathtext_frak.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 \\textscript{...} \c \\mathscript{...} : draw the contained text in script font face \image html jkqtmathtext/jkqtmathtext_script.png
- \c \\textbb{...} \c \\mathbb{...} : draw the contained text in blackboard font face \image html jkqtmathtext/jkqtmathtext_bb.png - \c \\textbb{...} \c \\mathbb{...} : draw the contained text in blackboard font face \image html jkqtmathtext/jkqtmathtext_bb.png
The class JKQTMathText also supports simulating blackboard fonts, if they are not available as an actual font on the system. Then the example would look like this: \image html jkqtmathtext/jkqtmathtext_bb_sim.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")
- MTBBDMsimulate: \image html jkqtmathtext/jkqtmathtext_bb_simulate.png using \c JKQTMathText::setFontBlackboard("Arial")
- 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 \\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 \\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 \\ul{...} \c \\underline{...} \c \\underlined{...} : draw the text with underlining \image html jkqtmathtext/jkqtmathtext_ul.png

View File

@ -53,6 +53,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>IMPROVED/NEW/breaking: refactored LaTeX parser in JKQTMathText</li> <li>IMPROVED/NEW/breaking: refactored LaTeX parser in JKQTMathText</li>
<li>REMOVED/breaking: \c \\v[a-zA-Z] and shorthand for \c \\vec{a-zA-Z} was removed, implementation of \c \\bbR,\c \\bbC,... changed</li> <li>REMOVED/breaking: \c \\v[a-zA-Z] and shorthand for \c \\vec{a-zA-Z} was removed, implementation of \c \\bbR,\c \\bbC,... changed</li>
<li>IMPROVED/REWORKED rendering of text in text- and math-mode. Now it is more consistent with the output of LaTeX itself</li> <li>IMPROVED/REWORKED rendering of text in text- and math-mode. Now it is more consistent with the output of LaTeX itself</li>
<li>IMPROVED/REWORKED rendering of blackboard font: now several different rendering modes can be selected using JKQTMathText::setFontBlackboradMode()</li>
<li>BREAKING/REWORKED: The \\verb!...!-command now works the same as in LaTeX</li> <li>BREAKING/REWORKED: The \\verb!...!-command now works the same as in LaTeX</li>
<li>NEW: now supports new decoration instructions: \c \\cancel, \c \\xcancel, \c \\bcancel, \c \\sout, \c \\ocirc, \c \\widetilde, \c \\widehat, \c \\breve</li> <li>NEW: now supports new decoration instructions: \c \\cancel, \c \\xcancel, \c \\bcancel, \c \\sout, \c \\ocirc, \c \\widetilde, \c \\widehat, \c \\breve</li>
<li>NEW: reworked drawing of decorations: improved appearance and positioning!</li> <li>NEW: reworked drawing of decorations: improved appearance and positioning!</li>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -21,11 +21,24 @@ jkqtmathtext_script.png
{\backslash}textscript: \textscript{Script text}\ \ \ \ \ {\backslash}mathscript: $\mathscript{L}=T-V$ {\backslash}textscript: \textscript{Script text}\ \ \ \ \ {\backslash}mathscript: $\mathscript{L}=T-V$
--- ---
jkqtmathtext_bb.png jkqtmathtext_bb.png
{\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text} --fontblackboard=Arial --fontblackboardmode=default
{\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}, \mathbb{1, \pi}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text! 123 \pi \"A\"o}
--- ---
jkqtmathtext_bb_sim.png jkqtmathtext_bb_font_directly.png
--fontblackboardsimulated=XITS Math --fontblackboardmode=font_directly
{\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text} {\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}, \mathbb{1, \pi}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text! 123 \pi \"A\"o}
---
jkqtmathtext_bb_simulate.png
--fontblackboard=Arial --fontblackboardmode=simulate
{\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}, \mathbb{1, \pi}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text! 123 \pi \"A\"o}
---
jkqtmathtext_bb_unicode_or_font_directly.png
--fontblackboardmode=unicode_or_font_directly
{\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}, \mathbb{1, \pi}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text! 123 \pi \"A\"o}
---
jkqtmathtext_bb_unicode_or_simulate.png
--fontblackboard=Arial --fontblackboardmode=unicode_or_simulate
{\backslash}mathbb: $x\in\mathbb{R}, z\in\mathbb{C}, \mathbb{1, \pi}$\ \ \ \ \ {\backslash}textbb: \textbb{Blackboard text! 123 \pi \"A\"o}
--- ---
jkqtmathtext_ol.png jkqtmathtext_ol.png
{\backslash}ol: \ol{overlined text} {\backslash}ol: \ol{overlined text}

View File

@ -283,7 +283,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbEncodingBlackboard->setCurrentIndex(static_cast<int>(mt.getFontEncodingBlackboard())); ui->cmbEncodingBlackboard->setCurrentIndex(static_cast<int>(mt.getFontEncodingBlackboard()));
ui->cmbUnicodeSymbol->setCurrentFont(QFont(mt.getFallbackFontSymbols())); ui->cmbUnicodeSymbol->setCurrentFont(QFont(mt.getFallbackFontSymbols()));
ui->cmbEncodingSymbol->setCurrentIndex(static_cast<int>(mt.getFontEncodingFallbackFontSymbols())); ui->cmbEncodingSymbol->setCurrentIndex(static_cast<int>(mt.getFontEncodingFallbackFontSymbols()));
ui->chkSimulateBlackboard->setChecked(mt.isFontBlackboardSimulated()); ui->cmdBlackboradMode->setCurrentText(JKQTMathTextBlackboradDrawingMode2String(mt.getFontBlackboradMode()));
@ -297,7 +297,7 @@ TestForm::TestForm(QWidget *parent) :
connect(ui->chkBigBox, SIGNAL(toggled(bool)), this, SLOT(updateMath())); connect(ui->chkBigBox, SIGNAL(toggled(bool)), this, SLOT(updateMath()));
connect(ui->chkAntiAlias, SIGNAL(toggled(bool)), this, SLOT(updateMath())); connect(ui->chkAntiAlias, SIGNAL(toggled(bool)), this, SLOT(updateMath()));
connect(ui->chkAntiAliasText, SIGNAL(toggled(bool)), this, SLOT(updateMath())); connect(ui->chkAntiAliasText, SIGNAL(toggled(bool)), this, SLOT(updateMath()));
connect(ui->chkSimulateBlackboard, SIGNAL(toggled(bool)), this, SLOT(updateMath())); connect(ui->cmdBlackboradMode, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath()));
connect(ui->cmbLastAlign, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath())); connect(ui->cmbLastAlign, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath()));
connect(ui->cmbFont, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath())); connect(ui->cmbFont, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath()));
connect(ui->cmbScript, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath())); connect(ui->cmbScript, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMath()));
@ -446,7 +446,7 @@ QString TestForm::getFonts(const JKQTMathText& mt) const
str<<"Script: "<<mt.getFontScript().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingScript()).toStdString()<<"\n"; str<<"Script: "<<mt.getFontScript().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingScript()).toStdString()<<"\n";
str<<"Typewriter: "<<mt.getFontTypewriter().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingTypewriter()).toStdString()<<"\n"; str<<"Typewriter: "<<mt.getFontTypewriter().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingTypewriter()).toStdString()<<"\n";
str<<"Caligraphic: "<<mt.getFontCaligraphic().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingCaligraphic()).toStdString()<<"\n"; str<<"Caligraphic: "<<mt.getFontCaligraphic().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingCaligraphic()).toStdString()<<"\n";
str<<"Blackboard: "<<mt.getFontBlackboard().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingBlackboard()).toStdString()<<", isSimulated="<<mt.isFontBlackboardSimulated(); str<<"Blackboard: "<<mt.getFontBlackboard().toStdString()<<", "<<JKQTMathTextFontEncoding2String(mt.getFontEncodingBlackboard()).toStdString()<<", mode="<<JKQTMathTextBlackboradDrawingMode2String(mt.getFontBlackboradMode()).toStdString()<<"\n";
return str.str().c_str(); return str.str().c_str();
} }
@ -644,7 +644,7 @@ void TestForm::updateMath()
mt.useXITS(false); mt.useXITS(false);
} }
mt.setFontBlackboardSimulated(ui->chkSimulateBlackboard->isChecked()); mt.setFontBlackboradMode(String2JKQTMathTextBlackboradDrawingMode(ui->cmdBlackboradMode->currentText()));
if (ui->cmbFont->currentIndex()==1) qDebug()<<"useXITS: "<<mt.useXITS(); if (ui->cmbFont->currentIndex()==1) qDebug()<<"useXITS: "<<mt.useXITS();
else if (ui->cmbFont->currentIndex()==2) qDebug()<<"useSTIX: "<<mt.useSTIX(); else if (ui->cmbFont->currentIndex()==2) qDebug()<<"useSTIX: "<<mt.useSTIX();

View File

@ -465,13 +465,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2">
<widget class="QCheckBox" name="chkSimulateBlackboard">
<property name="text">
<string>simulate blackboard</string>
</property>
</widget>
</item>
<item row="0" column="7"> <item row="0" column="7">
<widget class="QLabel" name="label_19"> <widget class="QLabel" name="label_19">
<property name="text"> <property name="text">
@ -528,6 +521,38 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2">
<widget class="QComboBox" name="cmdBlackboradMode">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>unicode_or_font_directly</string>
</property>
</item>
<item>
<property name="text">
<string>unicode_or_simulate</string>
</property>
</item>
<item>
<property name="text">
<string>font_directly</string>
</property>
</item>
<item>
<property name="text">
<string>simulate</string>
</property>
</item>
<item>
<property name="text">
<string>default</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="11" column="1"> <item row="11" column="1">

View File

@ -55,6 +55,11 @@ JKQTCOMMON_LIB_EXPORT Qt::BrushStyle jkqtp_String2QBrushStyle(const QString& sty
*/ */
JKQTCOMMON_LIB_EXPORT std::string jkqtp_UnicodeToUTF8(uint32_t codepoint); JKQTCOMMON_LIB_EXPORT std::string jkqtp_UnicodeToUTF8(uint32_t codepoint);
/** \copydoc jkqtp_UnicodeToUTF8() */
inline QString jkqtp_UnicodeToUTF8Q(uint32_t codepoint) {
return QString::fromStdString(jkqtp_UnicodeToUTF8(codepoint));
}
/** \brief convert a double to a string, using the loacle "C" /** \brief convert a double to a string, using the loacle "C"
* \ingroup jkqtptools_string * \ingroup jkqtptools_string
*/ */

View File

@ -99,7 +99,7 @@ JKQTMathText::JKQTMathText(QObject* parent):
sqrt_height_factor=1.2; sqrt_height_factor=1.2;
sqrt_smallfont_factor=0.57; sqrt_smallfont_factor=0.57;
blackboardSimulated=true; blackboradFontMode=MTBBDMdefault;
static QString serifFont="serif"; static QString serifFont="serif";
@ -166,8 +166,10 @@ JKQTMathText::JKQTMathText(QObject* parent):
setFontCaligraphic(decorativeFont, estimateJKQTMathTextFontEncoding(decorativeFont)); setFontCaligraphic(decorativeFont, estimateJKQTMathTextFontEncoding(decorativeFont));
if (blackboardFont!="blackboard") { if (blackboardFont!="blackboard") {
setFontBlackboard(blackboardFont, estimateJKQTMathTextFontEncoding(blackboardFont)); setFontBlackboard(blackboardFont, estimateJKQTMathTextFontEncoding(blackboardFont));
setFontBlackboradMode(MTBBDMunicodeCharactersOrFontDirectly);
} else { } else {
setFontBlackboardSimulated(blackboardFont=="blackboard"); setFontBlackboard(sansFont, estimateJKQTMathTextFontEncoding(sansFont));
setFontBlackboradMode(MTBBDMunicodeCharactersOrSimulate);
} }
setFontScript(scriptFont, estimateJKQTMathTextFontEncoding(scriptFont)); setFontScript(scriptFont, estimateJKQTMathTextFontEncoding(scriptFont));
setFontFraktur(fracturFont, estimateJKQTMathTextFontEncoding(fracturFont)); setFontFraktur(fracturFont, estimateJKQTMathTextFontEncoding(fracturFont));
@ -638,20 +640,19 @@ JKQTMathTextFontEncoding JKQTMathText::getFontEncodingMathRoman() const
void JKQTMathText::setFontBlackboard(const QString &__value, JKQTMathTextFontEncoding encoding) void JKQTMathText::setFontBlackboard(const QString &__value, JKQTMathTextFontEncoding encoding)
{ {
blackboardSimulated=false;
auto f=getReplacementFont(__value, __value, encoding); auto f=getReplacementFont(__value, __value, encoding);
fontDefinitions[MTEblackboard].fontName = f.first; fontDefinitions[MTEblackboard].fontName = f.first;
fontDefinitions[MTEblackboard].fontEncoding = f.second; fontDefinitions[MTEblackboard].fontEncoding = f.second;
} }
void JKQTMathText::setFontBlackboardSimulated(bool doSimulate) JKQTMathTextBlackboradDrawingMode JKQTMathText::getFontBlackboradMode() const
{ {
blackboardSimulated=doSimulate; return blackboradFontMode;
} }
bool JKQTMathText::isFontBlackboardSimulated() const void JKQTMathText::setFontBlackboradMode(JKQTMathTextBlackboradDrawingMode mode)
{ {
return blackboardSimulated; blackboradFontMode=mode;
} }
QString JKQTMathText::getFontBlackboard() const QString JKQTMathText::getFontBlackboard() const

View File

@ -373,11 +373,12 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
* *
*/ */
void setFontBlackboard(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); void setFontBlackboard(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
/** \copydoc blackboardSimulated */ /** \copydoc blackboradFontMode */
void setFontBlackboardSimulated(bool doSimulate); JKQTMathTextBlackboradDrawingMode getFontBlackboradMode() const;
/** \copydoc blackboardSimulated \see setFontBlackboardSimulated() */ /** \copydoc blackboradFontMode */
bool isFontBlackboardSimulated() const; void setFontBlackboradMode(JKQTMathTextBlackboradDrawingMode mode);
/** \brief retrieves the font to be used for text in the logical font MTEblackboard \see setFontBlackboardSimulated() */
/** \brief retrieves the font to be used for text in the logical font MTEblackboard \see blackboradFontMode */
QString getFontBlackboard() const; QString getFontBlackboard() const;
/** \brief set the font \a fontName and it's encoding \a encoding to be used for symbols in the logical font \a font */ /** \brief set the font \a fontName and it's encoding \a encoding to be used for symbols in the logical font \a font */
void setFallbackFontSymbols(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard); void setFallbackFontSymbols(const QString & fontName, JKQTMathTextFontEncoding encoding=JKQTMathTextFontEncoding::MTFEStandard);
@ -635,17 +636,26 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
/** \brief stores information about the different fonts used by LaTeX markup */ /** \brief stores information about the different fonts used by LaTeX markup */
QHash<JKQTMathTextEnvironmentFont, JKQTMathTextFontDefinition> fontDefinitions; QHash<JKQTMathTextEnvironmentFont, JKQTMathTextFontDefinition> fontDefinitions;
/** \brief if enabled, the blackboard-characters are simulated by using font outlines only
/** \brief specifies how to draw blackboard font characters (i.e. \c \\mathbb{N} )
* *
* A possible choice for a blackboard font (Castellar) looks like this: * Blackboard fonts are not widely available on target systems (viable fonts are e.g.
* \image html jkqtmathtext/jkqtmathtext_bb.png * <code>"Double Stroke", "CloisterOpenFace BT", "GoudyHandtooled BT", "Castellar", "MathJax_AMS", "Castellar Standard", "MathJax_AMS Standard", "Colonna MT"</code>).
* If such a font is not available, you can set this property blackboardSimulated * But the most important blackboard characters are usually available in the higher unicode
* to \c true and chose a font, like e.g. Arial to output blackboard-letters as: * codepoints of Fonts specialized for math (e.g. XIST, STIX, ASANA).
* \image html jkqtmathtext/jkqtmathtext_bb_sim.png
* *
* \see setFontBlackboard() setFontBlackboardSimulated() * 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")
* - MTBBDMsimulate: \image html jkqtmathtext/jkqtmathtext_bb_simulate.png using \c JKQTMathText::setFontBlackboard("Arial")
* - 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")
* .
*
* \see setFontBlackboard() setBlackboardFontMode()
*/ */
bool blackboardSimulated; JKQTMathTextBlackboradDrawingMode blackboradFontMode;
/** \brief resizing factor for braces in math mode */ /** \brief resizing factor for braces in math mode */

View File

@ -548,6 +548,19 @@ QFont JKQTMathTextEnvironment::getFont(JKQTMathText* parent) const {
return f; return f;
} }
JKQTMathTextEnvironment JKQTMathTextEnvironment::exchangedFontForRoman() const
{
if (insideMath) return exchangedFontFor(MTEmathRoman);
else return exchangedFontFor(MTEroman);
}
JKQTMathTextEnvironment JKQTMathTextEnvironment::exchangedFontFor(JKQTMathTextEnvironmentFont font) const
{
JKQTMathTextEnvironment newEnv=*this;
newEnv.font=font;
return newEnv;
}
QString JKQTMathTextEnvironment::toHtmlStart(JKQTMathTextEnvironment defaultEv, JKQTMathText* parentMathText) const { QString JKQTMathTextEnvironment::toHtmlStart(JKQTMathTextEnvironment defaultEv, JKQTMathText* parentMathText) const {
QString s; QString s;
if (fontSizeUnit==POINTS) s=s+"font-size: "+QLocale::c().toString(fontSize)+"pt; "; if (fontSizeUnit==POINTS) s=s+"font-size: "+QLocale::c().toString(fontSize)+"pt; ";
@ -845,3 +858,37 @@ JKQTMathTextVerticalOrientation String2JKQTMathTextVerticalOrientation(QString t
if (tokenName=="c" || tokenName=="center" || tokenName=="centered") return MTVOCentered; if (tokenName=="c" || tokenName=="center" || tokenName=="centered") return MTVOCentered;
return MTVOCentered; return MTVOCentered;
} }
QString JKQTMathTextBlackboradDrawingMode2String(JKQTMathTextBlackboradDrawingMode mode)
{
switch(mode) {
case MTBBDMfontDirectly: return "font_directly";
case MTBBDMsimulate: return "simulate";
case MTBBDMunicodeCharactersOrFontDirectly: return "unicode_or_font_directly";
case MTBBDMunicodeCharactersOrSimulate: return "unicode_or_simulate";
}
return "font_directly";
}
JKQTMathTextBlackboradDrawingMode String2JKQTMathTextBlackboradDrawingMode(QString mode)
{
mode=mode.toLower().simplified().trimmed();
if (mode=="font_directly" || mode=="font" || mode=="directly") return MTBBDMfontDirectly;
if (mode=="simulate") return MTBBDMsimulate;
if (mode=="unicode_or_font_directly" || mode=="unicode_or_font" || mode=="unicode_or_directly") return MTBBDMunicodeCharactersOrFontDirectly;
if (mode=="unicode_or_simulate") return MTBBDMunicodeCharactersOrSimulate;
if (mode=="default") return MTBBDMdefault;
return MTBBDMdefault;
}
void JKQTMathTextDrawStringSimBlackboard(QPainter &painter, const QFont &f, const QColor& color, double x, double y, const QString &txt)
{
const QFontMetricsF fm(f, painter.device());
const QPen p(color, fm.lineWidth()/4.0, Qt::SolidLine);
painter.setPen(p);
QPainterPath path;
path.addText(QPointF(x, y), f, txt);
path.addText(QPointF(x+fm.lineWidth()/2.0, y), f, txt);
painter.drawPath(path);
}

View File

@ -139,6 +139,31 @@ enum JKQTMathTextFontEncoding {
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFontEncoding estimateJKQTMathTextFontEncoding(QFont font); JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFontEncoding estimateJKQTMathTextFontEncoding(QFont font);
/** \brief used to specify how blackboard-fonts are drawn
* \ingroup jkqtmathtext_tools
*
* \see JKQTMathTextBlackboradDrawingMode2String(), String2JKQTMathTextBlackboradDrawingMode()
*/
enum JKQTMathTextBlackboradDrawingMode {
MTBBDMfontDirectly=0, /*!< \brief draw using the font specified by JKQTMathText::setFontBlackboard() \image html jkqtmathtext/jkqtmathtext_bb_font_directly.png */
MTBBDMsimulate, /*!< \brief simulate a blackboard font (i.e. draw the characters' outline only), based on the font specified by JKQTMathText::setFontBlackboard() (e.g. Arial or another sans-serif font is a good choice) \image html jkqtmathtext/jkqtmathtext_bb_simulate.png */
MTBBDMunicodeCharactersOrFontDirectly, /*!< \brief use the currently set font and look for special unicode-characters in it, uses the fallbackSymbolFont as fallback, use MTBBDMfontDirectly for characters that are not available \image html jkqtmathtext/jkqtmathtext_bb_unicode_or_font_directly.png */
MTBBDMunicodeCharactersOrSimulate, /*!< \brief use the currently set font and look for special unicode-characters in it, uses the fallbackSymbolFont as fallback, use MTBBDMsimulate for characters that are not available \image html jkqtmathtext/jkqtmathtext_bb_unicode_or_simulate.png */
MTBBDMdefault=MTBBDMunicodeCharactersOrFontDirectly /*!< \brief default drawing mode, same as MTBBDMunicodeCharactersOrFontDirectly */
};
/** \brief this converts a JKQTMathTextBlackboradDrawingMode into a string
* \ingroup jkqtmathtext_tools
* \see String2JKQTMathTextBlackboradDrawingMode(), JKQTMathTextBlackboradDrawingMode
*/
JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextBlackboradDrawingMode2String(JKQTMathTextBlackboradDrawingMode mode);
/** \brief this converts a QString into a JKQTMathTextBlackboradDrawingMode
* \ingroup jkqtmathtext_tools
* \see JKQTMathTextBlackboradDrawingMode2String(), JKQTMathTextBlackboradDrawingMode
*/
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBlackboradDrawingMode String2JKQTMathTextBlackboradDrawingMode(QString mode);
/** \brief convert MTfontEncoding to a string /** \brief convert MTfontEncoding to a string
* \ingroup jkqtmathtext_tools * \ingroup jkqtmathtext_tools
@ -277,6 +302,10 @@ struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextEnvironment {
/** \brief build a <a href="https://doc.qt.io/qt-5/qfont.html">QFont</a> object from the settings in this object */ /** \brief build a <a href="https://doc.qt.io/qt-5/qfont.html">QFont</a> object from the settings in this object */
QFont getFont(JKQTMathText* parent) const; QFont getFont(JKQTMathText* parent) const;
/** \brief return a copy of this object with the font exchanged for \a font */
JKQTMathTextEnvironment exchangedFontFor(JKQTMathTextEnvironmentFont font) const;
/** \brief return a copy of this object with the font exchanged for the matching roman font */
JKQTMathTextEnvironment exchangedFontForRoman() const;
/** \brief return the encoding of the given Font */ /** \brief return the encoding of the given Font */
JKQTMathTextFontEncoding getFontEncoding(JKQTMathText *parent) const; JKQTMathTextFontEncoding getFontEncoding(JKQTMathText *parent) const;
/** \brief generate a HTML prefix that formats the text after it according to the settings in this object /** \brief generate a HTML prefix that formats the text after it according to the settings in this object
@ -364,6 +393,14 @@ JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeArrow(double x, double y, d
*/ */
JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeDArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true); JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeDArrow(double x, double y, double width, double arrowW, bool left=false, bool right=true);
/** \brief draw a given \a txt in the font \a f using additional informaion (but not currentEv::getFont() ) from \a currentEv at (\a x , \a y ) using the given \a painter
*
* This function implements drawing of synthesized fonts, e.g. MTEblackboard when JKQTMathText::isFontBlackboardSimulated() is \c true .
*
* example output:
* \image html jkqtmathtext/jkqtmathtext_bb_unicode_or_simulate.png
*/
JKQTMATHTEXT_LIB_EXPORT void JKQTMathTextDrawStringSimBlackboard(QPainter& painter, const QFont& f, const QColor &color, double x, double y, const QString& txt);
struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRData { struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRData {
explicit JKQTMathTextTBRData(const QFont& f, const QString& text, QPaintDevice *pd); explicit JKQTMathTextTBRData(const QFont& f, const QString& text, QPaintDevice *pd);

View File

@ -54,26 +54,8 @@ QString JKQTMathTextTextBaseNode::getText() const
return text; return text;
} }
void JKQTMathTextTextBaseNode::drawString(QPainter &painter, const JKQTMathTextEnvironment &currentEv, double x, double y, const QString &txt) const {
const QFont f=currentEv.getFont(parentMathText);
drawString(painter, currentEv, f, x, y, txt);
}
void JKQTMathTextTextBaseNode::drawString(QPainter &painter, const JKQTMathTextEnvironment &currentEv, const QFont &f, double x, double y, const QString &txt) const
{
const QFontMetricsF fm(f, painter.device());
const QPen p(currentEv.color, fm.lineWidth()/2.0, Qt::SolidLine);
painter.setPen(p);
if (currentEv.font==MTEblackboard && parentMathText->isFontBlackboardSimulated()) {
QPainterPath path;
path.addText(QPointF(x, y), f, txt);
path.addText(QPointF(x+fm.lineWidth()/2.0, y), f, txt);
painter.drawPath(path);
} else {
painter.setFont(f);
painter.drawText(QPointF(x, y), txt);
}
}
QString JKQTMathTextTextBaseNode::textTransform(const QString &text, const JKQTMathTextEnvironment &/*currentEv*/) const QString JKQTMathTextTextBaseNode::textTransform(const QString &text, const JKQTMathTextEnvironment &/*currentEv*/) const
{ {
@ -91,10 +73,34 @@ bool JKQTMathTextTextBaseNode::toHtml(QString &html, JKQTMathTextEnvironment cur
QHash<QChar, uint32_t> JKQTMathTextTextNode::blackboardUnicodeTable=QHash<QChar, uint32_t>();
void JKQTMathTextTextNode::fillStaticTables() {
if (blackboardUnicodeTable.size()>0) return;
blackboardUnicodeTable['C']=0x2102;
blackboardUnicodeTable['H']=0x210D;
blackboardUnicodeTable['N']=0x2115;
blackboardUnicodeTable['P']=0x2119;
blackboardUnicodeTable['Q']=0x211A;
blackboardUnicodeTable['R']=0x211D;
blackboardUnicodeTable['Z']=0x2124;
for (const QChar ch: QString("ABDEFGIJKLMOSTUVWXYZ")) {
blackboardUnicodeTable[ch]=0x1D538+(ch.unicode()-QChar('A').unicode());
}
for (const QChar ch: QString("abcdefghijklmnopqrstuvwxyz")) {
blackboardUnicodeTable[ch]=0x1D552+(ch.unicode()-QChar('a').unicode());
}
for (const QChar ch: QString("0123456789")) {
blackboardUnicodeTable[ch]=0x1D7D8+(ch.unicode()-QChar('0').unicode());
}
}
JKQTMathTextTextNode::JKQTMathTextTextNode(JKQTMathText* _parent, const QString& textIn, bool addWhitespace, bool stripInnerWhitepace): JKQTMathTextTextNode::JKQTMathTextTextNode(JKQTMathText* _parent, const QString& textIn, bool addWhitespace, bool stripInnerWhitepace):
JKQTMathTextTextBaseNode(_parent, "") JKQTMathTextTextBaseNode(_parent, "")
{ {
fillStaticTables();
QString textTransformed=textIn; QString textTransformed=textIn;
if (stripInnerWhitepace) { if (stripInnerWhitepace) {
@ -117,28 +123,26 @@ JKQTMathTextTextNode::~JKQTMathTextTextNode() = default;
void JKQTMathTextTextNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { void JKQTMathTextTextNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
QStringList textpart; QStringList textpart;
QList<bool> fontForcedUpright; QList<FontMode> fontMode;
QList<double> textpartXPos; QList<double> textpartXPos;
getSizeInternalAndData(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos,textpart, fontForcedUpright, textpartXPos); getSizeInternalAndData(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos,textpart, fontMode, textpartXPos);
} }
void JKQTMathTextTextNode::getSizeInternalAndData(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, QStringList &textpart, QList<bool> &fontForcedUpright, QList<double> &textpartXPos) void JKQTMathTextTextNode::getSizeInternalAndData(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, QStringList &textpart, QList<FontMode> &fontMode, QList<double> &textpartXPos)
{ {
textpart.clear(); textpart.clear();
fontForcedUpright.clear(); fontMode.clear();
const QString txt=textTransform(text, currentEv); const QString txt=textTransform(text, currentEv);
if (currentEv.insideMath && currentEv.insideMathForceDigitsUpright) { splitTextForLayout(painter, currentEv, txt, textpart, fontMode);
splitTextForMathMode(txt, textpart, fontForcedUpright);
} else {
textpart.append(text);
fontForcedUpright.append(false);
}
const QFont f=currentEv.getFont(parentMathText); const QFont f=currentEv.getFont(parentMathText);
const QFont fnonItalic=JKQTMathTextGetNonItalic(f); const QFont fUpright=JKQTMathTextGetNonItalic(f);
const QFontMetricsF fmNonItalic(fnonItalic, painter.device()); const QFont fFallbackSym=currentEv.exchangedFontFor(MTEFallbackSymbols).getFont(parentMathText);
const QFont fRoman=currentEv.exchangedFontForRoman().getFont(parentMathText);
const QFontMetricsF fmUpright(fUpright, painter.device());
const QFontMetricsF fm(f, painter.device()); const QFontMetricsF fm(f, painter.device());
const QFontMetricsF fmFallbackSym(fFallbackSym, painter.device());
const QFontMetricsF fmRoman(fRoman, painter.device());
#if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0)) #if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0))
const double sp=fm.horizontalAdvance(' '); const double sp=fm.horizontalAdvance(' ');
#else #else
@ -148,8 +152,26 @@ void JKQTMathTextTextNode::getSizeInternalAndData(QPainter &painter, JKQTMathTex
double ascent=0; double ascent=0;
double descent=0; double descent=0;
for (int i=0; i<textpart.size(); i++) { for (int i=0; i<textpart.size(); i++) {
const QRectF br=(fontForcedUpright[i]) ? fmNonItalic.boundingRect(textpart[i]) : fm.boundingRect(textpart[i]); QRectF br, tbr;
const QRectF tbr=(fontForcedUpright[i]) ? JKQTMathTextGetTightBoundingRect(fnonItalic, textpart[i], painter.device()) : JKQTMathTextGetTightBoundingRect(f, textpart[i], painter.device()); switch(fontMode[i]) {
case FMasDefined:
case FMasDefinedOutline:
br=fm.boundingRect(textpart[i]);
tbr=JKQTMathTextGetTightBoundingRect(f, textpart[i], painter.device());
break;
case FMasDefinedForceUpright:
br=fmUpright.boundingRect(textpart[i]);
tbr=JKQTMathTextGetTightBoundingRect(fUpright, textpart[i], painter.device());
break;
case FMroman:
br=fmRoman.boundingRect(textpart[i]);
tbr=JKQTMathTextGetTightBoundingRect(fRoman, textpart[i], painter.device());
break;
case FMfallbackSymbol:
br=fmFallbackSym.boundingRect(textpart[i]);
tbr=JKQTMathTextGetTightBoundingRect(fFallbackSym, textpart[i], painter.device());
break;
}
textpartXPos.append(width); textpartXPos.append(width);
width+=br.width(); width+=br.width();
if (textpart[i].size()>0 && textpart[i].at(textpart[i].size()-1).isSpace()) { if (textpart[i].size()>0 && textpart[i].at(textpart[i].size()-1).isSpace()) {
@ -166,7 +188,7 @@ void JKQTMathTextTextNode::getSizeInternalAndData(QPainter &painter, JKQTMathTex
strikeoutPos=fm.strikeOutPos(); strikeoutPos=fm.strikeOutPos();
} }
void JKQTMathTextTextNode::splitTextForMathMode(const QString &txt, QStringList &textpart, QList<bool> &fontForcedUpright) void JKQTMathTextTextNode::splitTextForLayout(QPainter &painter, JKQTMathTextEnvironment currentEv, const QString &txt, QStringList &textpart, QList<FontMode> &fontMode) const
{ {
auto isForcedUprightChar=[](const QChar& c) { auto isForcedUprightChar=[](const QChar& c) {
return c.isDigit() return c.isDigit()
@ -174,37 +196,82 @@ void JKQTMathTextTextNode::splitTextForMathMode(const QString &txt, QStringList
|| c==QChar(0x2329) || c==QChar(0x232A) || c==QChar(0x2308) || c==QChar(0x2309) || c==QChar(0x230A) || c==QChar(0x230B); || c==QChar(0x2329) || c==QChar(0x232A) || c==QChar(0x2308) || c==QChar(0x2309) || c==QChar(0x230A) || c==QChar(0x230B);
}; };
//const QFont f=currentEv.getFont(parentMathText);
//const QFont fUpright=JKQTMathTextGetNonItalic(f);
const QFont fFallbackSym=currentEv.exchangedFontFor(MTEFallbackSymbols).getFont(parentMathText);
const QFont fRoman=currentEv.exchangedFontForRoman().getFont(parentMathText);
//const QFontMetricsF fm(f, painter.device());
//const QFontMetricsF fmUpright(fUpright, painter.device());
const QFontMetricsF fmFallbackSym(fFallbackSym, painter.device());
const QFontMetricsF fmRoman(fRoman, painter.device());
const JKQTMathTextBlackboradDrawingMode bbMode=parentMathText->getFontBlackboradMode();
textpart.clear(); textpart.clear();
fontForcedUpright.clear(); fontMode.clear();
QString currentSection=""; QString currentSection="";
bool currentSectionForcedUpright=false; FontMode currentSectionFontMode=FMasDefined;
int i=0; int i=0;
while (i<txt.size()) { while (i<txt.size()) {
const QChar c=txt[i]; const QChar c=txt[i];
QString cs=c;
FontMode CFontMode=FMasDefined;
const bool CisForcedUprightChar=isForcedUprightChar(c); const bool CisForcedUprightChar=isForcedUprightChar(c);
const bool CisForcedUprightCharExt=CisForcedUprightChar||(c=='.')||(c==','); const bool CisForcedUprightCharExt=CisForcedUprightChar||(c=='.')||(c==',');
if (currentEv.insideMath && currentEv.insideMathForceDigitsUpright && (currentEv.font==MTEroman || currentEv.font==MTEmathRoman)) {
if (currentSection.size()==0) {
if (CisForcedUprightChar) {
CFontMode=FMasDefinedForceUpright;
}
} else {
if (CisForcedUprightCharExt) {
CFontMode=FMasDefinedForceUpright;
}
}
} else if (currentEv.font==MTEblackboard) {
if (bbMode==MTBBDMfontDirectly) {
CFontMode=FMasDefined;
} else if (bbMode==MTBBDMsimulate) {
CFontMode=FMasDefinedOutline;
} else if (bbMode==MTBBDMunicodeCharactersOrSimulate || bbMode==MTBBDMunicodeCharactersOrFontDirectly) {
if (blackboardUnicodeTable.contains(c) && fmRoman.inFontUcs4(blackboardUnicodeTable[c])) {
cs=jkqtp_UnicodeToUTF8Q(blackboardUnicodeTable[c]);
CFontMode=FMroman;
} else if (blackboardUnicodeTable.contains(c) && fmFallbackSym.inFontUcs4(blackboardUnicodeTable[c])) {
cs=jkqtp_UnicodeToUTF8Q(blackboardUnicodeTable[c]);
CFontMode=FMfallbackSymbol;
} else {
if (bbMode==MTBBDMunicodeCharactersOrSimulate) {
CFontMode=FMasDefinedOutline;
} else if (bbMode==MTBBDMunicodeCharactersOrFontDirectly) {
CFontMode=FMasDefined;
}
}
}
}
if (currentSection.size()==0) { if (currentSection.size()==0) {
// start new section // start new section
currentSectionForcedUpright=CisForcedUprightChar; currentSectionFontMode=CFontMode;
currentSection+=c; currentSection+=cs;
} else { } else {
// existing section // existing section
if (CisForcedUprightCharExt==currentSectionForcedUpright) { if (CFontMode==currentSectionFontMode) {
// continue current section // continue current section
currentSection+=c; currentSection+=cs;
} else { } else {
// start new section // start new section
textpart.append(currentSection); textpart.append(currentSection);
fontForcedUpright.append(currentSectionForcedUpright); fontMode.append(currentSectionFontMode);
currentSection=c; currentSection=cs;
currentSectionForcedUpright=CisForcedUprightChar; currentSectionFontMode=CFontMode;
} }
} }
i++; i++;
} }
if (currentSection.size()>0) { if (currentSection.size()>0) {
textpart.append(currentSection); textpart.append(currentSection);
fontForcedUpright.append(currentSectionForcedUpright); fontMode.append(currentSectionFontMode);
} }
} }
@ -215,25 +282,49 @@ double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMat
double overallHeight=0; double overallHeight=0;
double sp=0; double sp=0;
QStringList textpart; QStringList textpart;
QList<bool> fontForcedUpright;
QList<double> textpartXPos; QList<double> textpartXPos;
getSizeInternalAndData(painter, currentEv, width, baselineHeight, overallHeight, sp, textpart, fontForcedUpright, textpartXPos); QList<FontMode> fontMode;
getSizeInternalAndData(painter, currentEv, width, baselineHeight, overallHeight, sp, textpart, fontMode, textpartXPos);
const QFont f=currentEv.getFont(parentMathText); const QFont f=currentEv.getFont(parentMathText);
const QFont fnonItalic=JKQTMathTextGetNonItalic(f); const QFont fUpright=JKQTMathTextGetNonItalic(f);
const QFont fFallbackSym=currentEv.exchangedFontFor(MTEFallbackSymbols).getFont(parentMathText);
const QFont fRoman=currentEv.exchangedFontForRoman().getFont(parentMathText);
const QFontMetricsF fm(f, painter.device()); const QFontMetricsF fm(f, painter.device());
const QFontMetricsF fmNonItalic(fnonItalic, painter.device()); const QFontMetricsF fmUpright(fUpright, painter.device());
const QFontMetricsF fmFallbackSym(fFallbackSym, painter.device());
const QFontMetricsF fmRoman(fRoman, painter.device());
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setFont(f); painter.setFont(f);
painter.setPen(currentEv.color);
//qDebug()<<"JKQTMathTextTextNode: text="<<text<<" font="<<f; //qDebug()<<"JKQTMathTextTextNode: text="<<text<<" font="<<f;
for (int i=0; i<textpart.size(); i++) { for (int i=0; i<textpart.size(); i++) {
if (fontForcedUpright[i]) drawString(painter, currentEv, fnonItalic, x+textpartXPos[i], y, textpart[i]); switch(fontMode[i]) {
else drawString(painter, currentEv, f, x+textpartXPos[i], y, textpart[i]); case FMasDefined:
painter.setFont(f);
painter.drawText(QPointF(x+textpartXPos[i], y), textpart[i]);
break;
case FMasDefinedOutline:
JKQTMathTextDrawStringSimBlackboard(painter, f, currentEv.color, x+textpartXPos[i], y, textpart[i]);
break;
case FMasDefinedForceUpright:
painter.setFont(fUpright);
painter.drawText(QPointF(x+textpartXPos[i], y), textpart[i]);
break;
case FMroman:
painter.setFont(fRoman);
painter.drawText(QPointF(x+textpartXPos[i], y), textpart[i]);
break;
case FMfallbackSymbol:
painter.setFont(fFallbackSym);
painter.drawText(QPointF(x+textpartXPos[i], y), textpart[i]);
break;
}
} }
return x+width; return x+width;
@ -282,6 +373,11 @@ QString JKQTMathTextTextNode::textTransform(const QString &text, const JKQTMathT
JKQTMathTextVerbatimNode::JKQTMathTextVerbatimNode(JKQTMathText *_parent, const QString& _text, bool visibleWhitespace_, JKQTMathTextHorizontalAlignment _alignment, double _linespacingFactor, JKQTMathTextVerticalOrientation _verticalOrientation): JKQTMathTextVerbatimNode::JKQTMathTextVerbatimNode(JKQTMathText *_parent, const QString& _text, bool visibleWhitespace_, JKQTMathTextHorizontalAlignment _alignment, double _linespacingFactor, JKQTMathTextVerticalOrientation _verticalOrientation):
JKQTMathTextTextBaseNode(_parent, _text), JKQTMathTextTextBaseNode(_parent, _text),
alignment(_alignment), alignment(_alignment),
@ -326,8 +422,9 @@ double JKQTMathTextVerbatimNode::draw(QPainter &painter, double x, double y, JKQ
f.setStyleStrategy(QFont::PreferDefault); f.setStyleStrategy(QFont::PreferDefault);
f.setFixedPitch(true); f.setFixedPitch(true);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setFont(f);
for (int i=0; i<l.lines.size(); i++) { for (int i=0; i<l.lines.size(); i++) {
drawString(painter, currentEv, f, x+l.X.at(i).x(), y+l.X.at(i).y(), l.lines.at(i)); painter.drawText(QPointF(x+l.X.at(i).x(), y+l.X.at(i).y()), l.lines.at(i));
} }
return x+l.width; return x+l.width;
} }

View File

@ -52,16 +52,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextBaseNode: public JKQTMathTextNode
protected: protected:
/** \brief text-contents of the node */ /** \brief text-contents of the node */
QString text; QString text;
/** \brief draw a given \a txt in the font defined by \a currentEv at (\a x , \a y ) using the given \a painter
*
* This function implements drawing of synthesized fonts, e.g. MTEblackboard when JKQTMathText::isFontBlackboardSimulated() is \c true .
*/
void drawString(QPainter& painter, const JKQTMathTextEnvironment& currentEv, double x, double y, const QString& txt) const;
/** \brief draw a given \a txt in the font \a f using additional informaion (but not currentEv::getFont() ) from \a currentEv at (\a x , \a y ) using the given \a painter
*
* This function implements drawing of synthesized fonts, e.g. MTEblackboard when JKQTMathText::isFontBlackboardSimulated() is \c true .
*/
void drawString(QPainter& painter, const JKQTMathTextEnvironment &currentEv, const QFont& f, double x, double y, const QString& txt) const;
/** \brief transforms the \a text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */ /** \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; virtual QString textTransform(const QString& text, const JKQTMathTextEnvironment& currentEv) const;
}; };
@ -79,13 +69,32 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextTextBaseN
/** \copydoc JKQTMathTextNode::getTypeName() */ /** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override ; virtual QString getTypeName() const override ;
protected: protected:
/** \brief defines how a character shold be drawn, used by splitTextForLayout */
enum FontMode {
FMasDefined,
FMasDefinedForceUpright,
FMasDefinedOutline,
FMroman,
FMfallbackSymbol
};
/** \copydoc JKQTMathTextNode::getSizeInternal() */ /** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \brief calculates the size of the node, much like JKQTMathTextNode::getSizeInternal(), but returns additional properties that can be reused for drawing */ /** \brief calculates the size of the node, much like JKQTMathTextNode::getSizeInternal(), but returns additional properties that can be reused for drawing */
void getSizeInternalAndData(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, QStringList& textpart, QList<bool>& fontForcedUpright, QList<double>& textpartXPos) ; void getSizeInternalAndData(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, QStringList& textpart, QList<FontMode>& fontMode, QList<double>& textpartXPos) ;
/** \brief split text for Math-Mode into section with "normal" text and "forced upright" text */ /** \brief split text for Math-Modelayout into sections, where each section has a defined way of output
static void splitTextForMathMode(const QString& txt, QStringList& textpart, QList<bool>& fontForcedUpright); *
/** \brief transforms the \a text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */ * \param painter the QPainter to use for sizing/drawing
* \param currentEv the environment that defines the formatting of the text
* \param txt the text to split up
* \param[out] textpart the input \A txt split up into sections
* \param[out] fontMode formating of each section in \a textpart
*/
void splitTextForLayout(QPainter &painter, JKQTMathTextEnvironment currentEv, const QString& txt, QStringList& textpart, QList<FontMode>& fontMode) const;
/** \brief translation table for blackboard-font characters from "normal" Latin-1 encoding to unicode-encoding of blackboards */
static QHash<QChar, uint32_t> blackboardUnicodeTable;
/** \brief fill static data */
static void fillStaticTables();
/** \copydoc JKQTMathTextTextBaseNode::textTransform() */
virtual QString textTransform(const QString& text, const JKQTMathTextEnvironment& currentEv) const override; virtual QString textTransform(const QString& text, const JKQTMathTextEnvironment& currentEv) const override;
}; };

View File

@ -68,7 +68,7 @@ The tool supports these command-line options:
- `--fontmathroman=FONT`: set the math-mode roman font - `--fontmathroman=FONT`: set the math-mode roman font
- `--fontmathsans=FONT`: set the math-mode sans font - `--fontmathsans=FONT`: set the math-mode sans font
- `--fontblackboard=FONT`: use the given font as blackboard-font and de-activate the simulate-feature - `--fontblackboard=FONT`: use the given font as blackboard-font and de-activate the simulate-feature
- `--fontblackboardsimulated=FONT`: use the given font as blackboard-font and activate the simulate-feature - `--fontblackboardmode=default|font_directly|simulate|unicode_or_font_directly|unicode_or_simulate`: use the given drawing mode for blackboard fonts
- `--fonttypewriter=FONT`: set the typewriter font - `--fonttypewriter=FONT`: set the typewriter font
- `--fontscript=FONT`: set the script font - `--fontscript=FONT`: set the script font
- `--fontcaligraphic=FONT`: set the caligraphic font - `--fontcaligraphic=FONT`: set the caligraphic font

View File

@ -69,7 +69,7 @@ int main(int argc, char* argv[])
parser.addOption(outputDirectoryOption); parser.addOption(outputDirectoryOption);
QCommandLineOption listsymbolsOption("listsymbols", "list all symbols in the given output file and generate images.", "listsymbols", ""); QCommandLineOption listsymbolsOption("listsymbols", "list all symbols in the given output file and generate images.", "listsymbols", "");
parser.addOption(listsymbolsOption); parser.addOption(listsymbolsOption);
QCommandLineOption drawBoxesOption("drawboxes", "draw boxes."); QCommandLineOption drawBoxesOption(QStringList()<<"drawboxes"<<"showboxes", "draw boxes.");
parser.addOption(drawBoxesOption); parser.addOption(drawBoxesOption);
QCommandLineOption verboseOption("verbose", "verbose output."); QCommandLineOption verboseOption("verbose", "verbose output.");
parser.addOption(verboseOption); parser.addOption(verboseOption);
@ -77,8 +77,6 @@ int main(int argc, char* argv[])
parser.addOption(fontOption); parser.addOption(fontOption);
QCommandLineOption fontsizeOption("fontsize", "font size.", "fontsize", "12"); QCommandLineOption fontsizeOption("fontsize", "font size.", "fontsize", "12");
parser.addOption(fontsizeOption); parser.addOption(fontsizeOption);
QCommandLineOption fontBlackboardSimOption("fontblackboardsimulated", "set the blackboard font and activate simulated-mode.", "fontblackboardsimulated", "");
parser.addOption(fontBlackboardSimOption);
QCommandLineOption fontRomanOption("fontroman", "set the text-mode roman font to use.", "fontroman", ""); QCommandLineOption fontRomanOption("fontroman", "set the text-mode roman font to use.", "fontroman", "");
parser.addOption(fontRomanOption); parser.addOption(fontRomanOption);
QCommandLineOption fontSansOption("fontsans", "set the text-mode sans font to use.", "fontsans", ""); QCommandLineOption fontSansOption("fontsans", "set the text-mode sans font to use.", "fontsans", "");
@ -101,6 +99,8 @@ int main(int argc, char* argv[])
parser.addOption(fontcaligraphicOption); parser.addOption(fontcaligraphicOption);
QCommandLineOption fontblackboardOption("fontblackboard", "set the blackboard font to use.", "fontblackboard", ""); QCommandLineOption fontblackboardOption("fontblackboard", "set the blackboard font to use.", "fontblackboard", "");
parser.addOption(fontblackboardOption); parser.addOption(fontblackboardOption);
QCommandLineOption fontblackboardmodeOption("fontblackboardmode", "set the usage mode for the blackboard font.", "fontblackboardmode", "default");
parser.addOption(fontblackboardmodeOption);
QCommandLineOption textcolorOption("textcolor", "set the color of the text.", "textcolor", "black"); QCommandLineOption textcolorOption("textcolor", "set the color of the text.", "textcolor", "black");
parser.addOption(textcolorOption); parser.addOption(textcolorOption);
QCommandLineOption sizeincreaseOption("sizeincrease", "additional pixels around output.", "sizeincrease", "2"); QCommandLineOption sizeincreaseOption("sizeincrease", "additional pixels around output.", "sizeincrease", "2");
@ -260,7 +260,6 @@ int main(int argc, char* argv[])
int resolution_dpi = parser.value(resolutionOption).toInt(); int resolution_dpi = parser.value(resolutionOption).toInt();
QColor backgroundColor = jkqtp_String2QColor(parser.value(backgroundOption)); QColor backgroundColor = jkqtp_String2QColor(parser.value(backgroundOption));
QColor textColor = jkqtp_String2QColor(parser.value(textcolorOption)); QColor textColor = jkqtp_String2QColor(parser.value(textcolorOption));
QString fontBlackboardSim = parser.value(fontBlackboardSimOption);
QString fontBlackboard=parser.value(fontblackboardOption); QString fontBlackboard=parser.value(fontblackboardOption);
QString fontRoman=parser.value(fontRomanOption); QString fontRoman=parser.value(fontRomanOption);
QString fontSans=parser.value(fontSansOption); QString fontSans=parser.value(fontSansOption);
@ -272,15 +271,15 @@ int main(int argc, char* argv[])
QString fontScript=parser.value(fontScriptOption); QString fontScript=parser.value(fontScriptOption);
QString fontFraktur=parser.value(fontFrakturOption); QString fontFraktur=parser.value(fontFrakturOption);
QString fontCaligraphic=parser.value(fontcaligraphicOption); QString fontCaligraphic=parser.value(fontcaligraphicOption);
JKQTMathTextBlackboradDrawingMode fontBlackboardMode=String2JKQTMathTextBlackboradDrawingMode(parser.value(fontblackboardmodeOption));
if (cmdoptions[i].size()>0) { if (cmdoptions[i].size()>0) {
for (const QString& key: cmdoptions[i].keys()) { for (const QString& key: cmdoptions[i].keys()) {
if (key=="drawboxes") drawBoxes=true; if (key=="drawboxes" || key=="showboxes") drawBoxes=true;
else if (key=="fontsize") fontsize=cmdoptions[i].value(key).toDouble(); else if (key=="fontsize") fontsize=cmdoptions[i].value(key).toDouble();
else if (key=="sizeincrease") sizeincrease=cmdoptions[i].value(key).toInt(); else if (key=="sizeincrease") sizeincrease=cmdoptions[i].value(key).toInt();
else if (key=="background") backgroundColor=jkqtp_String2QColor(cmdoptions[i].value(key)); else if (key=="background") backgroundColor=jkqtp_String2QColor(cmdoptions[i].value(key));
else if (key=="textcolor") textColor=jkqtp_String2QColor(cmdoptions[i].value(key)); else if (key=="textcolor") textColor=jkqtp_String2QColor(cmdoptions[i].value(key));
else if (key=="fontblackboardsimulated") fontBlackboardSim=cmdoptions[i].value(key);
else if (key=="fontblackboard") fontBlackboard=cmdoptions[i].value(key); else if (key=="fontblackboard") fontBlackboard=cmdoptions[i].value(key);
else if (key=="font") processFont(cmdoptions[i].value(key), fonts, mathFont); else if (key=="font") processFont(cmdoptions[i].value(key), fonts, mathFont);
else if (key=="fontroman") fontRoman=cmdoptions[i].value(key); else if (key=="fontroman") fontRoman=cmdoptions[i].value(key);
@ -293,6 +292,10 @@ int main(int argc, char* argv[])
else if (key=="fontscript") fontScript=cmdoptions[i].value(key); else if (key=="fontscript") fontScript=cmdoptions[i].value(key);
else if (key=="fontcaligraphic") fontCaligraphic=cmdoptions[i].value(key); else if (key=="fontcaligraphic") fontCaligraphic=cmdoptions[i].value(key);
else if (key=="fontfraktur") fontFraktur=cmdoptions[i].value(key); else if (key=="fontfraktur") fontFraktur=cmdoptions[i].value(key);
else if (key=="fontblackboardmode") fontBlackboardMode=String2JKQTMathTextBlackboradDrawingMode(cmdoptions[i].value(key));
else {
std::cerr<<"unknown command-line option --"<<key.toStdString()<<" in inputfile\n";
}
} }
} }
@ -328,14 +331,10 @@ int main(int argc, char* argv[])
if (fontFallbackSymbol.size()>0) mathText.setFallbackFontSymbols(fontFallbackSymbol, MTFEUnicode); if (fontFallbackSymbol.size()>0) mathText.setFallbackFontSymbols(fontFallbackSymbol, MTFEUnicode);
if (fontFallbackSymbol_symbolencoding.size()>0) mathText.setFallbackFontSymbols(fontFallbackSymbol_symbolencoding, MTFEWinSymbol); if (fontFallbackSymbol_symbolencoding.size()>0) mathText.setFallbackFontSymbols(fontFallbackSymbol_symbolencoding, MTFEWinSymbol);
if (fontBlackboardSim.size()>0) {
mathText.setFontBlackboard(fontBlackboardSim, MTFEUnicode);
mathText.setFontBlackboardSimulated(true);
}
if (fontBlackboard.size()>0) { if (fontBlackboard.size()>0) {
mathText.setFontBlackboard(fontBlackboard, MTFEUnicode); mathText.setFontBlackboard(fontBlackboard, MTFEUnicode);
mathText.setFontBlackboardSimulated(false);
} }
mathText.setFontBlackboradMode(fontBlackboardMode);
mathText.setFontSize(fontsize); mathText.setFontSize(fontsize);
mathText.setFontColor(textColor); mathText.setFontColor(textColor);