IMPROVED: JKQTMathText: improved drawing of parantheses, square brackets ...

This commit is contained in:
jkriege2 2022-06-26 23:42:06 +02:00
parent 2d2acc3b19
commit ebdc183b2b
7 changed files with 161 additions and 46 deletions

View File

@ -36,6 +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>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>

View File

@ -121,6 +121,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("text/math: brace test: left/right { }", "text: "+fAddBraceTest("\\{","\\}")+" -- math: $"+fAddBraceTest("\\{","\\}")+"$");
ui->cmbTestset->addItem("text/math: brace test: left/right || ||", "text: "+fAddBraceTest("\\|","\\|")+" -- math: $"+fAddBraceTest("\\|","\\|")+"$");
ui->cmbTestset->addItem("text/math: brace test: left/right | |", "text: "+fAddBraceTest("|","|")+" -- math: $"+fAddBraceTest("|","|")+"$");
ui->cmbTestset->addItem("text/math: brace test: left/right angles", "text: \\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle -- math: $\\left\\langle\\left\\langle\\left\\langle r^{123}\\right\\rangle\\right\\rangle\\right\\rangle$");
ui->cmbTestset->addItem("text/math: brace test: left/right floor", "text: \\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor -- math: $\\left\\lfloor\\left\\lfloor\\left\\lfloor r^{123}\\right\\rfloor\\right\\rfloor\\right\\rfloor$");
ui->cmbTestset->addItem("text/math: brace test: left/right ceil", "text: \\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil -- math: $\\left\\lceil\\left\\lceil\\left\\lceil r^{123}\\right\\rceil\\right\\rceil\\right\\rceil$");
ui->cmbTestset->addItem("text/math: brace test: left/right top-corner", "text: "+fAddBraceTest("\\ulcorner","\\urcorner")+" -- math: $"+fAddBraceTest("\\ulcorner","\\urcorner")+"$");
@ -130,6 +131,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("text/math: brace test: non-left/right [ ]", "text: [[[r^{123}]]] -- math: $[[[r^{123}]]]$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right { }", "text: \\{\\{\\{r^{123}\\}\\}\\} -- math: $\\{\\{\\{ r^{123}\\}\\}\\}$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right | |", "text: |||r^{123}||| -- math: $|||r^{123}|||$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right angle", "text: \\langle\\langle\\langle r^{123}\\rangle\\rangle\\rangle -- math: $\\langle\\langle\\langle r^{123}\\rangle\\rangle\\rangle$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right floor", "text: \\lfloor\\lfloor\\lfloor r^{123}\\rfloor\\rfloor\\rfloor -- math: $\\lfloor\\lfloor\\lfloor r^{123}\\rfloor\\rfloor\\rfloor$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right ceil", "text: \\lceil\\lceil\\lceil r^{123}\\rceil\\rceil\\rceil -- math: $\\lceil\\lceil\\lceil r^{123}\\rceil\\rceil\\rceil$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right top-corner", "text: \\ulcorner\\ulcorner\\ulcorner r^{123}\\urcorner\\urcorner\\urcorner -- math: $\\ulcorner\\ulcorner\\ulcorner r^{123}\\urcorner\\urcorner\\urcorner$");

View File

@ -60,25 +60,28 @@ JKQTMathText::JKQTMathText(QObject* parent):
//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();
fontSize=10;
fontColor=QColor("black");
italic_correction_factor=0.4;
brace_factor=1.04;
brace_shrink_factor=0.45;
brace_y_shift_factor=0.7;//-1;
subsuper_size_factor=0.7;
subsuper_mode_selection_by_size_factor=1.01;
italic_correction_factor=0.4;
sub_shift_factor=0.4;
super_shift_factor=0.7;
special_sub_shift_factor=0.4;
special_super_shift_factor=0.4;
brace_shrink_factor=0.6;
fontColor=QColor("black");
frac_factor=1.0;
frac_nested_factor=0.7;
frac_shift_factor=0.4;
underbrace_factor=0.75;
underset_factor=0.7;
decoration_height_factor=0.2;
decoration_width_reduction_Xfactor=0.2;
brace_y_shift_factor=0.7;//-1;
operatorsubsuper_size_factor=0.65;
operatorsubsuper_distance_factor=0.25;
operatorsubsuper_extraspace_factor=0.5;

View File

@ -566,20 +566,51 @@ QPainterPath JKQTMathTextMakeArrow(double x, double y, double width, double arro
return path;
}
QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double cubicshrink, double cubiccontrolfac) {
double xl1=x-(width)*cubicshrink+bw*cubicshrink;
double xr2=x+(width)*cubicshrink-bw*cubicshrink;
double xl2=x-bw*cubicshrink;
double xr1=x+bw*cubicshrink;
QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double lineWidth, double cubicshrink, double cubiccontrolfac, double lineWidthShrinkFactor, double lineWidthGrowFactor) {
const double thinLW=lineWidthShrinkFactor*lineWidth;
const double thickLW=lineWidth*lineWidthGrowFactor;
const double xleft=x-width/2.0;
const double xleft_inner=xleft+thinLW;
const double xleftflat_leftbottom=xleft+cubicshrink*bw;
const double xleftflat_lefttop=xleft_inner+cubicshrink*bw;
const double xright=x+width/2.0;
const double xright_inner=xright-thinLW;
const double xrightflat_rightbottom=xright-cubicshrink*bw;
const double xrightflat_righttop=xright_inner-cubicshrink*bw;
const double xleftflat_righttop=x-bw*cubicshrink;
const double xlefttip=x-thinLW/2.0;
const double xleftflat_rightbottom=xlefttip-bw*cubicshrink;
const double xrightflat_lefttop=x+bw*cubicshrink;
const double xrighttip=x+thinLW/2.0;
const double xrightflat_leftbottom=xrighttip+bw*cubicshrink;
const double ytop=ybrace-bw*cubicshrink;
const double yctop=ybrace-thickLW/2.0;
const double ycbottom=ybrace+thickLW/2.0;
const double ybottom=ybrace+bw*cubicshrink;
const double ybottomtip=ybottom-thickLW;
const double dxyControl=bw*cubiccontrolfac;
QPainterPath path;
path.moveTo(xl1-bw*cubicshrink, ybrace-bw*cubicshrink);
path.cubicTo(xl1-bw*cubicshrink, ybrace-bw*cubicshrink+bw*cubiccontrolfac, xl1-bw*cubiccontrolfac, ybrace, xl1, ybrace);
path.lineTo(xl2, ybrace);
path.cubicTo(xl2+bw*cubiccontrolfac, ybrace, (xl2+xr1)/2.0, ybrace+bw*cubicshrink-bw*cubiccontrolfac, (xl2+xr1)/2.0, ybrace+bw*cubicshrink);
path.cubicTo((xl2+xr1)/2.0, ybrace+bw*cubicshrink-bw*cubiccontrolfac, xr1-bw*cubiccontrolfac, ybrace, xr1, ybrace);
path.lineTo(xr2, ybrace);
path.cubicTo(xr2+bw*cubiccontrolfac, ybrace, xr2+bw*cubicshrink, ybrace-bw*cubicshrink+bw*cubiccontrolfac, xr2+bw*cubicshrink, ybrace-bw*cubicshrink);
path.moveTo(xleft_inner, ytop);
path.lineTo(xleft, ytop); // top-left flat
path.cubicTo(xleft, ytop+dxyControl, xleftflat_leftbottom-dxyControl, ycbottom, xleftflat_leftbottom, ycbottom);
path.lineTo(xleftflat_rightbottom,ycbottom); // left arm, bottom
path.cubicTo(xleftflat_rightbottom+dxyControl, ycbottom, xlefttip, ybottom-dxyControl, xlefttip, ybottom);
path.lineTo(xrighttip, ybottom); // bottom flat
path.cubicTo(xrighttip, ybottom-dxyControl,xrightflat_leftbottom-dxyControl, ycbottom, xrightflat_leftbottom, ycbottom);
path.lineTo(xrightflat_rightbottom, ycbottom); // right arm, bottom
path.cubicTo(xrightflat_rightbottom+dxyControl, ycbottom, xright, ytop+dxyControl, xright, ytop);
path.lineTo(xright_inner,ytop); // top-right flat
path.cubicTo(xright_inner, ytop+dxyControl, xrightflat_righttop+dxyControl, yctop, xrightflat_righttop, yctop);
path.lineTo(xrightflat_lefttop, yctop); // right arm, top
path.cubicTo(xrightflat_lefttop-dxyControl, yctop, x, yctop, x, ybottomtip); // center-tip
path.cubicTo(x, yctop, xleftflat_righttop+dxyControl, yctop, xleftflat_righttop, yctop);
path.lineTo(xleftflat_lefttop, yctop); // left arm, top
path.cubicTo(xleftflat_lefttop-dxyControl, yctop, xleft_inner,ytop+dxyControl, xleft_inner, ytop);
path.closeSubpath();
return path;
}

View File

@ -293,12 +293,22 @@ struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFontDefinition {
};
/** \brief create a QPainterPath for drawing horizontal braces
/** \brief create a QPainterPath for drawing horizontal braces, use QPainter::fillPath() with a vanishing line-width to draw this
* \ingroup jkqtmathtext_tools
*
* \image html jkqtmathtext/JKQTMathTextMakeHBracePath.png
*
* \param x x-center-position of the brace
* \param ybrace y-center-position of the brace
* \param width with of the overall brace
* \param height of the brace
* \param lineWidth linewidth when drawing, used for correcting so the brace exactly fills the rectangle and not overshoots it
* \param cubicshrink
* \param cubiccontrolfac
* \param lineWidthShrinkFactor the width of the tips is lineWidth reduced by this factor
* \param lineWidthGrowFactor the width of the horizontal bars is increased by this factor from lineWidth
*/
JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double cubicshrink=0.5, double cubiccontrolfac=0.3);
JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, double bw, double lineWidth, double cubicshrink=0.5, double cubiccontrolfac=0.3, double lineWidthShrinkFactor=0.3, double lineWidthGrowFactor=0.9);
/** \brief create a QPainterPath for drawing horizontal arrows

View File

@ -103,9 +103,14 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
QPen p=pold;
p.setWidthF(lw);
p.setColor(currentEv.color);
p.setCapStyle(Qt::FlatCap);
p.setJoinStyle(Qt::MiterJoin);
painter.setPen(p);
const double paren_fraction=0.85;
const double brace_fraction=0.65;
const double absnorm_linewidth_factor=0.75;
const double paren_topwidth=lw*0.75;
const double paren_centerwidth=lw*2.0;
{
bool showOpeningBrace=true;
const double xbrace1=xnew+lw;
@ -115,13 +120,29 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
path.moveTo(xbrace2, y1);
path.cubicTo(xbrace1, (y1+y2)/2.0+fabs(y1-y2)/6.0, xbrace1, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xbrace2, y2);
painter.drawPath(path);
const QPointF pb1(xbrace2-paren_topwidth/2.0, y1);
const QPointF pbc1(xbrace1-paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
const QPointF ptc1(xbrace1-paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
const QPointF pt1(xbrace2-paren_topwidth/2.0, y2);
const QPointF pt2(xbrace2+paren_topwidth/2.0, y2);
const QPointF ptc2(xbrace1+paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
const QPointF pbc2(xbrace1+paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
const QPointF pb2(xbrace2+paren_topwidth/2.0, y1);
path.moveTo(pb1);
path.cubicTo(pbc1, ptc1, pt1);
path.lineTo(pt2);
path.cubicTo(ptc2, pbc2, pb2);
path.closeSubpath();
painter.fillPath(path, QBrush(ev.color, Qt::SolidPattern));
painter.setPen("blue");
painter.drawLine(pb1,pbc1);
painter.drawLine(pt1,ptc1);
painter.drawLine(pb2,pbc2);
painter.drawLine(pt2,ptc2);
} else if (openbrace==MTBTSquareBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
const double y2=y-nodeBaselineHeight+lw/2.0;
path.moveTo(xbrace2s, y1);
path.lineTo(xbrace1, y1);
path.lineTo(xbrace1, y2);
@ -130,7 +151,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
} else if (openbrace==MTBTTopCorner) {
QPainterPath path;
const double dx=fabs(xbrace2s-xbrace1);
const double y1=y-nodeBaselineHeight;
const double y1=y-nodeBaselineHeight+lw/2.0;
path.moveTo(xbrace2s, y1);
path.lineTo(xbrace1, y1);
path.lineTo(xbrace1, y1+dx);
@ -138,21 +159,22 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
} else if (openbrace==MTBTBottomCorner) {
QPainterPath path;
const double dx=fabs(xbrace2s-xbrace1);
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
path.moveTo(xbrace2s, y1);
path.lineTo(xbrace1, y1);
path.lineTo(xbrace1, y1-dx);
painter.drawPath(path);
} else if (openbrace==MTBTCurlyBracket) {
QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction);
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction, p.widthF());
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.translate((xbrace1+xbrace2)/2.0, y-nodeBaselineHeight+nodeOverallHeight/2.0);
painter.rotate(90);
painter.drawPath(path);
QPen plocal=p;
plocal.setWidthF(0.0001);
painter.fillPath(path, QBrush(ev.color));
} else if (openbrace==MTBTFloorBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
const double y2=y-nodeBaselineHeight;
path.moveTo(xbrace2s, y1);
path.lineTo(xbrace1, y1);
@ -161,7 +183,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
} else if (openbrace==MTBTCeilBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const double y2=y-nodeBaselineHeight+lw/2.0;
path.moveTo(xbrace1, y1);
path.lineTo(xbrace1, y2);
path.lineTo(xbrace2s, y2);
@ -170,14 +192,22 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const QLineF l(xbrace1, y1, xbrace1, y2);
QPen plocal=p;
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
painter.setPen(plocal);
if (l.length()>0) painter.drawLine(l);
painter.setPen(p);
} else if (openbrace==MTBTDoubleLine) {
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
QPen plocal=p;
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
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);
if (l2.length()>0) painter.drawLine(l2);
painter.setPen(p);
} else if (openbrace==MTBTAngleBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
@ -208,13 +238,30 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
path.moveTo(xbrace1, y1);
path.cubicTo(xbrace2, (y1+y2)/2.0+fabs(y1-y2)/6.0, xbrace2, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xbrace1, y2);
painter.drawPath(path);
const QPointF pb1(xbrace1-paren_topwidth/2.0, y1);
const QPointF pbc1(xbrace2-paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
const QPointF ptc1(xbrace2-paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
const QPointF pt1(xbrace1-paren_topwidth/2.0, y2);
const QPointF pt2(xbrace1+paren_topwidth/2.0, y2);
const QPointF ptc2(xbrace2+paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
const QPointF pbc2(xbrace2+paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
const QPointF pb2(xbrace1+paren_topwidth/2.0, y1);
path.moveTo(pb1);
path.cubicTo(pbc1, ptc1, pt1);
path.lineTo(pt2);
path.cubicTo(ptc2, pbc2, pb2);
path.closeSubpath();
painter.fillPath(path, QBrush(ev.color, Qt::SolidPattern));
/*painter.setPen("blue");
painter.drawLine(pb1,pbc1);
painter.drawLine(pt1,ptc1);
painter.drawLine(pb2,pbc2);
painter.drawLine(pt2,ptc2);*/
} else if (closebrace==MTBTSquareBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
const double y2=y-nodeBaselineHeight+lw/2.0;
path.moveTo(xbrace1s, y1);
path.lineTo(xbrace2, y1);
path.lineTo(xbrace2, y2);
@ -223,7 +270,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
} else if (closebrace==MTBTBottomCorner) {
QPainterPath path;
const double dx=fabs(xbrace1s-xbrace2);
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
path.moveTo(xbrace1s, y1);
path.lineTo(xbrace2, y1);
path.lineTo(xbrace2, y1-dx);
@ -231,21 +278,29 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
} else if (closebrace==MTBTTopCorner) {
QPainterPath path;
const double dx=fabs(xbrace1s-xbrace2);
const double y1=y-nodeBaselineHeight;
const double y1=y-nodeBaselineHeight+lw/2.0;
path.moveTo(xbrace1s, y1);
path.lineTo(xbrace2, y1);
path.lineTo(xbrace2, y1+dx);
painter.drawPath(path);
} else if (closebrace==MTBTCurlyBracket) {
QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction);
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction, p.widthF());
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.translate((xbrace1+xbrace2)/2.0, y-nodeBaselineHeight+nodeOverallHeight/2.0);
painter.rotate(270);
painter.drawPath(path);
QPen plocal=p;
plocal.setWidthF(0.0001);
painter.fillPath(path, QBrush(ev.color));
/*QRectF r(0,0,nodeOverallHeight, bracewidth*brace_fraction);
r.moveCenter(QPointF(0,0));
painter.setPen("blue");
painter.drawRect(r);
painter.setPen("darkgreen");
painter.drawPath(path);*/
} else if (closebrace==MTBTFloorBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y1=y+(nodeOverallHeight-nodeBaselineHeight)-lw/2.0;
const double y2=y-nodeBaselineHeight;
path.moveTo(xbrace1s, y1);
path.lineTo(xbrace2, y1);
@ -254,7 +309,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
} else if (closebrace==MTBTCeilBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const double y2=y-nodeBaselineHeight+lw/2.0;
path.moveTo(xbrace2, y1);
path.lineTo(xbrace2, y2);
path.lineTo(xbrace1s, y2);
@ -263,14 +318,22 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const QLineF l(xbrace2, y1, xbrace2, y2);
QPen plocal=p;
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
painter.setPen(plocal);
if (l.length()>0) painter.drawLine(l);
painter.setPen(p);
} else if (closebrace==MTBTDoubleLine) {
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
const double y2=y-nodeBaselineHeight;
const QLineF l(xbrace2, y1, xbrace2, y2);
QPen plocal=p;
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);
if (l2.length()>0) painter.drawLine(l2);
painter.setPen(p);
} else if (closebrace==MTBTAngleBracket) {
QPainterPath path;
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);

View File

@ -248,9 +248,12 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
deltaWidth=xwidth;
} else if (mode==JKQTMathTextFracNode::MTFMunderbrace) {
double ybrace=y+descent1+bw/2.0;
const QPainterPath path=JKQTMathTextMakeHBracePath(x+xwidth/2.0+(width1)/2.0, ybrace, maxWidth, bw);
painter.drawPath(path);
{
const QPainterPath path=JKQTMathTextMakeHBracePath(x+xwidth/2.0+(width1)/2.0, ybrace, maxWidth, bw, 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);
deltaWidth=xwidth;
@ -265,8 +268,10 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
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);
painter.drawPath(path);
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0, maxWidth, bw, 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);