mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
IMPROVEMENTS: JKQTMathText: underbrace/overbrace and angle-braket improvements
This commit is contained in:
parent
ebdc183b2b
commit
56418f9504
@ -36,7 +36,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>IMPROVED: high-dpr-support in JKQTMathText</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>IMPROVED: improved drawing of parantheses, square brackets ...</li>
|
||||
<li>IMPROVED: improved drawing of parantheses, square brackets ... , underbrace/overbrace</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: reworked drawing of decorations: improved appearance and positioning!</li>
|
||||
|
@ -78,6 +78,8 @@ JKQTMathText::JKQTMathText(QObject* parent):
|
||||
frac_shift_factor=0.4;
|
||||
|
||||
underbrace_factor=0.75;
|
||||
underbrace_separation_xfactor=0.25;
|
||||
underbrace_bracesize_xfactor=0.5;
|
||||
underset_factor=0.7;
|
||||
decoration_height_factor=0.2;
|
||||
decoration_width_reduction_Xfactor=0.2;
|
||||
@ -218,6 +220,8 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group)
|
||||
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();
|
||||
underbrace_bracesize_xfactor=settings.value(group+"underbrace_bracesize_xfactor", underbrace_bracesize_xfactor).toDouble();
|
||||
underbrace_separation_xfactor=settings.value(group+"underbrace_separation_xfactor", underbrace_separation_xfactor).toDouble();
|
||||
underset_factor=settings.value(group+"undersetFactor", underset_factor).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();
|
||||
@ -249,6 +253,8 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const
|
||||
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+ "underbrace_bracesize_xfactor", underbrace_bracesize_xfactor);
|
||||
settings.setValue(group+ "underbrace_separation_xfactor", underbrace_separation_xfactor);
|
||||
settings.setValue(group+ "undersetFactor", underset_factor);
|
||||
settings.setValue(group+ "operatorsubsuper_size_factor", operatorsubsuper_size_factor);
|
||||
settings.setValue(group+ "operatorsubsuper_distance_factor", operatorsubsuper_distance_factor);
|
||||
@ -786,6 +792,26 @@ double JKQTMathText::getUnderbraceFactor() const
|
||||
return this->underbrace_factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setUnderbraceSeparationXFactor(double __value)
|
||||
{
|
||||
underbrace_separation_xfactor=__value;
|
||||
}
|
||||
|
||||
double JKQTMathText::getUnderbraceSeparationXFactor() const
|
||||
{
|
||||
return underbrace_separation_xfactor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setUnderbraceBraceSizeXFactor(double __value)
|
||||
{
|
||||
underbrace_bracesize_xfactor=__value;
|
||||
}
|
||||
|
||||
double JKQTMathText::getUnderbraceBraceSizeXFactor() const
|
||||
{
|
||||
return underbrace_bracesize_xfactor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setUndersetFactor(double __value)
|
||||
{
|
||||
this->underset_factor = __value;
|
||||
|
@ -486,6 +486,14 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
void setUnderbraceFactor(double __value);
|
||||
/** \copydoc underbrace_factor */
|
||||
double getUnderbraceFactor() const;
|
||||
/** \copydoc underbrace_separation_xfactor */
|
||||
void setUnderbraceSeparationXFactor(double __value);
|
||||
/** \copydoc underbrace_separation_xfactor */
|
||||
double getUnderbraceSeparationXFactor() const;
|
||||
/** \copydoc underbrace_bracesize_xfactor */
|
||||
void setUnderbraceBraceSizeXFactor(double __value);
|
||||
/** \copydoc underbrace_bracesize_xfactor */
|
||||
double getUnderbraceBraceSizeXFactor() const;
|
||||
/** \copydoc undersetFactor */
|
||||
void setUndersetFactor(double __value);
|
||||
/** \copydoc undersetFactor */
|
||||
@ -641,6 +649,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
double underbrace_factor;
|
||||
/** \brief scaling factor for font of underset/overset text */
|
||||
double underset_factor;
|
||||
/** \brief additional space between the main text to the curly brace and the brace to underbrace/overbrace, multiplied with height("x") */
|
||||
double underbrace_separation_xfactor;
|
||||
/** \brief height of the brace in underbrace/overbrace, multiplied with ascent */
|
||||
double underbrace_bracesize_xfactor;
|
||||
/** \brief fraction of the brace ascent that the brace is shifted downwards, when scaled */
|
||||
double brace_y_shift_factor;
|
||||
/** \brief size of the decorations (dot, tilde, ...), as fraction of the baselineheight
|
||||
|
@ -134,11 +134,30 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.cubicTo(ptc2, pbc2, pb2);
|
||||
path.closeSubpath();
|
||||
painter.fillPath(path, QBrush(ev.color, Qt::SolidPattern));
|
||||
painter.setPen("blue");
|
||||
/*painter.setPen("blue");
|
||||
painter.drawLine(pb1,pbc1);
|
||||
painter.drawLine(pt1,ptc1);
|
||||
painter.drawLine(pb2,pbc2);
|
||||
painter.drawLine(pt2,ptc2);
|
||||
painter.drawLine(pt2,ptc2);*/
|
||||
} else if (openbrace==MTBTAngleBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
const double yc=(y1+y2)/2.0;
|
||||
const QPointF pb1(xbrace2-paren_topwidth/2.0, y1);
|
||||
const QPointF pc1(xbrace1-paren_centerwidth/2.0, yc);
|
||||
const QPointF pt1(xbrace2-paren_topwidth/2.0, y2);
|
||||
const QPointF pt2(xbrace2+paren_topwidth/2.0, y2);
|
||||
const QPointF pc2(xbrace1+paren_centerwidth/2.0, yc);
|
||||
const QPointF pb2(xbrace2+paren_topwidth/2.0, y1);
|
||||
path.moveTo(pb1);
|
||||
path.lineTo(pc1);
|
||||
path.lineTo(pt1);
|
||||
path.lineTo(pt2);
|
||||
path.lineTo(pc2);
|
||||
path.lineTo(pb2);
|
||||
path.closeSubpath();
|
||||
painter.fillPath(path, QBrush(ev.color, Qt::SolidPattern));
|
||||
} else if (openbrace==MTBTSquareBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
|
||||
@ -205,17 +224,9 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
painter.setPen(plocal);
|
||||
const QLineF l(xbrace1, y1, xbrace1, y2);
|
||||
if (l.length()>0) painter.drawLine(l);
|
||||
const QLineF l2(xbrace1+1.5*lw, y1, xbrace1+1.5*lw, y2);
|
||||
const QLineF l2(xbrace1+2.5*lw, y1, xbrace1+2.5*lw, y2);
|
||||
if (l2.length()>0) painter.drawLine(l2);
|
||||
painter.setPen(p);
|
||||
} else if (openbrace==MTBTAngleBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
path.moveTo(xbrace2, y1);
|
||||
path.lineTo(xbrace1, (y2+y1)/2.0);
|
||||
path.lineTo(xbrace2, y2);
|
||||
painter.drawPath(path);
|
||||
} else {
|
||||
showOpeningBrace=false;
|
||||
}
|
||||
@ -257,7 +268,25 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
painter.drawLine(pt1,ptc1);
|
||||
painter.drawLine(pb2,pbc2);
|
||||
painter.drawLine(pt2,ptc2);*/
|
||||
|
||||
} else if (closebrace==MTBTAngleBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
const double yc=(y1+y2)/2.0;
|
||||
const QPointF pb1(xbrace1-paren_topwidth/2.0, y1);
|
||||
const QPointF pc1(xbrace2-paren_centerwidth/2.0, yc);
|
||||
const QPointF pt1(xbrace1-paren_topwidth/2.0, y2);
|
||||
const QPointF pt2(xbrace1+paren_topwidth/2.0, y2);
|
||||
const QPointF pc2(xbrace2+paren_centerwidth/2.0, yc);
|
||||
const QPointF pb2(xbrace1+paren_topwidth/2.0, y1);
|
||||
path.moveTo(pb1);
|
||||
path.lineTo(pc1);
|
||||
path.lineTo(pt1);
|
||||
path.lineTo(pt2);
|
||||
path.lineTo(pc2);
|
||||
path.lineTo(pb2);
|
||||
path.closeSubpath();
|
||||
painter.fillPath(path, QBrush(ev.color, Qt::SolidPattern));
|
||||
} else if (closebrace==MTBTSquareBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
|
||||
@ -331,17 +360,9 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
|
||||
painter.setPen(plocal);
|
||||
if (l.length()>0) painter.drawLine(l);
|
||||
const QLineF l2(xbrace2-1.5*lw, y1, xbrace2-1.5*lw, y2);
|
||||
const QLineF l2(xbrace2-2.5*lw, y1, xbrace2-2.5*lw, y2);
|
||||
if (l2.length()>0) painter.drawLine(l2);
|
||||
painter.setPen(p);
|
||||
} else if (closebrace==MTBTAngleBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
path.moveTo(xbrace1, y1);
|
||||
path.lineTo(xbrace2, (y2+y1)/2.0);
|
||||
path.lineTo(xbrace1, y2);
|
||||
painter.drawPath(path);
|
||||
} else {
|
||||
showClosingBrace=false;
|
||||
}
|
||||
|
@ -90,6 +90,8 @@ void JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
|
||||
const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
||||
const double xwidth=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width();
|
||||
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
||||
const double braceheight=fm.xHeight()*parentMathText->getUnderbraceBraceSizeXFactor();
|
||||
const double braceseparation=fm.xHeight()*parentMathText->getUnderbraceSeparationXFactor();
|
||||
|
||||
if (mode==JKQTMathTextFracNode::MTFMunderbrace || mode==JKQTMathTextFracNode::MTFMoverbrace) {
|
||||
ev2.fontSize=ev2.fontSize*parentMathText->getUnderbraceFactor();
|
||||
@ -108,6 +110,7 @@ void JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
|
||||
double width2=0, baselineHeight2=0, overallHeight2=0, strikeoutPos2=0;
|
||||
child1->getSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos1);
|
||||
child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos2);
|
||||
const double descent1=overallHeight1-baselineHeight1;
|
||||
|
||||
|
||||
overallHeight=0;
|
||||
@ -135,13 +138,14 @@ void JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
|
||||
overallHeight=newascent+newdescent;
|
||||
baselineHeight=newascent;
|
||||
} else if (mode==JKQTMathTextFracNode::MTFMunderbrace) {
|
||||
overallHeight=overallHeight1+overallHeight2+Mheight/2.0;
|
||||
const double newdescent=descent1+overallHeight2+braceheight+2.0*braceseparation;
|
||||
overallHeight=newdescent+baselineHeight1;
|
||||
baselineHeight=baselineHeight1;
|
||||
width=qMax(width1, width2)+xwidth;
|
||||
strikeoutPos=line_ascent;
|
||||
} else if (mode==JKQTMathTextFracNode::MTFMoverbrace) {
|
||||
overallHeight=overallHeight1+overallHeight2+Mheight/2.0;
|
||||
baselineHeight=baselineHeight1+overallHeight2+Mheight/2.0;
|
||||
overallHeight=overallHeight1+overallHeight2+braceheight+2.0*braceseparation;
|
||||
baselineHeight=baselineHeight1+overallHeight2+braceheight+2.0*braceseparation;
|
||||
width=qMax(width1, width2)+xwidth;
|
||||
strikeoutPos=line_ascent;
|
||||
} else if (mode==JKQTMathTextFracNode::MTFMunderset) {
|
||||
@ -189,7 +193,8 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
|
||||
const double linewideth=qMax(0.0,ceil(currentEv.fontSize/16.0));//fm.lineWidth();
|
||||
const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
||||
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
||||
const double bw=Mheight/2.0;
|
||||
const double braceheight=fm.xHeight()*parentMathText->getUnderbraceBraceSizeXFactor();
|
||||
const double braceseparation=fm.xHeight()*parentMathText->getUnderbraceSeparationXFactor();
|
||||
|
||||
if (mode==JKQTMathTextFracNode::MTFMunderbrace || mode==JKQTMathTextFracNode::MTFMoverbrace) {
|
||||
ev2.fontSize=ev2.fontSize*parentMathText->getUnderbraceFactor();
|
||||
@ -208,12 +213,12 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
|
||||
double width2=0, baselineHeight2=0, overallHeight2=0, strikeoutPos=0;
|
||||
child1->getSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos);
|
||||
child2->getSize(painter, ev2, width2, baselineHeight2, overallHeight2, strikeoutPos);
|
||||
double ascent1=baselineHeight1;
|
||||
double descent1=overallHeight1-baselineHeight1;
|
||||
double ascent2=baselineHeight2;
|
||||
double descent2=overallHeight2-baselineHeight2;
|
||||
const double ascent1=baselineHeight1;
|
||||
const double descent1=overallHeight1-baselineHeight1;
|
||||
const double ascent2=baselineHeight2;
|
||||
const double descent2=overallHeight2-baselineHeight2;
|
||||
|
||||
double yline=y-xheight*0.5;
|
||||
const double yline=y-xheight*0.5;
|
||||
|
||||
|
||||
//double overallHeight=overallHeight1+overallHeight2+xh;
|
||||
@ -247,35 +252,36 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
|
||||
child2->draw(painter, x+xwidth/2.0+(maxWidth-width2)/2.0, y+descent1+xheight/6.0+ascent2, ev2);
|
||||
deltaWidth=xwidth;
|
||||
} else if (mode==JKQTMathTextFracNode::MTFMunderbrace) {
|
||||
double ybrace=y+descent1+bw/2.0;
|
||||
const double ybrace=y+descent1+braceseparation+braceheight/2.0;
|
||||
const double ybot=y+descent1+2.0*braceseparation+braceheight+ascent2;
|
||||
{
|
||||
const QPainterPath path=JKQTMathTextMakeHBracePath(x+xwidth/2.0+(width1)/2.0, ybrace, maxWidth, bw, p.width());
|
||||
const QPainterPath path=JKQTMathTextMakeHBracePath(x+xwidth/2.0+(width1)/2.0, ybrace, maxWidth, braceheight, p.width());
|
||||
QPen plocal=p;
|
||||
plocal.setWidthF(0.0001);
|
||||
painter.fillPath(path, QBrush(ev1.color));
|
||||
}
|
||||
child1->draw(painter, x+xwidth/2.0+(maxWidth-width1)/2.0, y, ev1);
|
||||
child2->draw(painter, x+xwidth/2.0+(maxWidth-width2)/2.0, y+descent1+bw+ascent2, ev2);
|
||||
child2->draw(painter, x+xwidth/2.0+(maxWidth-width2)/2.0, ybot, ev2);
|
||||
deltaWidth=xwidth;
|
||||
} else if (mode==JKQTMathTextFracNode::MTFMoverset) {
|
||||
child1->draw(painter, x+xwidth/2.0+(maxWidth-width1)/2.0, y, ev1);
|
||||
child2->draw(painter, x+xwidth/2.0+(maxWidth-width2)/2.0, y-ascent1-xheight/6.0-descent2, ev2);
|
||||
deltaWidth=xwidth;
|
||||
} else if (mode==JKQTMathTextFracNode::MTFMoverbrace) {
|
||||
const double ybrace=y-ascent1-bw/2.0;
|
||||
|
||||
const double ybrace=y-ascent1-braceheight/2.0-braceseparation;
|
||||
const double ytop=y-ascent1-2.0*braceseparation-braceheight-descent2;
|
||||
{
|
||||
painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.translate(x+xwidth/2.0+(width1)/2.0, ybrace);
|
||||
painter.rotate(180);
|
||||
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0, maxWidth, bw, p.widthF());
|
||||
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0, maxWidth, braceheight, p.widthF());
|
||||
QPen plocal=p;
|
||||
plocal.setWidthF(0.0001);
|
||||
painter.fillPath(path, QBrush(ev1.color));
|
||||
}
|
||||
|
||||
child1->draw(painter, x+xwidth/2.0+(maxWidth-width1)/2.0, y, ev1);
|
||||
child2->draw(painter, x+xwidth/2.0+(maxWidth-width2)/2.0, y-ascent1-bw-descent2, ev2);
|
||||
child2->draw(painter, x+xwidth/2.0+(maxWidth-width2)/2.0, ytop, ev2);
|
||||
deltaWidth=xwidth;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user