diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 4bdcf604c2..f1e11c9beb 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -26,7 +26,8 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
  • NEW: new "seaborn" style for plots
  • NEW/BREAKING CHANGE: changed JKQTPColorDerivationMode into a struct, which extends its capabilities above the previously available few enum-items
  • NEW: added debug-feature to show boxes around text in the plot
  • -
  • NEW: JKQTMathText supports new instructions: \cancel, \xcancel, \bcancel, \sout
  • +
  • NEW: JKQTMathText supports new decoration instructions: \cancel, \xcancel, \bcancel, \sout, \ocirc, \widetilde, \widehat, \breve
  • +
  • NEW: JKQTMathText: reworked drawing of decorations: improved appearance and positioning!
  • \subsection page_whatsnew_TRUNK_DOWNLOAD trunk: Download diff --git a/doc/images/mathparser/MTDarrow.png b/doc/images/mathparser/MTDarrow.png index 8a4607f618..4012f9c9f1 100644 Binary files a/doc/images/mathparser/MTDarrow.png and b/doc/images/mathparser/MTDarrow.png differ diff --git a/doc/images/mathparser/MTDbar.png b/doc/images/mathparser/MTDbar.png index 287a6e3ed6..e834682aed 100644 Binary files a/doc/images/mathparser/MTDbar.png and b/doc/images/mathparser/MTDbar.png differ diff --git a/doc/images/mathparser/MTDbreve.png b/doc/images/mathparser/MTDbreve.png new file mode 100644 index 0000000000..88df7d02ad Binary files /dev/null and b/doc/images/mathparser/MTDbreve.png differ diff --git a/doc/images/mathparser/MTDcheck.png b/doc/images/mathparser/MTDcheck.png new file mode 100644 index 0000000000..620a702fd3 Binary files /dev/null and b/doc/images/mathparser/MTDcheck.png differ diff --git a/doc/images/mathparser/MTDddot.png b/doc/images/mathparser/MTDddot.png index ed00b48b28..6066e570ea 100644 Binary files a/doc/images/mathparser/MTDddot.png and b/doc/images/mathparser/MTDddot.png differ diff --git a/doc/images/mathparser/MTDdot.png b/doc/images/mathparser/MTDdot.png index 8eb1493a63..a194c757c3 100644 Binary files a/doc/images/mathparser/MTDdot.png and b/doc/images/mathparser/MTDdot.png differ diff --git a/doc/images/mathparser/MTDdoubleoverline.png b/doc/images/mathparser/MTDdoubleoverline.png index 09636bd0fa..bc70e11844 100644 Binary files a/doc/images/mathparser/MTDdoubleoverline.png and b/doc/images/mathparser/MTDdoubleoverline.png differ diff --git a/doc/images/mathparser/MTDdoubleunderline.png b/doc/images/mathparser/MTDdoubleunderline.png index 8f5d9b1e6b..ed5c4e07c0 100644 Binary files a/doc/images/mathparser/MTDdoubleunderline.png and b/doc/images/mathparser/MTDdoubleunderline.png differ diff --git a/doc/images/mathparser/MTDhat.png b/doc/images/mathparser/MTDhat.png index 8ca1bfe277..0c2acba9b0 100644 Binary files a/doc/images/mathparser/MTDhat.png and b/doc/images/mathparser/MTDhat.png differ diff --git a/doc/images/mathparser/MTDocirc.png b/doc/images/mathparser/MTDocirc.png new file mode 100644 index 0000000000..2764499ecf Binary files /dev/null and b/doc/images/mathparser/MTDocirc.png differ diff --git a/doc/images/mathparser/MTDoverline.png b/doc/images/mathparser/MTDoverline.png index 75005713e7..0386308a88 100644 Binary files a/doc/images/mathparser/MTDoverline.png and b/doc/images/mathparser/MTDoverline.png differ diff --git a/doc/images/mathparser/MTDtilde.png b/doc/images/mathparser/MTDtilde.png index 0ef0850756..ab2ac0d775 100644 Binary files a/doc/images/mathparser/MTDtilde.png and b/doc/images/mathparser/MTDtilde.png differ diff --git a/doc/images/mathparser/MTDunderline.png b/doc/images/mathparser/MTDunderline.png index d30707b442..ad57894b8e 100644 Binary files a/doc/images/mathparser/MTDunderline.png and b/doc/images/mathparser/MTDunderline.png differ diff --git a/doc/images/mathparser/MTDvec.png b/doc/images/mathparser/MTDvec.png index f2f6c52bab..bb035a0ad3 100644 Binary files a/doc/images/mathparser/MTDvec.png and b/doc/images/mathparser/MTDvec.png differ diff --git a/doc/images/mathparser/MTDwidecheck.png b/doc/images/mathparser/MTDwidecheck.png new file mode 100644 index 0000000000..a938c671ea Binary files /dev/null and b/doc/images/mathparser/MTDwidecheck.png differ diff --git a/doc/images/mathparser/MTDwidehat.png b/doc/images/mathparser/MTDwidehat.png new file mode 100644 index 0000000000..738c5efe65 Binary files /dev/null and b/doc/images/mathparser/MTDwidehat.png differ diff --git a/doc/images/mathparser/MTDwidetilde.png b/doc/images/mathparser/MTDwidetilde.png new file mode 100644 index 0000000000..9533d83dfb Binary files /dev/null and b/doc/images/mathparser/MTDwidetilde.png differ diff --git a/doc/images/mathparser/decoration_sizing.png b/doc/images/mathparser/decoration_sizing.png new file mode 100644 index 0000000000..fd9e9d9c87 Binary files /dev/null and b/doc/images/mathparser/decoration_sizing.png differ diff --git a/doc/images/mathparser/decoration_sizing.svg b/doc/images/mathparser/decoration_sizing.svg new file mode 100644 index 0000000000..844fe872f5 --- /dev/null +++ b/doc/images/mathparser/decoration_sizing.svg @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + X + + + + + X + + + width_nonitalic + + width_possiblyitalic + + italic_xcorrectoin + + decoration + decoratedtext block + + + + decoration_width_reduction_Xfactor / 2 * width("X") + X + + + + + + + baseline_height + decoration_height_factor * baseline_height + X + + + width - italic_xcorrection + + diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp index d98cfa327c..58bdef11c2 100644 --- a/examples/jkqtmathtext_test/testform.cpp +++ b/examples/jkqtmathtext_test/testform.cpp @@ -29,7 +29,8 @@ TestForm::TestForm(QWidget *parent) : ui->cmbTestset->addItem("text 0", "text"); ui->cmbTestset->addItem("text 1", "text \\mathbf{bold}"); ui->cmbTestset->addItem("text 2", "text \\mathbf{bold}\\textcolor{red}{RED}"); - ui->cmbTestset->addItem("decoration: math", "$\\vec{x}\\vec{X}\\vec{\\psi} -- \\dot{x}\\dot{X}\\dot{\\psi} -- \\ddot{x}\\ddot{X}\\ddot{\\psi} -- \\overline{x}\\overline{X}\\overline{\\psi} -- \\underline{x}\\underline{X}\\underline{\\psi} -- \\hat{x}\\hat{X}\\hat{\\psi} -- \\tilde{x}\\tilde{X}\\tilde{\\psi} -- \\uul{x}\\uul{X}\\uul{\\psi} -- \\ool{x}\\ool{X}\\ool{\\psi} -- \\bar{x}\\bar{X}\\bar{\\psi} -- \\arrow{x}\\arrow{X}\\arrow{\\psi} -- \\cancel{x}\\cancel{X}\\cancel{\\psi} -- \\bcancel{x}\\bcancel{X}\\bcancel{\\psi} -- \\xcancel{x}\\xcancel{X}\\xcancel{\\psi} -- \\sout{x}\\sout{X}\\sout{\\psi}$"); + const auto mathDecoExample=[](const QString& deco)->QString { return "\\"+deco+"{x}\\"+deco+"{i}\\"+deco+"{X}\\"+deco+"{\\psi}\\"+deco+"{abc}"; }; + ui->cmbTestset->addItem("decoration: math", "$"+mathDecoExample("vec")+" -- "+mathDecoExample("dot")+" -- "+mathDecoExample("ddot")+" -- "+mathDecoExample("ocirc")+" -- "+mathDecoExample("overline")+" -- "+mathDecoExample("underline")+" -- "+mathDecoExample("hat")+" -- "+mathDecoExample("widehat")+" -- "+mathDecoExample("check")+" -- "+mathDecoExample("widecheck")+" -- "+mathDecoExample("breve")+" -- "+mathDecoExample("tilde")+" -- "+mathDecoExample("widetilde")+" -- "+mathDecoExample("uul")+" -- "+mathDecoExample("ool")+" -- "+mathDecoExample("bar")+" -- "+mathDecoExample("arrow")+" -- "+mathDecoExample("cancel")+" -- "+mathDecoExample("bcancel")+" -- "+mathDecoExample("xcancel")+" -- "+mathDecoExample("sout")+"$"); ui->cmbTestset->addItem("decoration: text", "Text \\ul{underlined Text Equator} -- \\ol{overlined Text Equator} -- \\sout{striked out Text Equator} -- \\cancel{canceled out Text Equator} -- \\bcancel{b-canceled out Text Equator} -- \\xcancel{x-canceled out Text Equator}"); ui->cmbTestset->addItem("mathtest", "This is normal text: $this is math:\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle\\ \\ \\ g(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1} \\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\left\\{\\va\\left|\\|\\va\\|_2\\geq2\\right.\\right\\} \\vr\\vR\\frac{\\sqrt{\\sqrt{\\sqrt{\\sum_{i=0}^\\infty \\hat{i}^2}+y^\\alpha}+1}}{\\dot{v}\\equiv\\ddot{r}}\\argmin_{\\vec{k}}\\sum_{\\sqrt{i}=0}^{N}\\int_{x_0}^{x_1}\\left(\\left(\\left(x\\right)\\right)\\right)\\underbrace{\\left[\\left\\{\\frac{\\partial f}{\\partial x}\\right\\}\\cdot\\frac{1}{2}\\right]}{\\text{underbraced text \\hbar}}\\cdots\\frac{\\sqrt{\\sum_{i=0}^2 \\hat{i}^2}+y^\\alpha}{\\dot{v}\\equiv\\ddot{r}}, \\hat{t}\\hat{T} \\overbrace{\\left|\\sqrt{x\\cdot Y}\\right|}{\\propto\\bbN\\circ\\bbZ} \\left<\\arrow{x(\\tau)}\\cdot\\vec{R}(t+\\bar{\\tau})\\right> \\alpha\\beta\\gamma\\delta\\epsilon\\Gamma\\Delta\\Theta\\Omega \\left\\_\\left~\\cbrt{\\hbar\\omega}\\right~\\right\\_$"); ui->cmbTestset->addItem("upper/lower parantheses test:", "$\\text{bblabla} \\frac{1}{2}\\cdot\\left(\\frac{1}{\\mathrm{e}^x+\\mathrm{e}^{-x}}\\right)\\cdot\\left(\\frac{1}{\\frac{1+2}{5+x}}\\right)\\cdot\\left(\\frac{1}{\\exp\\left[-\\frac{y^2}{\\sqrt{x}}\\right]\\cdot\\exp\\left[-\\frac{1}{\\frac{1}{2}}\\right]}\\right) $"); diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp index eb4a129d12..65568512c2 100644 --- a/lib/jkqtmathtext/jkqtmathtext.cpp +++ b/lib/jkqtmathtext/jkqtmathtext.cpp @@ -206,6 +206,21 @@ void JKQTMathText::MTnode::getSize(QPainter &painter, JKQTMathText::MTenvironmen if (s<1e5) strikeoutPos=s; } + +double JKQTMathText::MTnode::getNonItalicXCorretion(QPainter &painter, double width_potentiallyitalic, const MTenvironment &ev_potentiallyitalic, JKQTMathText::MTnode* child) const +{ + double italic_xcorrection=0.0; + if (ev_potentiallyitalic.italic) { + MTenvironment ev_nonitalic=ev_potentiallyitalic; + ev_nonitalic.italic=false; + double width_nonitalic=0, baselineHeight_nonitalic=0, overallHeight_nonitalic=0, strikeoutPos_nonitalic=0; + child->getSize(painter, ev_nonitalic, width_nonitalic, baselineHeight_nonitalic, overallHeight_nonitalic, strikeoutPos_nonitalic); + italic_xcorrection=width_potentiallyitalic-width_nonitalic; + } + return italic_xcorrection; +} + + bool JKQTMathText::MTnode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment /*currentEv*/, JKQTMathText::MTenvironment /*defaultEv*/) { return false; } @@ -1147,15 +1162,25 @@ JKQTMathText::MTdecoratedNode::~MTdecoratedNode() { } void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* /*prevNodeSize*/) { - QFontMetricsF fm(currentEv.getFont(parent), painter.device()); - double wc=fm.boundingRect("A").width(); - double dheightfactor=1.0+parent->getDecorationHeightFactor()*2.0; + const QFontMetricsF fm(currentEv.getFont(parent), painter.device()); child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); - overallHeight=overallHeight*dheightfactor; - baselineHeight=baselineHeight*dheightfactor; - width=width+0.3*wc; + const double italic_xcorrection=getNonItalicXCorretion(painter, width, currentEv, child); + const double decoheightfactor=parent->getDecorationHeightFactor(); + const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection; + + const double decoAboveAscent_yposdelta=fm.ascent()*(1.0+2.0*decoheightfactor); + const double decoAboveBaselineheight_yposdelta=baselineHeight*(1.0+decoheightfactor); + + + const double descent=overallHeight-baselineHeight; + baselineHeight=decoAboveBaselineheight_yposdelta; + if (decoration==MTDbar) { + baselineHeight=std::max(baselineHeight, decoAboveAscent_yposdelta); + } + overallHeight=baselineHeight+descent; + width=std::max(deco_miniwidth,width); } double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* /*prevNodeSize*/) { @@ -1163,135 +1188,198 @@ double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y MTenvironment ev=currentEv; double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); - QFontMetricsF fm(ev.getFont(parent), painter.device()); - double w=width; - double wc=fm.boundingRect("A").width(); - //double ll=wc*0.8; - double a=baselineHeight; - //double d=overallHeight-baselineHeight; - double dheightfactor=parent->getDecorationHeightFactor(); - double dpos=y-a*(1.0+dheightfactor); - double spos=y-a/2.0; - double dposb=y+qMax((overallHeight-baselineHeight)*(1.0+dheightfactor), fm.xHeight()*dheightfactor); - double deltax=0;//(wc-ll)/2.0; - double dheight=dheightfactor*a; + const QFont font=ev.getFont(parent); + const QFontMetricsF fm(font, painter.device()); + const double width_X=fm.boundingRect("X").width(); + const double width_x=fm.boundingRect("x").width(); + const double width_dot=fm.boundingRect(".").width()/2.0; + const double decoheightfactor=parent->getDecorationHeightFactor(); + const double deco_ypos=y-baselineHeight*(1.0+decoheightfactor); + const double decoAboveAscent_ypos=y-fm.ascent()*(1.0+decoheightfactor); + const double strike_ypos=y-baselineHeight/2.0; + const double decobelow_ypos=y+qMax((overallHeight-baselineHeight)*(1.0+decoheightfactor), fm.xHeight()*decoheightfactor); + const double deco_height=decoheightfactor*baselineHeight; + const double italic_xcorrection=getNonItalicXCorretion(painter, width, ev, child); + const double deco_xoffset=parent->getDecorationWidthReductionXFactor()*width_X/2.0; + const double deco_width=std::max(width_x*0.5,width-2.0*deco_xoffset-italic_xcorrection); + const double deco_vecwidth=width_x*0.33; + const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection; + const double decotop_xcenter=x+italic_xcorrection+(width-italic_xcorrection)/2.0; + const double decotop_xstart=decotop_xcenter-deco_width/2.0; + const double decotop_xend=decotop_xcenter+deco_width/2.0; + const double decobot_xstart=x; + const double decobot_xend=x+width-italic_xcorrection; + const double decobot_xcenter=(decobot_xstart+decobot_xend)/2.0; + - if (ev.italic) deltax+=0.1*fm.boundingRect("A").width(); QPen pold=painter.pen(); QPen p=pold; p.setColor(ev.color); p.setWidthF(qMax(JKQTMathText::ABS_MIN_LINEWIDTH, fm.lineWidth()));//ceil(currentEv.fontSize/16.0)); - if (decoration==MTDbar) ev.overline=true; + double xnew=child->draw(painter, x, y, ev); + if (decoration==MTDvec) { painter.setPen(p); QPolygonF poly; - poly<0) painter.drawLine(l); + painter.setPen(pold); + } else if (decoration==MTDbar) { + painter.setPen(p); + const QLineF l(decotop_xstart, decoAboveAscent_ypos, decotop_xend, decoAboveAscent_ypos); if (l.length()>0) painter.drawLine(l); painter.setPen(pold); } else if (decoration==MTDdoubleoverline) { painter.setPen(p); - QLineF l(x+deltax, dpos, xnew+deltax-0.2*wc, dpos); - if (l.length()>0) painter.drawLine(l); - l=QLineF(x+deltax, dpos-2.0*p.widthF(), xnew+deltax-0.2*wc, dpos-2.0*p.widthF()); + const QLineF l(decotop_xstart, deco_ypos, decotop_xend, deco_ypos); if (l.length()>0) painter.drawLine(l); + const QLineF l2(decotop_xstart, deco_ypos-2.0*p.widthF(), decotop_xend, deco_ypos-2.0*p.widthF()); + if (l2.length()>0) painter.drawLine(l2); painter.setPen(pold); } else if (decoration==MTDunderline) { painter.setPen(p); - QLineF l(x+deltax, dposb, xnew+deltax-0.2*wc, dposb); + const QLineF l(decobot_xstart, decobelow_ypos, decobot_xend, decobelow_ypos); if (l.length()>0) painter.drawLine(l); painter.setPen(pold); } else if (decoration==MTDdoubleunderline) { painter.setPen(p); - QLineF l(x+deltax, dposb, xnew+deltax-0.2*wc, dposb); - if (l.length()>0) painter.drawLine(l); - l=QLineF(x+deltax, dposb+2.0*p.widthF(), xnew+deltax-0.2*wc, dposb+2.0*p.widthF()); + const QLineF l(decobot_xstart, decobelow_ypos, decobot_xend, decobelow_ypos); if (l.length()>0) painter.drawLine(l); + QLineF l2(decobot_xstart, decobelow_ypos+2.0*p.widthF(), decobot_xend, decobelow_ypos+2.0*p.widthF()); + if (l2.length()>0) painter.drawLine(l2); painter.setPen(pold); } else if (decoration==MTDarrow) { painter.setPen(p); - QLineF l(x+deltax, dpos+dheight/2.0, xnew+deltax-0.2*wc, dpos+dheight/2.0); + const QLineF l(decotop_xstart, deco_ypos+deco_height/2.0, decotop_xend, deco_ypos+deco_height/2.0); if (l.length()>0) painter.drawLine(l); QPolygonF poly; - poly<0) painter.drawLine(l); painter.setPen(pold); } else if (decoration==MTDcancel) { painter.setPen(p); - QLineF l(x+deltax, dposb, xnew+deltax-0.2*wc, dpos); + const QLineF l(decobot_xstart, decobelow_ypos, decotop_xend, deco_ypos); if (l.length()>0) painter.drawLine(l); painter.setPen(pold); } else if (decoration==MTDbcancel) { painter.setPen(p); - QLineF l(x+deltax, dpos, xnew+deltax-0.2*wc, dposb); + const QLineF l(decobot_xstart, deco_ypos, decotop_xend, decobelow_ypos); if (l.length()>0) painter.drawLine(l); painter.setPen(pold); } else if (decoration==MTDxcancel) { painter.setPen(p); - QLineF l(x+deltax, dpos, xnew+deltax-0.2*wc, dposb); + const QLineF l(decobot_xstart, deco_ypos, decotop_xend, decobelow_ypos); if (l.length()>0) painter.drawLine(l); - QLineF l1(x+deltax, dposb, xnew+deltax-0.2*wc, dpos); + const QLineF l1(decobot_xstart, decobelow_ypos, decotop_xend, deco_ypos); if (l1.length()>0) painter.drawLine(l1); painter.setPen(pold); } - // - return xnew+0.3*wc; + + /*painter.setPen(QPen(Qt::red, 1.5)); + painter.drawLine(QLineF(x, deco_ypos, xnew, deco_ypos)); + painter.setPen(QPen(Qt::green, 1.5)); + painter.drawLine(QLineF(deco_xstart, deco_ypos+2, deco_xend, deco_ypos+2)); + painter.drawEllipse(QPointF(deco_xpos_center, deco_ypos+2), 5, 5); + painter.setPen(pold);*/ + return xnew; } bool JKQTMathText::MTdecoratedNode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment /*currentEv*/, JKQTMathText::MTenvironment /*defaultEv*/) { @@ -3348,6 +3436,7 @@ JKQTMathText::JKQTMathText(QObject* parent): underbrace_factor=0.75; undersetFactor=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; mathoperator_width_factor=1.5; @@ -3483,6 +3572,7 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group) 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(); + decoration_width_reduction_Xfactor=settings.value(group+"decoration_width_reduction_xfactor", decoration_width_reduction_Xfactor).toDouble(); 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(); @@ -3510,6 +3600,7 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const 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); + settings.setValue(group+ "decoration_width_reduction_xfactor", decoration_width_reduction_Xfactor); } bool JKQTMathText::useSTIX(bool mathModeOnly) { @@ -4046,6 +4137,16 @@ double JKQTMathText::getDecorationHeightFactor() const return this->decoration_height_factor; } +void JKQTMathText::setDecorationWidthReductionXFactor(double __value) +{ + decoration_width_reduction_Xfactor=__value; +} + +double JKQTMathText::getDecorationWidthReductionXFactor() const +{ + return decoration_width_reduction_Xfactor; +} + void JKQTMathText::setExpensiveRendering(bool __value) { this->expensiveRendering = __value; @@ -4357,14 +4458,26 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu nl->addNode(new MTdecoratedNode(this, MTDdoubleoverline, parseLatexString(true))); } else if (name=="arrow"||name=="overrightarrow"||name=="overarrow") { nl->addNode(new MTdecoratedNode(this, MTDarrow, parseLatexString(true))); - } else if (name=="hat") { + } else if (name=="hat" || name=="^") { nl->addNode(new MTdecoratedNode(this, MTDhat, parseLatexString(true))); + } else if (name=="widehat") { + nl->addNode(new MTdecoratedNode(this, MTDwidehat, parseLatexString(true))); + } else if (name=="check" || name=="v") { + nl->addNode(new MTdecoratedNode(this, MTDcheck, parseLatexString(true))); + } else if (name=="widecheck") { + nl->addNode(new MTdecoratedNode(this, MTDwidecheck, parseLatexString(true))); } else if (name=="bar") { nl->addNode(new MTdecoratedNode(this, MTDbar, parseLatexString(true))); - } else if (name=="dot") { + } else if (name=="dot" || name==".") { nl->addNode(new MTdecoratedNode(this, MTDdot, parseLatexString(true))); - } else if (name=="tilde") { + } else if (name=="ocirc") { + nl->addNode(new MTdecoratedNode(this, MTDocirc, parseLatexString(true))); + } else if (name=="tilde" || name=="~") { nl->addNode(new MTdecoratedNode(this, MTDtilde, parseLatexString(true))); + } else if (name=="breve" || name=="u") { + nl->addNode(new MTdecoratedNode(this, MTDbreve, parseLatexString(true))); + } else if (name=="widetilde") { + nl->addNode(new MTdecoratedNode(this, MTDwidetilde, parseLatexString(true))); } else if (name=="ddot") { nl->addNode(new MTdecoratedNode(this, MTDddot, parseLatexString(true))); } else if (name=="cancel") { @@ -4635,6 +4748,13 @@ QRectF JKQTMathText::getTightBoundingRect(const QFont &fm, const QString &text, return d.tbr; } +QFont JKQTMathText::getNonItalic(const QFont &font) +{ + QFont f=font; + f.setItalic(false); + return f; +} + @@ -4817,8 +4937,20 @@ QString JKQTMathText::decorationToString(JKQTMathText::MTdecoration mode) return "vec"; case MTDtilde: return "tilde"; + case MTDbreve: + return "breve"; + case MTDwidetilde: + return "widetilde"; case MTDhat: return "hat"; + case MTDwidehat: + return "widehat"; + case MTDcheck: + return "check"; + case MTDwidecheck: + return "widecheck"; + case MTDocirc: + return "ocirc"; case MTDdot: return "dot"; case MTDddot: diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h index 74d4f14b16..ace3500525 100644 --- a/lib/jkqtmathtext/jkqtmathtext.h +++ b/lib/jkqtmathtext/jkqtmathtext.h @@ -584,11 +584,16 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { void setBraceYShiftFactor(double __value); /** \copydoc brace_y_shift_factor */ double getBraceYShiftFactor() const; - /** \copydoc decoration_height_factor */ + + /** \copydoc decoration_height_factor */ void setDecorationHeightFactor(double __value); - /** \copydoc decoration_height_factor */ + /** \copydoc decoration_height_factor */ double getDecorationHeightFactor() const; - /** \copydoc expensiveRendering */ + /** \copydoc decoration_width_reduction_Xfactor */ + void setDecorationWidthReductionXFactor(double __value); + /** \copydoc decoration_width_reduction_Xfactor */ + double getDecorationWidthReductionXFactor() const; + /** \copydoc expensiveRendering */ void setExpensiveRendering(bool __value); /** \copydoc expensiveRendering */ bool getExpensiveRendering() const; @@ -676,6 +681,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { * */ void getSize(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr); + /** \brief calculates the x-size-difference between the given (probably) italic (width externally calculated: \A width_potentiallyitalic, \a ev_potentiallyitalic) and the non-italic version of \a child */ + double getNonItalicXCorretion(QPainter &painter, double width_potentiallyitalic, const MTenvironment &ev_potentiallyitalic, JKQTMathText::MTnode* child) const; /** \brief draw the contents at the designated position * * \param painter QPainter to use @@ -741,10 +748,12 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /** \copydoc text */ QString getText() const; + /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override ; protected: /** \copydoc MTnode::getSizeInternal() */ virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; + /** \brief text-contents of the node */ QString text; /** \brief transforms the text before sizing/drawing (may e.g. exchange special letters for other unicode symbols etc.) */ virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false); @@ -771,7 +780,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual ~MTwhitespaceNode() override; /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override; - /** \brief convert node to HTML and returns \c true on success */ /** \copydoc MTnode::toHtml() */ virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; }; @@ -791,7 +799,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /** \copydoc symbolName */ QString getSymbolName() const; + /** \brief get font name of the symbol */ QString getSymbolfontName() const; + /** \copydoc addWhitespace */ bool getAddWhitespace() const; protected: /** \copydoc MTnode::getSizeInternal() */ @@ -847,6 +857,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual QString getTypeName() const override; /** \copydoc MTnode::draw() */ virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; + /** \brief add a child node */ void addNode(MTnode* n) { nodes.append(n); } /** \copydoc MTnode::toHtml() */ virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; @@ -908,7 +919,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override; /** \brief returns the child node */ - MTnode *getChild() const; + /** \brief returns the child node */ + MTnode *getChild() const; /** \copydoc MTnode::toHtml() */ virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /** \copydoc MTnode::setDrawBoxes() */ @@ -1002,6 +1014,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /** \copydoc MTnode::setDrawBoxes() */ virtual void setDrawBoxes(bool draw) override; + /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override ; /** \brief returns the child node */ MTnode *getChild() const; @@ -1036,6 +1049,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { public: MTfracNode(JKQTMathText* parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode); virtual ~MTfracNode() override; + /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override; /** \copydoc MTnode::draw() */ virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override; @@ -1084,10 +1098,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { int lines; }; - + /** \brief types of decoration available in a MTdecoratedNode */ enum MTdecoration { MTDvec, /*!< \brief vector arrow over block \image html mathparser/MTDvec.png */ - MTDhat, /*!< \brief hat over block \image html mathparser/MTDhat.png */ + MTDhat, /*!< \brief small hat over block \image html mathparser/MTDhat.png */ + MTDwidehat, /*!< \brief full-width hat over block \image html mathparser/MTDwidehat.png */ + MTDcheck, /*!< \brief small v over block \image html mathparser/MTDcheck.png */ + MTDwidecheck, /*!< \brief full-width v over block \image html mathparser/MTDwidecheck.png */ + MTDbreve, /*!< \brief small tilde over block \image html mathparser/MTDbreve.png */ + MTDocirc, /*!< \brief single circle over block \image html mathparser/MTDocirc.png */ MTDdot, /*!< \brief single dot over block \image html mathparser/MTDvec.png */ MTDddot, /*!< \brief double dot over block \image html mathparser/MTDddot.png */ MTDbar, /*!< \brief bar over block \image html mathparser/MTDbar.png */ @@ -1096,7 +1115,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { MTDdoubleoverline, /*!< \brief double overline over block \image html mathparser/MTDdoubleoverline.png */ MTDunderline, /*!< \brief underline under block \image html mathparser/MTDunderline.png */ MTDdoubleunderline, /*!< \brief double underline under block \image html mathparser/MTDdoubleunderline.png */ - MTDtilde, /*!< \brief tilde over block \image html mathparser/MTDtilde.png */ + MTDtilde, /*!< \brief small tilde over block \image html mathparser/MTDtilde.png */ + MTDwidetilde, /*!< \brief full width tilde over block \image html mathparser/MTDwidetilde.png */ MTDcancel, /*!< \brief cancel text with sloped line \image html mathparser/MTDcancel.png */ MTDbcancel, /*!< \brief cancel text with backward sloped line \image html mathparser/MTDbcancel.png */ MTDxcancel, /*!< \brief cancel text with X \image html mathparser/MTDxcancel.png */ @@ -1107,6 +1127,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { /** \brief subclass representing a decorated text m (e.g. \c \\vec \c \\hat ...) node * \ingroup jkqtmathtext_items + * + * \image html mathparser/decoration_sizing.png + * */ class JKQTMATHTEXT_LIB_EXPORT MTdecoratedNode: public MTnode { public: @@ -1118,6 +1141,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; /** \copydoc MTnode::setDrawBoxes() */ virtual void setDrawBoxes(bool draw) override; + /** \copydoc MTnode::getTypeName() */ virtual QString getTypeName() const override ; /** \brief returns the child node */ MTnode* getChild() const; @@ -1126,7 +1150,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { protected: /** \copydoc MTnode::getSizeInternal() */ virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override; + /** \brief child node that is decorated by this node */ MTnode* child; + /** \brief type of decoration that is added to the child node */ MTdecoration decoration; }; @@ -1198,8 +1224,16 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { double undersetFactor; /** \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 fractio of the baselineheight */ + /** \brief size of the decorations (dot, tilde, ...), as fraction of the baselineheight + * + * \image html mathparser/decoration_sizing.png + */ double decoration_height_factor; + /** \brief a decoration has a size, which is slightly smaller than the text- width. the width is reduced by \c decoration_width_reduction_Xfactor*width("X") and the position is centered around the child-box. Also an italic correction is applied: + * + * \image html mathparser/decoration_sizing.png + */ + double decoration_width_reduction_Xfactor; /** \brief switches on some options that will grant better rendering at the expense of higher time consumption */ bool expensiveRendering; /** \brief a list that will be filled with error messages while parsing, if any error occur */ @@ -1275,7 +1309,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject { static QList tbrs; static QHash tbrh; static QRectF getTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd); - + /** \brief returns a copy of \a f, but with the italic-property set to \c false */ + static QFont getNonItalic(const QFont& f); };