IMPROVEMENT: JKQTMathText: added x-correction for sub/superscript above/below/besides integrals

This commit is contained in:
jkriege2 2022-06-27 22:57:49 +02:00
parent b6dc081d0c
commit fc557c9aff
6 changed files with 182 additions and 24 deletions

View File

@ -37,6 +37,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>IMPROVED: typesetting of sub-/supercripts, especially for large math operators and braces</li> <li>IMPROVED: typesetting of sub-/supercripts, especially for large math operators and braces</li>
<li>MODIFIED: brace node now calculates the extension of the child height above or below the strikeoutPos, in order to center braces around the strikeoutPos</li> <li>MODIFIED: brace node now calculates the extension of the child height above or below the strikeoutPos, in order to center braces around the strikeoutPos</li>
<li>IMPROVED: improved drawing of parantheses, square brackets ... , underbrace/overbrace</li> <li>IMPROVED: improved drawing of parantheses, square brackets ... , underbrace/overbrace</li>
<li>IMPROVED: added x-correction for sub/superscript above/below/besides integrals</li>
<li>remove/breaking: \v[a-zA-Z] and shorthand for \vec{a-zA-Z} was removed, implementation of \bbR,\bbC,... changed</li> <li>remove/breaking: \v[a-zA-Z] and shorthand for \vec{a-zA-Z} was removed, implementation of \bbR,\bbC,... changed</li>
<li>NEW: now supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve</li> <li>NEW: now supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve</li>
<li>NEW: reworked drawing of decorations: improved appearance and positioning!</li> <li>NEW: reworked drawing of decorations: improved appearance and positioning!</li>

View File

@ -87,6 +87,8 @@ JKQTMathText::JKQTMathText(QObject* parent):
operatorsubsuper_size_factor=0.65; operatorsubsuper_size_factor=0.65;
operatorsubsuper_distance_factor=0.25; operatorsubsuper_distance_factor=0.25;
operatorsubsuper_extraspace_factor=0.5; operatorsubsuper_extraspace_factor=0.5;
intsubsuper_xcorrection_factor=0.25;
intsubbesides_xcorrection_xfactor=0.33;
mathoperator_width_factor=1.5; mathoperator_width_factor=1.5;
bigmathoperator_font_factor=1.8; bigmathoperator_font_factor=1.8;
@ -230,6 +232,8 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group)
operatorsubsuper_distance_factor=settings.value(group+"operatorsubsuper_distance_factor", operatorsubsuper_distance_factor).toDouble(); operatorsubsuper_distance_factor=settings.value(group+"operatorsubsuper_distance_factor", operatorsubsuper_distance_factor).toDouble();
operatorsubsuper_extraspace_factor=settings.value(group+"operatorsubsuper_extraspace_factor", operatorsubsuper_extraspace_factor).toDouble(); operatorsubsuper_extraspace_factor=settings.value(group+"operatorsubsuper_extraspace_factor", operatorsubsuper_extraspace_factor).toDouble();
mathoperator_width_factor=settings.value(group+"mathoperator_width_factor", mathoperator_width_factor).toDouble(); mathoperator_width_factor=settings.value(group+"mathoperator_width_factor", mathoperator_width_factor).toDouble();
intsubsuper_xcorrection_factor=settings.value(group+"intsubsuper_xcorrection_factor", intsubsuper_xcorrection_factor).toDouble();
intsubbesides_xcorrection_xfactor=settings.value(group+"intsubbesides_xcorrection_xfactor", intsubbesides_xcorrection_xfactor).toDouble();
if (settings.value(group+"use_stix_fonts", false).toBool()) useSTIX(); if (settings.value(group+"use_stix_fonts", false).toBool()) useSTIX();
@ -260,6 +264,8 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const
settings.setValue(group+ "operatorsubsuper_distance_factor", operatorsubsuper_distance_factor); settings.setValue(group+ "operatorsubsuper_distance_factor", operatorsubsuper_distance_factor);
settings.setValue(group+ "operatorsubsuper_extraspace_factor", operatorsubsuper_extraspace_factor); settings.setValue(group+ "operatorsubsuper_extraspace_factor", operatorsubsuper_extraspace_factor);
settings.setValue(group+ "mathoperator_width_factor", mathoperator_width_factor); settings.setValue(group+ "mathoperator_width_factor", mathoperator_width_factor);
settings.setValue(group+ "intsubsuper_xcorrection_factor", intsubsuper_xcorrection_factor);
settings.setValue(group+ "intsubbesides_xcorrection_xfactor", intsubbesides_xcorrection_xfactor);
settings.setValue(group+ "brace_y_shift_factor", brace_y_shift_factor); settings.setValue(group+ "brace_y_shift_factor", brace_y_shift_factor);
settings.setValue(group+ "decoration_height_factor", decoration_height_factor); settings.setValue(group+ "decoration_height_factor", decoration_height_factor);
settings.setValue(group+ "decoration_width_reduction_xfactor", decoration_width_reduction_Xfactor); settings.setValue(group+ "decoration_width_reduction_xfactor", decoration_width_reduction_Xfactor);
@ -722,6 +728,26 @@ double JKQTMathText::getMathoperatorWidthFactor() const
return this->mathoperator_width_factor; return this->mathoperator_width_factor;
} }
void JKQTMathText::setIntSubSuperXCorrectionFactor(double __value)
{
intsubsuper_xcorrection_factor=__value;
}
double JKQTMathText::getIntSubSuperXCorrectionFactor() const
{
return intsubsuper_xcorrection_factor;
}
void JKQTMathText::setIntSubBesidesXCorrectionXFactor(double __value)
{
intsubbesides_xcorrection_xfactor=__value;
}
double JKQTMathText::getIntSubBesidesXCorrectionXFactor() const
{
return intsubbesides_xcorrection_xfactor;
}
void JKQTMathText::setBigMathoperatorFontFactor(double __value) void JKQTMathText::setBigMathoperatorFontFactor(double __value)
{ {
bigmathoperator_font_factor=__value; bigmathoperator_font_factor=__value;

View File

@ -458,6 +458,14 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
void setMathoperatorWidthFactor(double __value); void setMathoperatorWidthFactor(double __value);
/** \copydoc mathoperator_width_factor */ /** \copydoc mathoperator_width_factor */
double getMathoperatorWidthFactor() const; double getMathoperatorWidthFactor() const;
/** \copydoc intsubsuper_xcorrection_factor */
void setIntSubSuperXCorrectionFactor(double __value);
/** \copydoc intsubsuper_xcorrection_factor */
double getIntSubSuperXCorrectionFactor() const;
/** \copydoc intsubbesides_xcorrection_xfactor */
void setIntSubBesidesXCorrectionXFactor(double __value);
/** \copydoc intsubbesides_xcorrection_xfactor */
double getIntSubBesidesXCorrectionXFactor() const;
/** \copydoc bigmathoperator_font_factor */ /** \copydoc bigmathoperator_font_factor */
void setBigMathoperatorFontFactor(double __value); void setBigMathoperatorFontFactor(double __value);
/** \copydoc bigmathoperator_font_factor */ /** \copydoc bigmathoperator_font_factor */
@ -592,6 +600,23 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
* \image html jkqtmathtext_subsuper_with_limits.png * \image html jkqtmathtext_subsuper_with_limits.png
*/ */
double operatorsubsuper_extraspace_factor; double operatorsubsuper_extraspace_factor;
/** \brief for integrals (\c \\int , \c \\oint , ...) the sub-/superscripts above/below the symbol have to be shifted a bit to the left/right to accomodate the shape of the operator symbol (i.e. some free space at the top-left and bottom-right)
*
* This factor is multiplied by the symbol width: xshift=intsubsuper_xcorrection_factor*symbolWidth
* Then the subscript below is placed at centerx(symbol)-xshift and the superscript at centerx(symbol)+shiftx.
* This is also used to correct a subset next to the symbol by shifting it to rightx(symbol)-xshift.
*
* This correction is applied to \\int, \\iint, \\iiint, \\oint, ...
*/
double intsubsuper_xcorrection_factor;
/** \brief for integrals (\c \\int , \c \\oint , ...) the subscripts besides the symbol have to be shifted to the left a bit to the left to accomodate the shape of the operator symbol (i.e. some free space at the bottom-right)
*
* This factor is multiplied by the width of an x: xshift=intsubbesides_xcorrection_xfactor*xWidth
* Then the subscript besides the symbol is shifted by xshift to the left
*
* This correction is applied to \\int, \\iint, \\iiint, \\oint, ...
*/
double intsubbesides_xcorrection_xfactor;
/** \brief factor, used to extend the size of an operator in math mode /** \brief factor, used to extend the size of an operator in math mode
* *
* The next image demonstrates the effect of this property, which adds extra space * The next image demonstrates the effect of this property, which adds extra space

View File

@ -72,9 +72,13 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
JKQTMathTextNodeSize prevNodeSize; JKQTMathTextNodeSize prevNodeSize;
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr; JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr; JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr;
double subSuperXCorrection=0;
double subBesidesXCorrection=0;
if (i>0) { if (i>0) {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i-1]);
if (symbN) symbN->getSymbolSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos, subSuperXCorrection, subBesidesXCorrection);
else nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos);
const double prevAscent=prevNodeSize.baselineHeight; const double prevAscent=prevNodeSize.baselineHeight;
const double prevDescent=prevNodeSize.overallHeight-prevNodeSize.baselineHeight; const double prevDescent=prevNodeSize.overallHeight-prevNodeSize.baselineHeight;
const bool shouldUseSpecialSubscriptMode=prevAscent>=subsuperSpecialModeAscent; const bool shouldUseSpecialSubscriptMode=prevAscent>=subsuperSpecialModeAscent;
@ -117,7 +121,7 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
overallHeight=baselineHeight+oh-bh; overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp; strikeoutPos=sp;
} }
xnew+=qMax(w1+spaceWidth, w2); xnew+=qMax(w1+spaceWidth, w2+subBesidesXCorrection);
doDraw=false; doDraw=false;
//qDebug()<<"### super+sub"; //qDebug()<<"### super+sub";
@ -150,13 +154,28 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
overallHeight=baselineHeight+oh-bh; overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp; strikeoutPos=sp;
} }
xnew+=qMax(w1, w2+spaceWidth); xnew+=qMax(w1+subBesidesXCorrection, w2+spaceWidth);
doDraw=false; doDraw=false;
//qDebug()<<"### sub+super"; //qDebug()<<"### sub+super";
//qDebug()<<"### subsupop: sub+super1 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: sub+super1 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
} else {
double w1, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtrForSubscript);
if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=bh;
strikeoutPos=sp;
}
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
}
xnew+=w1-subBesidesXCorrection;
doDraw=false;
} }
} else { } else {
if (nodes[i]->isSubSuperscriptAboveBelowNode()) { if (nodes[i]->isSubSuperscriptAboveBelowNode()) {
@ -175,7 +194,8 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
//std::cout<<"symbol ='"<<s.toStdString()<<"' subn="<<subn<<" supn="<<supn<<"\n"; //std::cout<<"symbol ='"<<s.toStdString()<<"' subn="<<subn<<" supn="<<supn<<"\n";
if ((subn && supn2) || (subn2 && supn)) { // is this subscript and superscript or superscript and subscript? if ((subn && supn2) || (subn2 && supn)) { // is this subscript and superscript or superscript and subscript?
if (!subn) subn=subn2; if (!subn) subn=subn2;
if (!supn) supn=supn2; JKQTMathTextEnvironment ev=currentEv; if (!supn) supn=supn2;
JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor(); ev.fontSize=ev.fontSize*parentMathText->getOperatorsubsuperSizeFactor();
double w1=0, wsub=0, wsup=0; double w1=0, wsub=0, wsup=0;
double oh1=0, ohsub=0, ohsup=0; double oh1=0, ohsub=0, ohsup=0;
@ -187,18 +207,18 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
//qDebug()<<"sub_super: node: "<<subn->getTypeName()<<" w2="<<w2<<" bh2"<<bh2<<" oh2="<<oh2<<" sp2="<<sp2; //qDebug()<<"sub_super: node: "<<subn->getTypeName()<<" w2="<<w2<<" bh2"<<bh2<<" oh2="<<oh2<<" sp2="<<sp2;
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup); supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
//qDebug()<<"sub_super: node: "<<supn->getTypeName()<<" w3="<<w3<<" bh3"<<bh3<<" oh3="<<oh3<<" sp3="<<sp3; //qDebug()<<"sub_super: node: "<<supn->getTypeName()<<" w3="<<w3<<" bh3"<<bh3<<" oh3="<<oh3<<" sp3="<<sp3;
const double descent1=oh1-bh1;
//double d1=oh1-bh1; //double d1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
//double d3=oh3-bh3; //double d3=oh3-bh3;
const double neww=qMax(qMax(w1, wsub), wsup)+subsuperextrawidth; const double neww=qMax(qMax(w1, wsub+subSuperXCorrection), wsup+subSuperXCorrection)+subsuperextrawidth;
const double newBaselineHeight=bh1+ohsup+subsupershift; const double newBaselineHeight=bh1+ohsup+subsupershift;
if (newBaselineHeight>baselineHeight) { if (newBaselineHeight>baselineHeight) {
const double extraBaselineHeight=newBaselineHeight-baselineHeight; const double extraBaselineHeight=newBaselineHeight-baselineHeight;
baselineHeight=newBaselineHeight; baselineHeight=newBaselineHeight;
overallHeight=overallHeight+extraBaselineHeight; overallHeight=overallHeight+extraBaselineHeight;
} }
const double newDescent=oh1-bh1+ohsub+subsupershift; const double newDescent=descent1+ohsub+subsupershift;
if (newDescent>overallHeight-baselineHeight) { if (newDescent>overallHeight-baselineHeight) {
const double extraDescent=newDescent-(overallHeight-baselineHeight); const double extraDescent=newDescent-(overallHeight-baselineHeight);
overallHeight=overallHeight+extraDescent; overallHeight=overallHeight+extraDescent;
@ -217,17 +237,27 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
double oh1=0, ohsub=0; double oh1=0, ohsub=0;
double bh1=0, bhsub=0; double bh1=0, bhsub=0;
double sp1=0, spsub=0;//, sp3=0; double sp1=0, spsub=0;//, sp3=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
if (symbN) {
symbN->getSymbolSize(painter, currentEv, w1, bh1, oh1, sp1, subSuperXCorrection, subBesidesXCorrection);
} else {
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1);
}
subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub); subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
const double descent1=oh1-bh1;
//double d1=oh1-bh1; //double d1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
const double newDescent=oh1-bh1+ohsub+subsupershift; const double newDescent=descent1+ohsub+subsupershift;
if (newDescent>overallHeight-baselineHeight) { if (newDescent>overallHeight-baselineHeight) {
const double extraDescent=newDescent-(overallHeight-baselineHeight); const double extraDescent=newDescent-(overallHeight-baselineHeight);
overallHeight=overallHeight+extraDescent; overallHeight=overallHeight+extraDescent;
} }
const double neww=qMax(w1, wsub)+subsuperextrawidth; if (bh1>baselineHeight) {
overallHeight=overallHeight+(bh1-baselineHeight);
baselineHeight=bh1;
}
const double neww=qMax(w1, wsub+subSuperXCorrection)+subsuperextrawidth;
i++; i++;
doDraw=false; doDraw=false;
xnew+=neww; xnew+=neww;
@ -239,7 +269,13 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
double oh1=0, ohsup=0; double oh1=0, ohsup=0;
double bh1=0, bhsup=0; double bh1=0, bhsup=0;
double sp1=0, spsup=0;//, sp3=0; double sp1=0, spsup=0;//, sp3=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
if (symbN) {
symbN->getSymbolSize(painter, currentEv, w1, bh1, oh1, sp1, subSuperXCorrection, subBesidesXCorrection);
} else {
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp1);
}
const double descent1=oh1-bh1;
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup); supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
//double d1=oh1-bh1; //double d1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
@ -250,8 +286,11 @@ void JKQTMathTextListNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
baselineHeight=newBaselineHeight; baselineHeight=newBaselineHeight;
overallHeight=overallHeight+extraBaselineHeight; overallHeight=overallHeight+extraBaselineHeight;
} }
if (descent1>overallHeight-baselineHeight) {
overallHeight=baselineHeight+descent1;
}
const double neww=qMax(w1, wsup)+subsuperextrawidth; const double neww=qMax(w1, wsup+subSuperXCorrection)+subsuperextrawidth;
i++; i++;
doDraw=false; doDraw=false;
xnew+=neww; xnew+=neww;
@ -303,9 +342,16 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
JKQTMathTextNodeSize prevNodeSize; JKQTMathTextNodeSize prevNodeSize;
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr; JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr; JKQTMathTextNodeSize* prevNodeSizePtrForSuperscript=nullptr;
double subSuperXCorrection=0;
double subBesidesXCorrection=0;
if (i>0) { if (i>0) {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i-1]);
if (symbN) {
symbN->getSymbolSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos, subSuperXCorrection, subBesidesXCorrection);
} else {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos);
}
const double prevAscent=prevNodeSize.baselineHeight; const double prevAscent=prevNodeSize.baselineHeight;
const double prevDescent=prevNodeSize.overallHeight-prevNodeSize.baselineHeight; const double prevDescent=prevNodeSize.overallHeight-prevNodeSize.baselineHeight;
const bool shouldUseSpecialSubscriptMode=prevAscent>=subsuperSpecialModeAscent; const bool shouldUseSpecialSubscriptMode=prevAscent>=subsuperSpecialModeAscent;
@ -330,7 +376,7 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
i++; i++;
//painter.setPen(QPen("magenta")); //painter.setPen(QPen("magenta"));
//painter.drawEllipse(xnew-4,ynew-4,8,8); //painter.drawEllipse(xnew-4,ynew-4,8,8);
double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSubscript); double xnew2=nodes[i]->draw(painter, xnew-subSuperXCorrection, ynew, currentEv, prevNodeSizePtrForSubscript);
//i++; //i++;
xnew=qMax(xnew1, xnew2); xnew=qMax(xnew1, xnew2);
doDraw=false; doDraw=false;
@ -341,7 +387,7 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i+1])) { // is this subscript?
//painter.setPen(QPen("red")); //painter.setPen(QPen("red"));
//painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8); //painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8);
double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSubscript); double xnew1=nodes[i]->draw(painter, xnew-subSuperXCorrection, ynew, currentEv, prevNodeSizePtrForSubscript);
i++; i++;
//painter.setPen(QPen("magenta")); //painter.setPen(QPen("magenta"));
//painter.drawEllipse(xnew-4,ynew-4,8,8); //painter.drawEllipse(xnew-4,ynew-4,8,8);
@ -350,6 +396,9 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
xnew=qMax(xnew1, xnew2); xnew=qMax(xnew1, xnew2);
doDraw=false; doDraw=false;
} }
} else {
xnew=nodes[i]->draw(painter, xnew-subBesidesXCorrection, ynew, currentEv, prevNodeSizePtrForSubscript);
doDraw=false;
} }
} else { } else {
@ -375,7 +424,14 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
double w1=0, wsub=0, wsup=0; double w1=0, wsub=0, wsup=0;
double oh1=0, ohsub=0, ohsup=0; double oh1=0, ohsub=0, ohsup=0;
double bh1=0, bhsub=0, bhsup=0, spsub, spsup, sp; double bh1=0, bhsub=0, bhsup=0, spsub, spsup, sp;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
if (symbN) {
symbN->getSymbolSize(painter, currentEv, w1, bh1, oh1, sp, subSuperXCorrection, subBesidesXCorrection);
} else {
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
}
subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub); subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup); supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
const double descent1=oh1-bh1; const double descent1=oh1-bh1;
@ -387,10 +443,10 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv); const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv);
i++; i++;
//double xnew2= //double xnew2=
const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0, ynew+bhsub+descent1+subsupershift, ev); const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0-subSuperXCorrection, ynew+bhsub+descent1+subsupershift, ev);
i++; i++;
//double xnew3= //double xnew3=
const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0, ynew-bh1-descent3-subsupershift, ev); const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0+subSuperXCorrection, ynew-bh1-descent3-subsupershift, ev);
doDraw=false; doDraw=false;
xnew=qMax(qMax(xn1, xnsub), xnsup)+subsuperextrawidth/2.0; xnew=qMax(qMax(xn1, xnsub), xnsup)+subsuperextrawidth/2.0;
} else if (subn) { // is this subscript and no following superscript? } else if (subn) { // is this subscript and no following superscript?
@ -399,7 +455,12 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
double w1=0, wsub=0; double w1=0, wsub=0;
double oh1=0, ohsub=0; double oh1=0, ohsub=0;
double bh1=0, bhsub=0, sp=0, spsub=0; double bh1=0, bhsub=0, sp=0, spsub=0;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
if (symbN) {
symbN->getSymbolSize(painter, currentEv, w1, bh1, oh1, sp, subSuperXCorrection, subBesidesXCorrection);
} else {
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
}
subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub); subn->getChild()->getSize(painter, ev, wsub, bhsub, ohsub, spsub);
const double descent1=oh1-bh1; const double descent1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
@ -409,7 +470,7 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv); const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv);
i++; i++;
//double xnew2= //double xnew2=
const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0, ynew+bhsub+descent1+subsupershift, ev)+subsupershift; const double xnsub=subn->getChild()->draw(painter, xnew+(neww-wsub)/2.0-subSuperXCorrection, ynew+bhsub+descent1+subsupershift, ev)+subsupershift;
doDraw=false; doDraw=false;
//xnew+=w; //xnew+=w;
xnew=qMax(xnsub, xn1)+subsuperextrawidth/2.0; xnew=qMax(xnsub, xn1)+subsuperextrawidth/2.0;
@ -419,7 +480,12 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
double w1=0, wsup=0; double w1=0, wsup=0;
double oh1=0, ohsup=0; double oh1=0, ohsup=0;
double bh1=0, bhsup=0, sp, spsup; double bh1=0, bhsup=0, sp, spsup;
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp); JKQTMathTextSymbolNode* symbN=dynamic_cast<JKQTMathTextSymbolNode*>(nodes[i]);
if (symbN) {
symbN->getSymbolSize(painter, currentEv, w1, bh1, oh1, sp, subSuperXCorrection, subBesidesXCorrection);
} else {
nodes[i]->getSize(painter, currentEv, w1, bh1, oh1, sp);
}
supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup); supn->getChild()->getSize(painter, ev, wsup, bhsup, ohsup, spsup);
//double d1=oh1-bh1; //double d1=oh1-bh1;
//double d2=oh2-bh2; //double d2=oh2-bh2;
@ -430,7 +496,7 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv); const double xn1=nodes[i]->draw(painter, xnew+(neww-w1)/2.0, ynew, currentEv);
i++; i++;
//double xnew3= //double xnew3=
const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0, ynew-bh1-descent3-subsupershift, ev); const double xnsup=supn->getChild()->draw(painter, xnew+(neww-wsup)/2.0+subSuperXCorrection, ynew-bh1-descent3-subsupershift, ev);
doDraw=false; doDraw=false;
xnew=qMax(xn1, xnsup)+subsuperextrawidth/2.0; xnew=qMax(xn1, xnsup)+subsuperextrawidth/2.0;
} }
@ -439,7 +505,7 @@ double JKQTMathTextListNode::draw(QPainter& painter, double x, double y, JKQTMat
if (i<nodes.size() && doDraw) { if (i<nodes.size() && doDraw) {
if (nodeI_SuperScript) xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSuperscript); if (nodeI_SuperScript) xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSuperscript);
else if (nodeI_SubScript) xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtrForSubscript); else if (nodeI_SubScript) xnew=nodes[i]->draw(painter, xnew-subBesidesXCorrection, ynew, currentEv, prevNodeSizePtrForSubscript);
else xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, nullptr); else xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, nullptr);
} }
} }

View File

@ -891,7 +891,13 @@ JKQTMathTextSymbolNode::SymbolProps JKQTMathTextSymbolNode::getSymbolProp(const
} }
void JKQTMathTextSymbolNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) { void JKQTMathTextSymbolNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize) {
double dummy1, dummy2;
getSymbolSizeInternal(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos, dummy1, dummy2, prevNodeSize);
}
void JKQTMathTextSymbolNode::getSymbolSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, double &subSuperXCorrection, double &subBesidesXCorrection, const JKQTMathTextNodeSize *prevNodeSize)
{
QFont f=currentEv.getFont(parentMathText); QFont f=currentEv.getFont(parentMathText);
auto props=getSymbolProp(symbolName, currentEv); auto props=getSymbolProp(symbolName, currentEv);
f.setFamily(props.font); f.setFamily(props.font);
@ -942,6 +948,11 @@ void JKQTMathTextSymbolNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvi
if (props.extendWidthInMathmode && currentEv.insideMath) width=width*parentMathText->getMathoperatorWidthFactor(); if (props.extendWidthInMathmode && currentEv.insideMath) width=width*parentMathText->getMathoperatorWidthFactor();
static QSet<QString> intCorrectionSymbolNames=QSet<QString>()<<"int"<<"iint"<<"iiint"<<"oint"<<"oiint"<<"oiiint";
if (intCorrectionSymbolNames.contains(symbolName)) {
subSuperXCorrection=parentMathText->getIntSubSuperXCorrectionFactor()*tbr.width();
subBesidesXCorrection=parentMathText->getIntSubBesidesXCorrectionXFactor()*JKQTMathTextGetTightBoundingRect(f, "X", painter.device()).width();
}
} }
double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) { double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
@ -1316,3 +1327,16 @@ bool JKQTMathTextSymbolNode::getAddWhitespace() const
return addWhitespace; return addWhitespace;
} }
void JKQTMathTextSymbolNode::getSymbolSize(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, double &subSuperXCorrection, double &subBesidesXCorrection, const JKQTMathTextNodeSize *prevNodeSize)
{
double w=width, b=baselineHeight, o=overallHeight, s=strikeoutPos;
getSymbolSizeInternal(painter, currentEv, w, b, o, s, subSuperXCorrection, subBesidesXCorrection, prevNodeSize);
if (w<1e5) width=w;
if (b<1e5) baselineHeight=b;
if (o<1e5) overallHeight=o;
if (s<1e5) strikeoutPos=s;
}

View File

@ -51,9 +51,25 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
QString getSymbolfontName() const; QString getSymbolfontName() const;
/** \copydoc addWhitespace */ /** \copydoc addWhitespace */
bool getAddWhitespace() const; bool getAddWhitespace() const;
/** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal()
*
* \param painter painter to use for determining the size
* \param currentEv current environment object
* \param[out] width width of the block/node
* \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline
* \param[out] overallHeight overall height (bottom to top) of the node, the ascent is \c overallHeight-baselineHeight
* \param[out] strikeoutPos position of the strikeout-line
* \param[out] subSuperXCorrection x-correction as described for JKQTMathParser::intsubsuper_xcorrection_factor for placing sub-/superscript below/above the symbol
* \param[out] subBesidesXCorrection x-correction as described for JKQTMathParser::intsubbesides_xcorrection_xfactor for placing sub-/superscript below/above the symbol
* \param[in] prevNodeSize optional parameter, describing the size of the previous node (on the left). This may be used for layout of some nodes (e.g. sub/super to move correctly next to large parantheses ...)
*
*/
void getSymbolSize(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, double& subSuperXCorrection, double& subBesidesXCorrection, const JKQTMathTextNodeSize* prevNodeSize=nullptr);
protected: protected:
/** \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;
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSymbolSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, double& subSuperXCorrection, double& subBesidesXCorrection, const JKQTMathTextNodeSize* prevNodeSize=nullptr) ;
/** \brief this string will be sent to the drawText method with properly set fonts */ /** \brief this string will be sent to the drawText method with properly set fonts */
QString symbolName; QString symbolName;