2019-01-26 19:28:44 +08:00
/*
2022-06-08 21:38:26 +08:00
Copyright ( c ) 2008 - 2022 Jan W . Krieger ( < jan @ jkrieger . de > )
2019-01-26 19:28:44 +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
2019-02-08 00:24:46 +08:00
the Free Software Foundation , either version 2.1 of the License , or
2019-01-26 19:28:44 +08:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License ( LGPL ) for more details .
You should have received a copy of the GNU Lesser General Public License ( LGPL )
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "jkqtmathtext/jkqtmathtext.h"
2022-06-08 21:38:26 +08:00
# include "jkqtmathtext/nodes/jkqtmathtextnode.h"
2019-05-30 04:40:02 +08:00
# include "jkqtcommon/jkqtpcodestructuring.h"
# include "jkqtcommon/jkqtpstringtools.h"
2022-06-08 21:38:26 +08:00
# include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextbracenode.h"
# include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h"
# include "jkqtmathtext/nodes/jkqtmathtextfracnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextlistnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextmatrixnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextsqrtnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h"
# include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h"
2019-05-30 04:40:02 +08:00
# include <cmath>
2019-01-26 19:28:44 +08:00
# include <QFontMetricsF>
# include <QDebug>
# include <QFontDatabase>
# include <typeinfo>
# include <QApplication>
2020-08-14 20:12:59 +08:00
# include <QPainterPath>
2019-01-26 19:28:44 +08:00
2022-04-21 16:57:24 +08:00
2019-02-08 00:24:46 +08:00
const double JKQTMathText : : ABS_MIN_LINEWIDTH = 0.02 ;
2019-01-26 19:28:44 +08:00
2022-06-03 19:33:18 +08:00
2019-06-30 23:34:41 +08:00
// --------------------------------------------------------------------------------------------------
// -- implementation of the JKQTMathText methods
// --------------------------------------------------------------------------------------------------
JKQTMathText : : JKQTMathText ( QObject * parent ) :
QObject ( parent )
{
2019-11-24 19:48:20 +08:00
//std::chrono::high_resolution_clock::time_point t0=std::chrono::high_resolution_clock::now();
2020-06-28 15:49:20 +08:00
initJKQTMathTextResources ( ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"init_resoucre: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
fontSize = 10 ;
brace_factor = 1.04 ;
subsuper_size_factor = 0.7 ;
italic_correction_factor = 0.4 ;
sub_shift_factor = 0.4 ;
super_shift_factor = 0.6 ;
brace_shrink_factor = 0.6 ;
fontColor = QColor ( " black " ) ;
2022-06-09 05:52:22 +08:00
frac_factor = 1.0 ;
frac_nested_factor = 0.7 ;
2019-06-30 23:34:41 +08:00
frac_shift_factor = 0.4 ;
underbrace_factor = 0.75 ;
undersetFactor = 0.7 ;
decoration_height_factor = 0.2 ;
2022-06-07 05:24:05 +08:00
decoration_width_reduction_Xfactor = 0.2 ;
2019-06-30 23:34:41 +08:00
brace_y_shift_factor = 0.7 ; //-1;
operatorsubsuper_size_factor = 0.65 ;
mathoperator_width_factor = 1.5 ;
expensiveRendering = true ;
blackboardSimulated = true ;
2022-06-09 20:30:15 +08:00
showLeftBrace = true ;
showRightBrace = true ;
2019-06-30 23:34:41 +08:00
2019-06-30 23:59:04 +08:00
static QString serifFont = " serif " ;
static QString sansFont = " sans " ;
static QString symbolFont = " symbol " ;
static QString scriptFont = " script " ;
static QString typewriterFont = " typewriter " ;
static QString decorativeFont = " decorative " ;
static QString blackboardFont = " blackboard " ;
static QString fracturFont = " fraktur " ;
static bool firstStart = true ;
if ( firstStart ) {
2019-11-24 19:48:20 +08:00
//t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:59:04 +08:00
firstStart = false ;
2022-06-03 04:31:39 +08:00
# if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb ;
const auto fonts = fdb . families ( ) ;
# else
const auto fonts = QFontDatabase : : families ( ) ;
# endif
2019-06-30 23:59:04 +08:00
//qDebug()<<"fonts:\n"<<fonts;
2019-11-24 19:48:20 +08:00
/*if (SCAN_FONTS_ON_STARTUP) {
for ( const QString & f : fonts ) {
QFont fnt ( f ) ;
QFontInfo fi ( fnt ) ;
if ( typewriterFont = = " typewriter " & & fi . styleHint ( ) = = QFont : : TypeWriter ) {
typewriterFont = f ;
}
if ( decorativeFont = = " decorative " & & fi . styleHint ( ) = = QFont : : Decorative ) {
decorativeFont = f ;
}
if ( serifFont = = " serif " & & fi . styleHint ( ) = = QFont : : Serif ) {
serifFont = f ;
}
if ( sansFont = = " sans " & & fi . styleHint ( ) = = QFont : : SansSerif ) {
sansFont = f ;
}
if ( scriptFont = = " script " & & fi . styleHint ( ) = = QFont : : Cursive ) {
scriptFont = f ;
}
2019-06-30 23:34:41 +08:00
}
2019-11-24 19:48:20 +08:00
} */
//qDebug()<<"iterate "<<fonts.size()<<" fonts: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
2019-06-30 23:59:04 +08:00
auto checkForFonts = [ & fonts ] ( QString & targetfont , const QStringList & fontoptions ) {
for ( auto & f : fontoptions ) {
if ( fonts . contains ( f ) ) {
targetfont = f ;
break ;
}
}
} ;
2019-06-30 23:34:41 +08:00
2019-06-30 23:59:04 +08:00
checkForFonts ( serifFont , QStringList { " Times New Roman " , " Times " , " FreeSerif " , " DejaVu Serif " } ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"check 1st font: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms";
2019-06-30 23:59:04 +08:00
checkForFonts ( sansFont , QStringList { " Arial Unicode MS " , " Arial Unicode " , " Lucida Sans Unicode " , " Arial " , " Helvetica " , " FreeSans " , " DejaVu Sans " , " Lucida Sans " } ) ;
checkForFonts ( symbolFont , QStringList { " SymbolStandard " , " Symbol " } ) ;
checkForFonts ( typewriterFont , QStringList { " Courier New " , " Courier " , " Courier Std " , " FreeMono " , " CMU Typewriter Text " , " UM Typewriter " } ) ;
checkForFonts ( blackboardFont , QStringList { " Double Stroke " , " CloisterOpenFace BT " , " GoudyHandtooled BT " , " Castellar " , " MathJax_AMS " , " Castellar Standard " , " MathJax_AMS Standard " , " Colonna MT " } ) ;
checkForFonts ( decorativeFont , QStringList { " Lucida Calligraphy " , " Cookie " , " Segoe Print " , " Comic Sans " , " Comic Sans MS " , " Gabriola " , " Gabriola Standard " , " Lucida Handwriting Kursiv " , " Lucida Handwriting " , " Pristina " , " Pristina Standard " , " MathJax_Caligraphics " } ) ;
checkForFonts ( scriptFont , QStringList { " Lucida Handwriting " , " Dancing Script " , " Amazone BT " , " ScriptS " , " ScriptC " , " ScriptC Standard " , " Script " , " Brush Script MT " , " Brush Script MT Kursiv " , " MathJax_Script " } ) ;
checkForFonts ( fracturFont , QStringList { " Old English Text MT " , " Old English Text MT Standard " , " UnifrakturMaguntia Standard " , " UnifrakturMaguntia " , " MathJax_Fraktur " , " UnifrakturCook Fett " } ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"check all font: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms";
2019-06-30 23:59:04 +08:00
}
2019-06-30 23:34:41 +08:00
2019-11-24 19:48:20 +08:00
//t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
if ( serifFont ! = " serif " ) addReplacementFont ( " serif " , serifFont ) ;
if ( sansFont ! = " sans " ) addReplacementFont ( " sans " , sansFont ) ;
if ( symbolFont ! = " symbol " ) addReplacementFont ( " symbol " , symbolFont ) ;
if ( scriptFont ! = " script " ) addReplacementFont ( " script " , scriptFont ) ;
if ( typewriterFont ! = " typewriter " ) addReplacementFont ( " typewriter " , typewriterFont ) ;
if ( decorativeFont ! = " decorative " ) addReplacementFont ( " decorative " , decorativeFont ) ;
if ( fracturFont ! = " fraktur " ) addReplacementFont ( " fraktur " , fracturFont ) ;
if ( blackboardFont ! = " blackboard " ) {
addReplacementFont ( " blackboard " , blackboardFont ) ;
}
2019-11-24 19:48:20 +08:00
//qDebug()<<"add replacement fonts: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
setFontSans ( sansFont , MTFEStandard ) ;
setFontMathSans ( sansFont , MTFEStandard ) ;
setFontTypewriter ( typewriterFont , MTFEStandard ) ;
setFontRoman ( serifFont , MTFEStandard ) ;
setFontMathRoman ( serifFont , MTFEStandard ) ;
setFontCaligraphic ( decorativeFont , MTFEStandard ) ;
setFontBlackboard ( blackboardFont , MTFEStandard ) ;
setFontBlackboardSimulated ( blackboardFont = = " blackboard " ) ;
setFontScript ( scriptFont , MTFEStandard ) ;
setFontFraktur ( fracturFont , MTFEStandard ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"set fonts: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
useXITS ( ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"useXITS: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
useUnparsed = false ;
parsedNode = nullptr ;
unparsedNode = nullptr ;
currentToken = MTTnone ;
currentTokenName = " " ;
currentTokenID = 0 ;
parseString = " " ;
parsingMathEnvironment = false ;
}
JKQTMathText : : ~ JKQTMathText ( ) {
if ( parsedNode ! = nullptr ) delete parsedNode ;
parsedNode = nullptr ;
if ( unparsedNode ! = nullptr ) delete unparsedNode ;
unparsedNode = nullptr ;
}
void JKQTMathText : : loadSettings ( const QSettings & settings , const QString & group ) {
fontSize = settings . value ( group + " font_size " , fontSize ) . toDouble ( ) ;
fontColor = jkqtp_String2QColor ( settings . value ( group + " font_color " , jkqtp_QColor2String ( fontColor ) ) . toString ( ) ) ;
brace_factor = settings . value ( group + " brace_factor " , brace_factor ) . toDouble ( ) ;
brace_shrink_factor = settings . value ( group + " brace_shrink_factor " , brace_shrink_factor ) . toDouble ( ) ;
subsuper_size_factor = settings . value ( group + " subsuper_size_factor " , subsuper_size_factor ) . toDouble ( ) ;
italic_correction_factor = settings . value ( group + " italic_correction_factor " , italic_correction_factor ) . toDouble ( ) ;
super_shift_factor = settings . value ( group + " super_shift_factor " , super_shift_factor ) . toDouble ( ) ;
sub_shift_factor = settings . value ( group + " sub_shift_factor " , sub_shift_factor ) . toDouble ( ) ;
frac_factor = settings . value ( group + " frac_factor " , frac_factor ) . toDouble ( ) ;
frac_shift_factor = settings . value ( group + " frac_shift_factor " , frac_shift_factor ) . toDouble ( ) ;
underbrace_factor = settings . value ( group + " underbrace_factor " , underbrace_factor ) . toDouble ( ) ;
undersetFactor = settings . value ( group + " undersetFactor " , undersetFactor ) . toDouble ( ) ;
brace_y_shift_factor = settings . value ( group + " brace_y_shift_factor " , brace_y_shift_factor ) . toDouble ( ) ;
decoration_height_factor = settings . value ( group + " decoration_height_factor " , decoration_height_factor ) . toDouble ( ) ;
2022-06-07 05:24:05 +08:00
decoration_width_reduction_Xfactor = settings . value ( group + " decoration_width_reduction_xfactor " , decoration_width_reduction_Xfactor ) . toDouble ( ) ;
2019-06-30 23:34:41 +08:00
operatorsubsuper_size_factor = settings . value ( group + " operatorsubsuper_size_factor " , operatorsubsuper_size_factor ) . toDouble ( ) ;
mathoperator_width_factor = settings . value ( group + " mathoperator_width_factor " , mathoperator_width_factor ) . toDouble ( ) ;
if ( settings . value ( group + " use_stix_fonts " , false ) . toBool ( ) ) useSTIX ( ) ;
if ( settings . value ( group + " use_xits_fonts " , false ) . toBool ( ) ) useXITS ( ) ;
if ( settings . value ( group + " use_asana_fonts " , false ) . toBool ( ) ) useASANA ( ) ;
}
void JKQTMathText : : saveSettings ( QSettings & settings , const QString & group ) const {
settings . setValue ( group + " font_size " , fontSize ) ;
settings . setValue ( group + " font_color " , jkqtp_QColor2String ( fontColor ) ) ;
settings . setValue ( group + " brace_factor " , brace_factor ) ;
settings . setValue ( group + " brace_shrink_factor " , brace_shrink_factor ) ;
settings . setValue ( group + " subsuper_size_factor " , subsuper_size_factor ) ;
settings . setValue ( group + " italic_correction_factor " , italic_correction_factor ) ;
settings . setValue ( group + " sub_shift_factor " , sub_shift_factor ) ;
settings . setValue ( group + " super_shift_factor " , super_shift_factor ) ;
settings . setValue ( group + " frac_factor " , frac_factor ) ;
settings . setValue ( group + " frac_shift_factor " , frac_shift_factor ) ;
settings . setValue ( group + " underbrace_factor " , underbrace_factor ) ;
settings . setValue ( group + " undersetFactor " , undersetFactor ) ;
settings . setValue ( group + " operatorsubsuper_size_factor " , operatorsubsuper_size_factor ) ;
settings . setValue ( group + " mathoperator_width_factor " , mathoperator_width_factor ) ;
settings . setValue ( group + " brace_y_shift_factor " , brace_y_shift_factor ) ;
settings . setValue ( group + " decoration_height_factor " , decoration_height_factor ) ;
2022-06-07 05:24:05 +08:00
settings . setValue ( group + " decoration_width_reduction_xfactor " , decoration_width_reduction_Xfactor ) ;
2019-06-30 23:34:41 +08:00
}
bool JKQTMathText : : useSTIX ( bool mathModeOnly ) {
2022-06-03 03:02:23 +08:00
const JKQTMathTextFontSpecifier xits = JKQTMathTextFontSpecifier : : getSTIXFamilies ( ) ;
2019-06-30 23:34:41 +08:00
bool res = false ;
2022-06-03 03:02:23 +08:00
if ( ! mathModeOnly & & ! xits . fontName ( ) . isEmpty ( ) ) {
setFontRoman ( xits . fontName ( ) , MTFEunicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
2022-06-03 03:02:23 +08:00
if ( ! xits . mathFontName ( ) . isEmpty ( ) ) {
setFontMathRoman ( xits . mathFontName ( ) , MTFEunicode ) ;
res = true ;
} else if ( ! xits . fontName ( ) . isEmpty ( ) ) {
setFontMathRoman ( xits . fontName ( ) , MTFEunicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
brace_shrink_factor = 0.6 ;
return res ;
}
bool JKQTMathText : : useXITS ( bool mathModeOnly )
{
2022-06-03 03:02:23 +08:00
const JKQTMathTextFontSpecifier xits = JKQTMathTextFontSpecifier : : getXITSFamilies ( ) ;
2019-06-30 23:34:41 +08:00
bool res = false ;
2022-06-03 03:02:23 +08:00
if ( ! mathModeOnly & & ! xits . fontName ( ) . isEmpty ( ) ) {
setFontRoman ( xits . fontName ( ) , MTFEunicode ) ;
setSymbolfontSymbol ( xits . fontName ( ) , MTFEunicode ) ;
setSymbolfontGreek ( xits . fontName ( ) , MTFEunicode ) ;
2019-11-16 22:02:48 +08:00
brace_shrink_factor = 0.6 ;
2019-06-30 23:34:41 +08:00
res = true ;
}
2022-06-03 03:02:23 +08:00
if ( ! xits . mathFontName ( ) . isEmpty ( ) ) {
setFontMathRoman ( xits . mathFontName ( ) , MTFEunicode ) ;
setSymbolfontSymbol ( xits . fontName ( ) , MTFEunicode ) ;
setSymbolfontGreek ( xits . fontName ( ) , MTFEunicode ) ;
2019-11-16 22:02:48 +08:00
brace_shrink_factor = 0.6 ;
2019-06-30 23:34:41 +08:00
res = true ;
}
return res ;
}
bool JKQTMathText : : useASANA ( bool mathModeOnly )
{
2022-06-03 03:02:23 +08:00
const JKQTMathTextFontSpecifier asana = JKQTMathTextFontSpecifier : : getXITSFamilies ( ) ;
2019-06-30 23:34:41 +08:00
bool res = false ;
2022-06-03 03:02:23 +08:00
if ( ! mathModeOnly & & ! asana . fontName ( ) . isEmpty ( ) ) {
setFontRoman ( asana . fontName ( ) , MTFEunicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
2022-06-03 03:02:23 +08:00
if ( ! asana . mathFontName ( ) . isEmpty ( ) ) {
setFontMathRoman ( asana . mathFontName ( ) , MTFEunicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
brace_shrink_factor = 0.6 ;
return res ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : useAnyUnicode ( QString timesFont , const QString & sansFont , JKQTMathTextFontEncoding encodingTimes , JKQTMathTextFontEncoding encodingSans )
2019-06-30 23:34:41 +08:00
{
if ( ! timesFont . isEmpty ( ) ) { setFontRoman ( timesFont , encodingTimes ) ; }
if ( ! sansFont . isEmpty ( ) ) { setFontSans ( sansFont , encodingSans ) ; }
brace_shrink_factor = 0.6 ;
}
QString JKQTMathText : : toHtml ( bool * ok , double fontPointSize ) {
QString s ;
bool okk = false ;
if ( getTree ( ) ! = nullptr ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-06-30 23:34:41 +08:00
ev . color = fontColor ;
ev . fontSize = fontPointSize ;
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment defaultev ;
2019-06-30 23:34:41 +08:00
defaultev . fontSize = fontPointSize ;
okk = getTree ( ) - > toHtml ( s , ev , defaultev ) ;
}
if ( ok ) * ok = okk ;
return s ;
}
void JKQTMathText : : setFontColor ( const QColor & __value )
{
this - > fontColor = __value ;
}
QColor JKQTMathText : : getFontColor ( ) const
{
return this - > fontColor ;
}
void JKQTMathText : : setFontSize ( double __value )
{
this - > fontSize = __value ;
}
double JKQTMathText : : getFontSize ( ) const
{
return this - > fontSize ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : addReplacementFont ( const QString & nonUseFont , const QString & useFont , JKQTMathTextFontEncoding useFontEncoding ) {
2019-06-30 23:34:41 +08:00
fontReplacements . insert ( nonUseFont , useFont ) ;
fontEncodingReplacements . insert ( nonUseFont , useFontEncoding ) ;
}
void JKQTMathText : : addReplacementFont ( const QString & nonUseFont , const QString & useFont ) {
fontReplacements . insert ( nonUseFont , useFont ) ;
auto it = fontEncodingReplacements . find ( nonUseFont ) ;
if ( it ! = fontEncodingReplacements . end ( ) ) fontEncodingReplacements . erase ( it ) ;
}
2022-06-08 21:38:26 +08:00
QPair < QString , JKQTMathTextFontEncoding > JKQTMathText : : getReplacementFont ( const QString & nonUseFont , const QString & defaultFont , JKQTMathTextFontEncoding defaultFontEncoding ) const {
QPair < QString , JKQTMathTextFontEncoding > res ( defaultFont , defaultFontEncoding ) ;
2019-06-30 23:34:41 +08:00
bool foundFont = false ;
for ( auto it = fontReplacements . begin ( ) ; it ! = fontReplacements . end ( ) ; + + it ) {
if ( it . key ( ) . toLower ( ) = = nonUseFont . toLower ( ) ) {
foundFont = true ;
res . first = it . value ( ) ;
res . second = fontEncodingReplacements . value ( res . first , res . second ) ;
return res ;
}
}
return res ;
}
2022-06-08 21:38:26 +08:00
QPair < QString , JKQTMathTextFontEncoding > JKQTMathText : : getFontData ( JKQTMathTextEnvironmentFont font , bool in_math_environment , FontSubclass subclass ) const
2019-06-30 23:34:41 +08:00
{
2022-06-03 19:33:18 +08:00
if ( in_math_environment ) {
if ( font = = MTEroman ) font = MTEmathRoman ;
if ( font = = MTEsans ) font = MTEmathSans ;
}
2022-06-03 03:02:23 +08:00
const auto fd = fontDefinitions . value ( font ) ;
2022-06-08 21:38:26 +08:00
if ( subclass = = FontSubclass : : Greek ) return QPair < QString , JKQTMathTextFontEncoding > ( fd . symbolfontGreek , fd . symbolfontGreekEncoding ) ;
if ( subclass = = FontSubclass : : Symbols ) return QPair < QString , JKQTMathTextFontEncoding > ( fd . symbolfontSymbol , fd . symbolfontSymbolEncoding ) ;
return QPair < QString , JKQTMathTextFontEncoding > ( fd . fontName , fd . fontEncoding ) ;
2019-06-30 23:34:41 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontRomanOrSpecial ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
2022-06-03 03:02:23 +08:00
setFontRomanOrSpecial ( JKQTMathTextFontSpecifier : : fromFontSpec ( __value ) , encoding ) ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontRomanOrSpecial ( const JKQTMathTextFontSpecifier & fontName , JKQTMathTextFontEncoding encoding )
2022-06-03 03:02:23 +08:00
{
if ( ! fontName . hasMathFontName ( ) ) {
if ( fontName . fontName ( ) . toUpper ( ) = = " XITS " ) useXITS ( false ) ;
else if ( fontName . fontName ( ) . toUpper ( ) = = " STIX " ) useSTIX ( false ) ;
else if ( fontName . fontName ( ) . toUpper ( ) = = " ASANA " ) useASANA ( false ) ;
else {
setFontRoman ( fontName . fontName ( ) , encoding ) ;
setFontMathRoman ( fontName . fontName ( ) , encoding ) ;
2019-06-30 23:34:41 +08:00
}
2022-06-03 03:02:23 +08:00
} else {
if ( fontName . mathFontName ( ) . toUpper ( ) = = " XITS " ) useXITS ( true ) ;
else if ( fontName . mathFontName ( ) . toUpper ( ) = = " STIX " ) useSTIX ( true ) ;
else if ( fontName . mathFontName ( ) . toUpper ( ) = = " ASANA " ) useASANA ( true ) ;
else setFontMathRoman ( fontName . mathFontName ( ) , encoding ) ;
setFontRoman ( fontName . fontName ( ) , encoding ) ;
2019-06-30 23:34:41 +08:00
}
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontRoman ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEroman ] . fontName = f . first ;
fontDefinitions [ MTEroman ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontRoman ( ) const
{
return fontDefinitions [ MTEroman ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingRoman ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEroman ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontSans ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEsans ] . fontName = f . first ;
fontDefinitions [ MTEsans ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontSans ( ) const
{
return fontDefinitions [ MTEsans ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingSans ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEsans ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontTypewriter ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEtypewriter ] . fontName = f . first ;
fontDefinitions [ MTEtypewriter ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontTypewriter ( ) const
{
return fontDefinitions [ MTEtypewriter ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingTypewriter ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEtypewriter ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontScript ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEscript ] . fontName = f . first ;
fontDefinitions [ MTEscript ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontScript ( ) const
{
return fontDefinitions [ MTEscript ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingScript ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEscript ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontFraktur ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEfraktur ] . fontName = f . first ;
fontDefinitions [ MTEfraktur ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontFraktur ( ) const
{
return fontDefinitions [ MTEfraktur ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingFraktur ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEfraktur ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setSymbolfontGreek ( JKQTMathTextEnvironmentFont font , const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ font ] . symbolfontGreek = f . first ;
fontDefinitions [ font ] . symbolfontGreekEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setSymbolfontGreek ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
for ( int f = 0 ; f < static_cast < int > ( MTenvironmentFontCount ) ; f + + ) {
2022-06-08 21:38:26 +08:00
setSymbolfontGreek ( static_cast < JKQTMathTextEnvironmentFont > ( f ) , fontName , encoding ) ;
2019-06-30 23:34:41 +08:00
}
}
2022-06-08 21:38:26 +08:00
QString JKQTMathText : : getSymbolfontGreek ( JKQTMathTextEnvironmentFont font ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ font ] . symbolfontGreek ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getSymbolfontEncodingGreek ( JKQTMathTextEnvironmentFont font ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ font ] . symbolfontGreekEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setSymbolfontSymbol ( JKQTMathTextEnvironmentFont font , const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ font ] . symbolfontSymbol = f . first ;
fontDefinitions [ font ] . symbolfontSymbolEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setSymbolfontSymbol ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
for ( int f = 0 ; f < static_cast < int > ( MTenvironmentFontCount ) ; f + + ) {
2022-06-08 21:38:26 +08:00
setSymbolfontSymbol ( static_cast < JKQTMathTextEnvironmentFont > ( f ) , fontName , encoding ) ;
2019-06-30 23:34:41 +08:00
}
}
2022-06-08 21:38:26 +08:00
QString JKQTMathText : : getSymbolfontSymbol ( JKQTMathTextEnvironmentFont font ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ font ] . symbolfontSymbol ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getSymbolfontEncodingSymbol ( JKQTMathTextEnvironmentFont font ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ font ] . symbolfontSymbolEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontCaligraphic ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEcaligraphic ] . fontName = f . first ;
fontDefinitions [ MTEcaligraphic ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontCaligraphic ( ) const
{
return fontDefinitions [ MTEcaligraphic ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingCaligraphic ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEcaligraphic ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontMathRoman ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( fontName , fontName , encoding ) ;
fontDefinitions [ MTEmathRoman ] . fontName = f . first ;
fontDefinitions [ MTEmathRoman ] . fontEncoding = f . second ;
}
QString JKQTMathText : : getFontMathRoman ( ) const
{
return fontDefinitions [ MTEmathRoman ] . fontName ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontMathSans ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( fontName , fontName , encoding ) ;
fontDefinitions [ MTEmathSans ] . fontName = f . first ;
fontDefinitions [ MTEmathSans ] . fontEncoding = f . second ;
}
QString JKQTMathText : : getFontMathSans ( ) const
{
return fontDefinitions [ MTEmathSans ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingMathSans ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEmathSans ] . fontEncoding ;
}
2019-01-26 19:28:44 +08:00
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingMathRoman ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEmathRoman ] . fontEncoding ;
}
2019-01-26 19:28:44 +08:00
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontBlackboard ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
blackboardSimulated = false ;
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEblackboard ] . fontName = f . first ;
fontDefinitions [ MTEblackboard ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setFontBlackboardSimulated ( bool doSimulate )
{
blackboardSimulated = doSimulate ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
bool JKQTMathText : : isFontBlackboardSimulated ( ) const
{
return blackboardSimulated ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
QString JKQTMathText : : getFontBlackboard ( ) const
{
return fontDefinitions [ MTEblackboard ] . fontName ;
2019-01-26 19:28:44 +08:00
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingBlackboard ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEblackboard ] . fontEncoding ;
2019-06-21 04:24:47 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setBraceFactor ( double __value )
{
this - > brace_factor = __value ;
2019-03-07 06:18:29 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getBraceFactor ( ) const
{
return this - > brace_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setSubsuperSizeFactor ( double __value )
2019-01-26 19:28:44 +08:00
{
2019-06-30 23:34:41 +08:00
this - > subsuper_size_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getSubsuperSizeFactor ( ) const
{
return this - > subsuper_size_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setItalicCorrectionFactor ( double __value )
{
this - > italic_correction_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getItalicCorrectionFactor ( ) const
{
return this - > italic_correction_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setOperatorsubsuperSizeFactor ( double __value )
{
this - > operatorsubsuper_size_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getOperatorsubsuperSizeFactor ( ) const
{
return this - > operatorsubsuper_size_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setMathoperatorWidthFactor ( double __value )
{
this - > mathoperator_width_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getMathoperatorWidthFactor ( ) const
{
return this - > mathoperator_width_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setSuperShiftFactor ( double __value )
{
this - > super_shift_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getSuperShiftFactor ( ) const
{
return this - > super_shift_factor ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setSubShiftFactor ( double __value )
{
this - > sub_shift_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getSubShiftFactor ( ) const
{
return this - > sub_shift_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setBraceShrinkFactor ( double __value )
{
this - > brace_shrink_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getBraceShrinkFactor ( ) const
{
return this - > brace_shrink_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setUnderbraceFactor ( double __value )
{
this - > underbrace_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getUnderbraceFactor ( ) const
{
return this - > underbrace_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setUndersetFactor ( double __value )
{
this - > undersetFactor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getUndersetFactor ( ) const
{
return this - > undersetFactor ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setFracFactor ( double __value )
2019-01-26 19:28:44 +08:00
{
2019-06-30 23:34:41 +08:00
this - > frac_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getFracFactor ( ) const
2019-01-26 19:28:44 +08:00
{
2019-06-30 23:34:41 +08:00
return this - > frac_factor ;
2019-01-26 19:28:44 +08:00
}
2022-06-09 05:52:22 +08:00
void JKQTMathText : : setFracNestedFactor ( double __value )
{
frac_nested_factor = __value ;
}
double JKQTMathText : : getFracNestedFactor ( ) const
{
return frac_nested_factor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setFracShiftFactor ( double __value )
{
this - > frac_shift_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getFracShiftFactor ( ) const
{
return this - > frac_shift_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setBraceYShiftFactor ( double __value )
{
this - > brace_y_shift_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getBraceYShiftFactor ( ) const
{
return this - > brace_y_shift_factor ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setDecorationHeightFactor ( double __value )
{
this - > decoration_height_factor = __value ;
2019-05-06 01:31:20 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getDecorationHeightFactor ( ) const
2019-02-08 00:24:46 +08:00
{
2019-06-30 23:34:41 +08:00
return this - > decoration_height_factor ;
2019-02-08 00:24:46 +08:00
}
2022-06-07 05:24:05 +08:00
void JKQTMathText : : setDecorationWidthReductionXFactor ( double __value )
{
decoration_width_reduction_Xfactor = __value ;
}
double JKQTMathText : : getDecorationWidthReductionXFactor ( ) const
{
return decoration_width_reduction_Xfactor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setExpensiveRendering ( bool __value )
{
this - > expensiveRendering = __value ;
}
2019-02-08 00:24:46 +08:00
2019-06-30 23:34:41 +08:00
bool JKQTMathText : : getExpensiveRendering ( ) const
{
return this - > expensiveRendering ;
}
void JKQTMathText : : setUseUnparsed ( bool __value )
{
this - > useUnparsed = __value ;
}
bool JKQTMathText : : isUsingUnparsed ( ) const
{
return this - > useUnparsed ;
}
QStringList JKQTMathText : : getErrorList ( ) const {
return this - > error_list ;
2019-01-26 19:28:44 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : addToErrorList ( const QString & error )
{
error_list . append ( error ) ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
2019-01-26 19:28:44 +08:00
JKQTMathText : : tokenType JKQTMathText : : getToken ( ) {
currentTokenID + + ;
if ( currentTokenID > parseString . size ( ) - 1 ) return currentToken = MTTnone ;
QChar c = parseString [ currentTokenID ] ;
currentTokenName = " " ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// define some static sets for easy character lookup/identificattion
static QSet < QChar > TokenCharacters ;
static QSet < QChar > mathEnvironmentSpecialChars , mathEnvironmentSpecialEndChars ;
static QSet < QChar > SingleCharInstructions ;
if ( TokenCharacters . size ( ) = = 0 ) {
mathEnvironmentSpecialChars < < ' ( ' < < ' [ ' < < ' | ' < < ' ) ' < < ' ] ' < < ' + ' < < ' - ' < < ' * ' < < ' / ' < < ' < ' < < ' > ' < < ' = ' ;
mathEnvironmentSpecialEndChars < < ' ( ' < < ' & ' < < ' [ ' < < ' | ' < < ' ) ' < < ' ] ' < < ' \\ ' < < ' $ ' < < ' { ' < < ' } ' < < ' _ ' < < ' ^ ' < < ' + ' < < ' - ' < < ' / ' < < ' * ' < < ' = ' < < ' < ' < < ' > ' ;
TokenCharacters < < ' _ ' < < ' ^ ' < < ' \\ ' < < ' $ ' < < ' & ' < < ' } ' < < ' { ' < < ' [ ' < < ' ] ' ;
SingleCharInstructions < < ' | ' < < ' ; ' < < ' : ' < < ' ! ' < < ' , ' < < ' _ ' < < ' \\ ' < < ' $ ' < < ' % ' < < ' & ' < < ' # ' < < ' } ' < < ' { ' < < ' ' < < ' [ ' < < ' ] ' ;
}
//----------------------------------------------------------
// read an instruction name
if ( c = = ' \\ ' ) {
2019-01-26 19:28:44 +08:00
currentTokenID + + ;
if ( currentTokenID > = parseString . size ( ) - 1 ) return currentToken = MTTnone ;
c = parseString [ currentTokenID ] ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// parsing single-character instruction
if ( SingleCharInstructions . contains ( c ) ) {
2019-01-26 19:28:44 +08:00
currentTokenName = c ; // parse one-symbol instructions like \\, \& ...
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTinstruction ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// letter-only instruction name
} else {
2019-01-26 19:28:44 +08:00
while ( c . isLetter ( ) & & ( currentTokenID < parseString . size ( ) ) ) {
currentTokenName + = c ;
currentTokenID + + ;
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
}
if ( ! c . isLetter ( ) ) currentTokenID - - ;
currentTokenName = currentTokenName . trimmed ( ) ;
}
//std::cout<<"found instruction node '"<<currentTokenName.toStdString()<<"'\n";
2022-06-19 21:11:06 +08:00
if ( currentTokenName . size ( ) = = 0 ) error_list . append ( tr ( " error @ ch. %1: parser encountered empty istruction " ) . arg ( currentTokenID ) ) ;
2019-01-26 19:28:44 +08:00
return currentToken = MTTinstruction ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for $ character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' $ ' ) {
//std::cout<<"found dollar\n";
return currentToken = MTTdollar ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for & character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' & ' ) {
//std::cout<<"found ampersand\n";
return currentToken = MTTampersand ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for { character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' { ' ) {
//std::cout<<"found openbrace\n";
return currentToken = MTTopenbrace ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for } character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' } ' ) {
//std::cout<<"found closebrace\n";
return currentToken = MTTclosebrace ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for [ character
} else if ( c = = ' [ ' ) {
//std::cout<<"found openbracket\n";
return currentToken = MTTopenbracket ;
//----------------------------------------------------------
// check for ] character
} else if ( c = = ' ] ' ) {
//std::cout<<"found closebracket\n";
return currentToken = MTTclosebracket ;
//----------------------------------------------------------
// check for _ character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' _ ' ) {
//std::cout<<"found underscore\n";
return currentToken = MTTunderscore ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for ^ character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' ^ ' ) {
//std::cout<<"found hat\n";
return currentToken = MTThat ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for whitespace character
2019-01-26 19:28:44 +08:00
} else if ( c . isSpace ( ) ) {
while ( c . isSpace ( ) & & ( currentTokenID < parseString . size ( ) ) ) { // eat up whitespace
currentTokenID + + ;
2022-06-19 21:11:06 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
2019-01-26 19:28:44 +08:00
}
if ( ! c . isSpace ( ) ) currentTokenID - - ;
//std::cout<<"found whitespace\n";
return currentToken = MTTwhitespace ;
} else {
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// no instruction or special character => parse text
2019-01-26 19:28:44 +08:00
if ( parsingMathEnvironment ) {
// inside math environments we split texts at every brace {[(|)]} so that
2022-06-08 21:38:26 +08:00
// braces form their own JKQTMathTextTextNode and may be formated accordingly
2022-06-03 19:33:18 +08:00
if ( mathEnvironmentSpecialChars . contains ( c ) ) {
2019-01-26 19:28:44 +08:00
currentTokenName = c ;
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTtext ;
}
2022-06-03 19:33:18 +08:00
while ( ! mathEnvironmentSpecialEndChars . contains ( c ) & & ( currentTokenID < parseString . size ( ) ) ) {
2019-01-26 19:28:44 +08:00
// add whitespaces only once
if ( c . isSpace ( ) ) {
if ( ! currentTokenName . isEmpty ( ) ) {
if ( ! currentTokenName [ currentTokenName . size ( ) - 1 ] . isSpace ( ) )
currentTokenName + = c ;
}
} else currentTokenName + = c ;
currentTokenID + + ;
2022-06-19 21:11:06 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
2019-01-26 19:28:44 +08:00
}
2022-06-03 19:33:18 +08:00
if ( mathEnvironmentSpecialEndChars . contains ( c ) | | c . isSpace ( ) ) currentTokenID - - ;
2019-01-26 19:28:44 +08:00
//currentTokenName=currentTokenName.trimmed();
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTtext ;
} else {
2022-06-19 21:11:06 +08:00
while ( ( ! c . isSpace ( ) ) & & ! TokenCharacters . contains ( c ) & & ( currentTokenID < parseString . size ( ) ) ) {
2019-01-26 19:28:44 +08:00
// add whitespaces only once
if ( c . isSpace ( ) ) {
if ( ! currentTokenName . isEmpty ( ) ) {
if ( ! currentTokenName [ currentTokenName . size ( ) - 1 ] . isSpace ( ) )
currentTokenName + = c ;
}
} else currentTokenName + = c ;
currentTokenID + + ;
2022-06-19 21:11:06 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
if ( TokenCharacters . contains ( c ) | | c . isSpace ( ) ) currentTokenID - - ;
2019-01-26 19:28:44 +08:00
//currentTokenName=currentTokenName.trimmed();
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTtext ;
}
}
return currentToken = MTTnone ;
}
2022-06-19 21:11:06 +08:00
JKQTMathTextNode * JKQTMathText : : parseLatexString ( bool get , JKQTMathTextBraceType quitOnClosingBrace , const QString & quitOnEnvironmentEnd , bool quitOnClosingBracket ) {
2019-01-26 19:28:44 +08:00
//std::cout<<" entering parseLatexString()\n";
2022-06-08 21:38:26 +08:00
JKQTMathTextListNode * nl = new JKQTMathTextListNode ( this ) ;
2019-01-26 19:28:44 +08:00
if ( get ) getToken ( ) ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// initialize some static sets for easy and fast character lookup
static QSet < QString > mathEnvironmentSpecialText ;
if ( mathEnvironmentSpecialText . size ( ) = = 0 ) {
mathEnvironmentSpecialText < < " + " < < " - " < < " = " < < " * " < < " < " < < " > " < < " | " < < " / " ;
}
2019-01-26 19:28:44 +08:00
bool getNew = true ;
while ( currentToken ! = MTTnone ) {
getNew = true ;
if ( currentToken = = MTTtext ) {
QString text = currentTokenName ;
bool addWhite = ( getToken ( ) = = MTTwhitespace ) & & ( ! parsingMathEnvironment ) ;
getNew = addWhite ;
2022-06-03 19:33:18 +08:00
if ( parsingMathEnvironment ) {
if ( mathEnvironmentSpecialText . contains ( text . trimmed ( ) ) ) {
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextSymbolNode ( this , text , addWhite ) ) ;
2022-06-03 19:33:18 +08:00
} else {
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextTextNode ( this , text , addWhite , parsingMathEnvironment ) ) ;
2022-06-03 19:33:18 +08:00
}
} else {
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextTextNode ( this , text , addWhite , parsingMathEnvironment ) ) ;
2022-06-03 19:33:18 +08:00
}
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTinstruction ) {
2022-06-19 21:11:06 +08:00
const QString currentInstructionName = currentTokenName ;
if ( currentInstructionName = = " \\ " ) break ; // break on linebrak character
2019-01-26 19:28:44 +08:00
getToken ( ) ; // look at next token
if ( currentToken = = MTTopenbrace ) {
//std::cout<<"found '{' after '"<<name.toStdString()<<"'\n";
2022-06-19 21:11:06 +08:00
if ( currentInstructionName = = " sqrt " ) {
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextSqrtNode ( this , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " cbrt " ) {
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextSqrtNode ( this , parseLatexString ( true ) , 3 ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " verb " ) {
2019-01-26 19:28:44 +08:00
QString text = " " ;
currentTokenID + + ;
if ( currentTokenID < = parseString . size ( ) - 1 ) {
QChar c = parseString [ currentTokenID ] ;
while ( c ! = ' } ' & & ( currentTokenID < parseString . size ( ) ) ) {
text = text + c ;
currentTokenID + + ;
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
}
2022-06-19 21:11:06 +08:00
if ( c ! = ' } ' ) error_list . append ( tr ( " error @ ch. %1: \v erb{...} not closed by '}' " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextTextNode ( this , text , false ) ) ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " frac " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMfrac ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " dfrac " | | currentInstructionName = = " cfrac " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMdfrac ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " sfrac " | | currentInstructionName = = " slantfrac " | | currentInstructionName = = " xfrac " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-05-18 17:41:17 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMsfrac ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " stfrac " | | currentInstructionName = = " nicefrac " | | currentInstructionName = = " slanttextfrac " | | currentInstructionName = = " xtfrac " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-05-18 17:41:17 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMstfrac ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " tfrac " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMtfrac ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " stackrel " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMstackrel ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " binom " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-19 21:11:06 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTParenthesis , MTBTParenthesis , new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMstackrel ) ) ) ;
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " underbrace " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMunderbrace ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " underset " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMunderset ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " overbrace " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMoverbrace ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " overset " ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
2022-06-10 02:32:16 +08:00
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMoverset ) ) ;
2022-06-19 21:11:06 +08:00
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else if ( currentInstructionName = = " begin " ) {
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTtext ) {
QString envname = currentTokenName ;
while ( currentToken ! = MTTclosebrace ) getToken ( ) ; // find closing brace '}' after '\\begin{name'
if ( envname = = " matrix " | | envname = = " array " | | envname = = " aligned " | | envname = = " align " | | envname = = " cases " | | envname = = " pmatrix " | | envname = = " bmatrix " | | envname = = " Bmatrix " | | envname = = " vmatrix " | | envname = = " Vmatrix " ) {
2022-06-08 21:38:26 +08:00
QVector < QVector < JKQTMathTextNode * > > items ;
2019-01-26 19:28:44 +08:00
//int lines=0;
//int cols=0;
bool first = true ;
2022-06-08 21:38:26 +08:00
QVector < JKQTMathTextNode * > line ;
2019-01-26 19:28:44 +08:00
//std::cout<<"found \\begin{matrix}\n";
while ( first | | currentToken = = MTTampersand | | ( currentToken = = MTTinstruction & & currentTokenName = = " \\ " ) ) {
2022-06-19 21:11:06 +08:00
JKQTMathTextNode * it = parseLatexString ( true , MTBTAny , envname ) ;
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTampersand ) {
//std::cout<<" appending item\n";
line . append ( it ) ;
} else {
line . append ( it ) ;
//std::cout<<" appending item and line with "<<line.size()<<" items.\n";
items . append ( line ) ;
line . clear ( ) ;
}
first = false ;
}
//std::cout<<" creating matrix-node with "<<items.size()<<" items.\n";
2022-06-19 21:11:06 +08:00
if ( envname = = " pmatrix " ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTParenthesis , MTBTParenthesis , new JKQTMathTextMatrixNode ( this , items ) ) ) ;
else if ( envname = = " cases " ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTCurlyBracket , MTBTNone , new JKQTMathTextMatrixNode ( this , items ) ) ) ;
else if ( envname = = " bmatrix " ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTSquareBracket , MTBTSquareBracket , new JKQTMathTextMatrixNode ( this , items ) ) ) ;
else if ( envname = = " Bmatrix " ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTCurlyBracket , MTBTCurlyBracket , new JKQTMathTextMatrixNode ( this , items ) ) ) ;
else if ( envname = = " vmatrix " ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTSingleLine , MTBTSingleLine , new JKQTMathTextMatrixNode ( this , items ) ) ) ;
else if ( envname = = " Vmatrix " ) nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTDoubleLine , MTBTDoubleLine , new JKQTMathTextMatrixNode ( this , items ) ) ) ;
2022-06-08 21:38:26 +08:00
else nl - > addNode ( new JKQTMathTextMatrixNode ( this , items ) ) ;
2019-01-26 19:28:44 +08:00
//std::cout<<" creating matrix-node ... done!\n";
} else {
error_list . append ( tr ( " error @ ch. %1: unknown environment '%2' " ) . arg ( currentTokenID ) . arg ( envname ) ) ;
}
} else { // find next '}'
error_list . append ( tr ( " error @ ch. %1: text after ' \\ begin{' expected! " ) . arg ( currentTokenID ) ) ;
while ( currentToken ! = MTTclosebrace ) getToken ( ) ;
getNew = true ;
}
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " end " ) {
2019-01-26 19:28:44 +08:00
if ( getToken ( ) = = MTTtext ) {
QString envname = currentTokenName ;
while ( currentToken ! = MTTclosebrace ) getToken ( ) ; // find closing brace '}' after '\\begin{name'
if ( envname = = quitOnEnvironmentEnd ) {
break ;
} else {
error_list . append ( tr ( " error @ ch. %1: ' \\ end{%2}' widthout preceding ' \\ begin{%3}' " ) . arg ( currentTokenID ) . arg ( envname ) . arg ( envname ) ) ;
}
} else { // find next '}'
error_list . append ( tr ( " error @ ch. %1: text after ' \\ begin{' expected! " ) . arg ( currentTokenID ) ) ;
while ( currentToken ! = MTTclosebrace ) getToken ( ) ;
getNew = true ;
}
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " vec " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDvec , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " overline " | | currentInstructionName = = " oline " | | currentInstructionName = = " ol " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDoverline , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " underline " | | currentInstructionName = = " uline " | | currentInstructionName = = " ul " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDunderline , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " uuline " | | currentInstructionName = = " uul " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDdoubleunderline , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " ooline " | | currentInstructionName = = " ool " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDdoubleoverline , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " arrow " | | currentInstructionName = = " overrightarrow " | | currentInstructionName = = " overarrow " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDarrow , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " hat " | | currentInstructionName = = " ^ " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDhat , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " widehat " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDwidehat , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " check " | | currentInstructionName = = " v " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDcheck , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " widecheck " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDwidecheck , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " bar " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDbar , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " dot " | | currentInstructionName = = " . " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDdot , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " ocirc " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDocirc , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " tilde " | | currentInstructionName = = " ~ " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDtilde , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " breve " | | currentInstructionName = = " u " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDbreve , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " widetilde " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDwidetilde , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " ddot " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDddot , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " cancel " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDcancel , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " xcancel " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDxcancel , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " bcancel " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDbcancel , parseLatexString ( true ) ) ) ;
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " strike " | | currentInstructionName = = " st " | | currentInstructionName = = " sout " ) {
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDstrike , parseLatexString ( true ) ) ) ;
2019-01-26 19:28:44 +08:00
} else {
2022-06-19 21:11:06 +08:00
if ( currentInstructionName = = " textcolor " | | currentInstructionName = = " mathcolor " | | currentInstructionName = = " color " | | currentInstructionName = = " colorbox " ) {
2019-01-26 19:28:44 +08:00
bool foundError = true ;
QString col = " " ;
if ( getToken ( ) = = MTTtext ) {
col = currentTokenName ;
if ( getToken ( ) = = MTTclosebrace ) {
if ( getToken ( ) = = MTTopenbrace ) {
foundError = false ;
}
}
}
2022-06-19 21:11:06 +08:00
if ( foundError ) error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
else nl - > addNode ( new JKQTMathTextInstruction1Node ( this , currentInstructionName , parseLatexString ( true ) , QStringList ( col ) ) ) ;
2019-01-26 19:28:44 +08:00
} else {
2022-06-19 21:11:06 +08:00
nl - > addNode ( new JKQTMathTextInstruction1Node ( this , currentInstructionName , parseLatexString ( true ) ) ) ;
}
}
} else if ( currentToken = = MTTopenbracket & & currentInstructionName ! = " left " ) {
//std::cout<<"found '[' after '"<<name.toStdString()<<"'\n";
if ( currentInstructionName = = " sqrt " ) {
JKQTMathTextNode * n1 = parseLatexString ( true , MTBTAny , " " , true ) ;
JKQTMathTextListNode * n1lst = dynamic_cast < JKQTMathTextListNode * > ( n1 ) ;
JKQTMathTextTextNode * n1txt = dynamic_cast < JKQTMathTextTextNode * > ( n1 ) ;
if ( n1lst & & n1lst - > count ( ) = = 1 ) {
n1txt = dynamic_cast < JKQTMathTextTextNode * > ( n1lst - > child ( 0 ) ) ;
}
int degree = 2 ;
bool ok = false ;
if ( n1txt ) degree = n1txt - > getText ( ) . toInt ( & ok ) ;
if ( ! ok ) {
degree = 2 ;
error_list . append ( tr ( " error @ ch. %1: an integer in [] after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
JKQTMathTextNode * n2 = nullptr ;
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
else error_list . append ( tr ( " error @ ch. %1: expected one argument in '{' braces after '%2' command with an optional argument in [] " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
if ( n1 & & n2 ) nl - > addNode ( new JKQTMathTextSqrtNode ( this , n2 , degree ) ) ;
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else {
nl - > addNode ( new JKQTMathTextTextNode ( this , " [ " , false ) ) ;
2019-01-26 19:28:44 +08:00
}
} else {
//std::cout<<"did not find '{' after '"<<name.toStdString()<<"'\n";
2022-06-19 21:11:06 +08:00
if ( currentInstructionName = = " right " ) {
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) > 0 ) {
2022-06-19 21:11:06 +08:00
bool tokenWasNoBrace = false ;
if ( TokenNameMatchesJKQTMathTextBraceType ( currentTokenName [ 0 ] , quitOnClosingBrace , true , & tokenWasNoBrace ) ) {
2019-01-26 19:28:44 +08:00
//std::cout<<"found \\right '"<<currentTokenName.toStdString()<<"'\n";
2022-06-19 21:11:06 +08:00
showLeftBrace = ( quitOnClosingBrace = = MTBTAny | | quitOnClosingBrace ! = MTBTNone ) ;
showRightBrace = ! tokenWasNoBrace ;
2019-01-26 19:28:44 +08:00
//if (!showRightBrace) std::cout<<"don't show right brace '"<<quitOnClosingBrace.toStdString()<<"' !!!\n";
2022-06-19 21:11:06 +08:00
if ( quitOnClosingBrace ! = MTBTAny ) currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ;
2019-01-26 19:28:44 +08:00
break ;
} else {
getNew = false ;
}
}
} else if ( currentToken = = MTTinstruction ) {
2022-06-19 21:11:06 +08:00
if ( InstructionNameMatchesJKQTMathTextBraceType ( currentTokenName , quitOnClosingBrace , true ) ) {
currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ;
break ;
}
} else if ( currentToken = = MTTclosebracket ) {
if ( quitOnClosingBrace = = MTBTSquareBracket | | quitOnClosingBrace = = MTBTAny ) {
currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ;
break ;
2019-01-26 19:28:44 +08:00
}
} else {
getNew = false ;
}
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName = = " left " ) {
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) > 0 ) {
2022-06-19 21:11:06 +08:00
const JKQTMathTextBraceType bracetype = TokenName2JKQTMathTextBraceType ( currentTokenName [ 0 ] ) ;
if ( bracetype = = MTBTNone ) {
2019-01-26 19:28:44 +08:00
currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ;
2022-06-19 21:11:06 +08:00
JKQTMathTextNode * cn = parseLatexString ( currentTokenName . size ( ) < = 0 , MTBTAny ) ;
nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTNone , bracetype , cn ) ) ;
} else if ( isPrintableJKQTMathTextBraceType ( bracetype ) ) {
currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ; // we already used the first character from the text token!
nl - > addNode ( new JKQTMathTextBraceNode ( this , bracetype , bracetype , parseLatexString ( currentTokenName . size ( ) < = 0 , bracetype ) ) ) ;
2019-01-26 19:28:44 +08:00
} else {
getNew = false ;
}
}
2022-06-19 21:11:06 +08:00
} else if ( currentToken = = MTTinstruction ) {
const JKQTMathTextBraceType bracetypeopening = InstructionName2OpeningJKQTMathTextBraceType ( currentTokenName ) ;
if ( bracetypeopening ! = MTBTUnknown ) {
nl - > addNode ( new JKQTMathTextBraceNode ( this , bracetypeopening , bracetypeopening , parseLatexString ( true , bracetypeopening ) ) ) ;
} else if ( currentToken = = MTTinstruction & & TokenNameMatchesJKQTMathTextBraceType ( currentTokenName , quitOnClosingBrace , true ) ) {
break ;
}
} else if ( currentToken = = MTTopenbracket ) {
nl - > addNode ( new JKQTMathTextBraceNode ( this , MTBTSquareBracket , MTBTSquareBracket , parseLatexString ( true , MTBTSquareBracket ) ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: unexpected token after \\ left " ) . arg ( currentTokenID ) ) ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
2019-01-26 19:28:44 +08:00
} else {
//bool addWhite=(currentToken==MTTwhitespace);
//getNew=addWhite;
getNew = false ;
bool done = false ;
2022-06-19 21:11:06 +08:00
if ( currentInstructionName . size ( ) = = 2 ) {
QChar n0 = currentInstructionName [ 0 ] ;
QChar n1 = currentInstructionName [ 1 ] ;
2019-01-26 19:28:44 +08:00
if ( n0 = = ' v ' & & n1 . isLetter ( ) ) {
done = true ;
//std::cout<<"found \\v... command\n";
2022-06-10 02:32:16 +08:00
nl - > addNode ( new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : MTDvec , new JKQTMathTextTextNode ( this , QString ( n1 ) , false , parsingMathEnvironment ) ) ) ;
2019-01-26 19:28:44 +08:00
} else if ( n0 = = ' c ' & & n1 . isLetter ( ) ) {
done = true ;
//std::cout<<"found \\v... command\n";
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextInstruction1Node ( this , " mathcal " , new JKQTMathTextTextNode ( this , QString ( n1 ) , false , parsingMathEnvironment ) ) ) ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
} else if ( currentInstructionName . size ( ) = = 3 ) {
QString n0 = currentInstructionName . left ( 2 ) ;
QChar n1 = currentInstructionName [ currentInstructionName . size ( ) - 1 ] ;
2019-01-26 19:28:44 +08:00
if ( n0 = = " bb " & & n1 . isLetter ( ) ) {
done = true ;
//std::cout<<"found \\v... command\n";
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextInstruction1Node ( this , " mathbb " , new JKQTMathTextTextNode ( this , QString ( n1 ) , false , parsingMathEnvironment ) ) ) ;
2019-01-26 19:28:44 +08:00
}
}
2022-06-19 21:11:06 +08:00
if ( ! done ) nl - > addNode ( new JKQTMathTextSymbolNode ( this , currentInstructionName , false ) ) ; //, addWhite));
2019-01-26 19:28:44 +08:00
}
}
} else if ( currentToken = = MTTwhitespace ) {
2022-06-08 21:38:26 +08:00
if ( ! parsingMathEnvironment ) nl - > addNode ( new JKQTMathTextWhitespaceNode ( this ) ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTunderscore ) {
getToken ( ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * child = nullptr ;
JKQTMathTextNode * child2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTinstruction ) {
QString name = currentTokenName ;
getToken ( ) ; // look at next token
if ( currentToken = = MTTopenbrace ) {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextInstruction1Node ( this , name , parseLatexString ( true ) ) ;
2019-01-26 19:28:44 +08:00
} else {
//bool addWhite=(currentToken==MTTwhitespace);
//getNew=addWhite;
2022-06-08 21:38:26 +08:00
//child=new JKQTMathTextSymbolNode(this, name, addWhite);
2019-01-26 19:28:44 +08:00
getNew = false ;
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextSymbolNode ( this , name , false ) ;
2019-01-26 19:28:44 +08:00
}
} else if ( currentToken = = MTTopenbrace ) {
child = parseLatexString ( true ) ;
} else if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) < = 1 ) {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , currentTokenName , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
} else {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , QString ( currentTokenName [ 0 ] ) , false , parsingMathEnvironment ) ;
child2 = new JKQTMathTextTextNode ( this , currentTokenName . right ( currentTokenName . size ( ) - 1 ) , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
}
} else {
getNew = false ;
}
2022-06-08 21:38:26 +08:00
if ( child ! = nullptr ) nl - > addNode ( new JKQTMathTextSubscriptNode ( this , child ) ) ;
2019-01-26 19:28:44 +08:00
if ( child2 ! = nullptr ) nl - > addNode ( child2 ) ;
} else if ( currentToken = = MTThat ) {
getToken ( ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * child = nullptr ;
JKQTMathTextNode * child2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTinstruction ) {
QString name = currentTokenName ;
getToken ( ) ; // look at next token
if ( currentToken = = MTTopenbrace ) {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextInstruction1Node ( this , name , parseLatexString ( true ) ) ;
2019-01-26 19:28:44 +08:00
} else {
//bool addWhite=(currentToken==MTTwhitespace);
//getNew=addWhite;
2022-06-08 21:38:26 +08:00
//child=new JKQTMathTextSymbolNode(this, name, addWhite);
2019-01-26 19:28:44 +08:00
getNew = false ;
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextSymbolNode ( this , name , false ) ;
2019-01-26 19:28:44 +08:00
}
} else if ( currentToken = = MTTopenbrace ) {
child = parseLatexString ( true ) ;
} else if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) < = 1 ) {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , currentTokenName , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
} else {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , QString ( currentTokenName [ 0 ] ) , false , parsingMathEnvironment ) ;
child2 = new JKQTMathTextTextNode ( this , currentTokenName . right ( currentTokenName . size ( ) - 1 ) , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
}
} else {
getNew = false ;
}
2022-06-08 21:38:26 +08:00
if ( child ! = nullptr ) nl - > addNode ( new JKQTMathTextSuperscriptNode ( this , child ) ) ;
2019-01-26 19:28:44 +08:00
if ( child2 ! = nullptr ) nl - > addNode ( child2 ) ;
} else if ( currentToken = = MTTopenbrace ) {
nl - > addNode ( parseLatexString ( true ) ) ;
} else if ( currentToken = = MTTclosebrace ) {
break ;
2022-06-19 21:11:06 +08:00
} else if ( currentToken = = MTTopenbracket ) {
nl - > addNode ( new JKQTMathTextTextNode ( this , " [ " , false ) ) ;
} else if ( currentToken = = MTTclosebracket ) {
if ( quitOnClosingBracket ) break ;
else nl - > addNode ( new JKQTMathTextTextNode ( this , " ] " , false ) ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTampersand ) {
break ;
} else if ( currentToken = = MTTdollar ) {
if ( parsingMathEnvironment ) { // reached end of math environment
parsingMathEnvironment = false ;
break ;
} else { // starting math environment
parsingMathEnvironment = true ;
2022-06-08 21:38:26 +08:00
nl - > addNode ( new JKQTMathTextInstruction1Node ( this , " equation " , parseLatexString ( true ) ) ) ;
2019-01-26 19:28:44 +08:00
}
}
if ( getNew ) getToken ( ) ;
}
//std::cout<<" leaving parseLatexString()\n";
2022-06-19 21:11:06 +08:00
return JKQTMathTextListNode : : simplyfyListNode ( nl ) ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * JKQTMathText : : getParsedNode ( ) const {
2019-06-30 23:34:41 +08:00
return this - > parsedNode ;
}
2019-01-26 19:28:44 +08:00
2022-06-03 05:24:41 +08:00
bool JKQTMathText : : parse ( const QString & text , bool addSpaceBeforeAndAfter ) {
QString ntext ;
if ( addSpaceBeforeAndAfter ) ntext = QString ( " \\ ; " ) + text + QString ( " \\ ; " ) ;
else ntext = text ;
2019-01-26 19:28:44 +08:00
ntext = ntext . remove ( " \\ limits " ) ;
if ( parsedNode & & parseString = = ntext ) return true ;
if ( parsedNode ! = nullptr ) delete parsedNode ;
if ( unparsedNode ! = nullptr ) delete unparsedNode ;
parseString = ntext ;
currentTokenID = - 1 ;
currentToken = MTTnone ;
currentTokenName = " " ;
parsingMathEnvironment = false ;
error_list . clear ( ) ;
parsedNode = parseLatexString ( true ) ;
unparsedNode = new MTplainTextNode ( this , text , false ) ;
return ( parsedNode ! = nullptr ) ;
}
QSizeF JKQTMathText : : getSize ( QPainter & painter ) {
if ( getTree ( ) ! = nullptr ) {
double w = 0 , a = 0 , d = 0 , s = 0 ;
getSizeDetail ( painter , w , a , d , s ) ;
return QSizeF ( w , a + d ) ;
}
return QSizeF ( 0 , 0 ) ;
}
double JKQTMathText : : getDescent ( QPainter & painter ) {
double w = 0 , a = 0 , d = 0 , s = 0 ;
getSizeDetail ( painter , w , a , d , s ) ;
return d ;
}
double JKQTMathText : : getAscent ( QPainter & painter ) {
double w = 0 , a = 0 , d = 0 , s = 0 ;
getSizeDetail ( painter , w , a , d , s ) ;
return a ;
}
void JKQTMathText : : getSizeDetail ( QPainter & painter , double & width , double & ascent , double & descent , double & strikeoutPos ) {
width = 0 ;
ascent = 0 ;
descent = 0 ;
strikeoutPos = 0 ;
if ( getTree ( ) ! = nullptr ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-01-26 19:28:44 +08:00
ev . color = fontColor ;
ev . fontSize = fontSize ;
double overallHeight = 0 ;
getTree ( ) - > 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 ;
}
}
void JKQTMathText : : draw ( QPainter & painter , double x , double y , bool drawBoxes ) {
if ( getTree ( ) ! = nullptr ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-01-26 19:28:44 +08:00
ev . color = fontColor ;
ev . fontSize = fontSize ;
2019-05-06 01:31:20 +08:00
QPen pp = painter . pen ( ) ;
QPen p = pp ;
p . setStyle ( Qt : : SolidLine ) ;
painter . setPen ( p ) ;
2019-01-26 20:00:40 +08:00
getTree ( ) - > setDrawBoxes ( drawBoxes ) ;
2019-05-06 01:31:20 +08:00
painter . setPen ( p ) ;
2019-01-26 19:28:44 +08:00
getTree ( ) - > draw ( painter , x , y , ev ) ;
2019-05-06 01:31:20 +08:00
painter . setPen ( pp ) ;
2019-01-26 19:28:44 +08:00
}
}
2019-05-01 20:58:19 +08:00
void JKQTMathText : : draw ( QPainter & painter , unsigned int flags , QRectF rect , bool drawBoxes ) {
2019-01-26 19:28:44 +08:00
if ( getTree ( ) ! = nullptr ) {
2019-05-06 01:31:20 +08:00
QPen pp = painter . pen ( ) ;
QPen p = pp ;
p . setStyle ( Qt : : SolidLine ) ;
painter . setPen ( p ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-01-26 19:28:44 +08:00
ev . color = fontColor ;
ev . fontSize = fontSize ;
2019-01-26 20:00:40 +08:00
getTree ( ) - > setDrawBoxes ( drawBoxes ) ;
2019-05-06 01:31:20 +08:00
painter . setPen ( p ) ;
2019-01-26 19:28:44 +08:00
double width = 0 ;
double baselineHeight = 0 ;
double overallHeight = 0 , strikeoutPos = 0 ;
getTree ( ) - > getSize ( painter , ev , width , baselineHeight , overallHeight , strikeoutPos ) ;
// align left top
double x = rect . left ( ) ;
double y = rect . top ( ) + baselineHeight ;
// care for horizontal align
if ( ( flags & Qt : : AlignRight ) ! = 0 ) x = x + rect . width ( ) - width ;
else if ( ( flags & Qt : : AlignHCenter ) ! = 0 ) x = x + ( rect . width ( ) - width ) / 2.0 ;
// care for vertical align
if ( ( flags & Qt : : AlignBottom ) ! = 0 ) y = y + rect . height ( ) - overallHeight ;
else if ( ( flags & Qt : : AlignVCenter ) ! = 0 ) y = y + ( rect . height ( ) - overallHeight ) / 2.0 ;
// finally draw
getTree ( ) - > draw ( painter , x , y , ev ) ;
2019-05-06 01:31:20 +08:00
painter . setPen ( pp ) ;
2019-01-26 19:28:44 +08:00
}
}
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * JKQTMathText : : getTree ( ) const {
2019-06-30 23:34:41 +08:00
if ( useUnparsed ) return unparsedNode ;
return parsedNode ;
}
2022-06-03 03:02:23 +08:00