diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index 6485321c9e..494f6c354f 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -47,7 +47,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: improved frac-rendering: font-scaling takes nesting-level into account, overall-rendering, sizes, if a brace surrounds a frac, the heights are equal above and below to center the brace , ...
NEW: shows strikeoutPos when drawing Debug-Boxes
NEW: LaTeX-Parser understands optional instruction parameters in [...] now
- NEW: LaTeX-Parser simplifies parrse-tree to increase speed of execution
+ NEW: LaTeX-Parser simplifies parse-tree to increase speed of execution
NEW: \limits and \nolimits works as in LaTeX now (before it was simply removed and the functionality implemented for a fixed list of symbols)
NEW: added top-corner (\ulcorner/\urcorner) and bottom-corner brackets (\llcorner/\lrcorner)
NEW: added \overbracket and \underbracket
diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp
index ce3ce5cf12..45ce7f86c6 100644
--- a/examples/jkqtmathtext_test/testform.cpp
+++ b/examples/jkqtmathtext_test/testform.cpp
@@ -369,7 +369,8 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
if (fracN->getChild1()) ti->addChild(createTree(fracN->getChild1(), ti));
if (fracN->getChild2()) ti->addChild(createTree(fracN->getChild2(), ti));
} else if (sqrtN) {
- name=QString("MTsqrtNode: deg=%1").arg(sqrtN->getDegree());
+ name=QString("MTsqrtNode");
+ if (sqrtN->getChildDegree()) ti->addChild(createTree(sqrtN->getChildDegree(), ti));
if (sqrtN->getChild()) ti->addChild(createTree(sqrtN->getChild(), ti));
} else if (braceN) {
name=QString("MTbraceNode: l='%1', r='%2'").arg(JKQTMathTextBraceType2String(braceN->getOpenbrace())).arg(JKQTMathTextBraceType2String(braceN->getClosebrace()));
diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp
index e8b14ced3c..27eb754957 100644
--- a/lib/jkqtmathtext/jkqtmathtext.cpp
+++ b/lib/jkqtmathtext/jkqtmathtext.cpp
@@ -1146,7 +1146,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
if (currentInstructionName=="sqrt") {
nl->addChild(new JKQTMathTextSqrtNode(this, parseLatexString(true)));
} else if (currentInstructionName=="cbrt") {
- nl->addChild(new JKQTMathTextSqrtNode(this, parseLatexString(true), 3));
+ nl->addChild(new JKQTMathTextSqrtNode(this, parseLatexString(true), new JKQTMathTextTextNode(this, "3", false)));
} else if (currentInstructionName=="verb") {
QString text="";
currentTokenID++;
@@ -1370,24 +1370,11 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
//std::cout<<"found '[' after '"<(n1);
- JKQTMathTextTextNode* n1txt=dynamic_cast(n1);
- if (n1lst && n1lst->childCount()==1) {
- n1txt=dynamic_cast(n1lst->getChild(0));
- }
- int degree=2;
- bool ok=false;
- if (n1txt) degree=n1txt->getText().toInt(&ok);
- if (!ok) {
- degree=2;
- error_list.append(tr("error @ ch. %1: an integer in [] after '%2' command").arg(currentTokenID).arg(currentInstructionName));
- }
-
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
else error_list.append(tr("error @ ch. %1: expected one argument in '{' braces after '%2' command with an optional argument in []").arg(currentTokenID).arg(currentInstructionName));
- if (n1 && n2) nl->addChild(new JKQTMathTextSqrtNode(this, n2, degree));
+ if (n1 && n2) nl->addChild(new JKQTMathTextSqrtNode(this, n2, n1));
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
} else {
nl->addChild(new JKQTMathTextTextNode(this, "[", false));
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp
index 66d072e981..bd8a44d535 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp
@@ -35,21 +35,24 @@
-JKQTMathTextSqrtNode::JKQTMathTextSqrtNode(JKQTMathText* _parent, JKQTMathTextNode* child, int degree):
- JKQTMathTextSingleChildNode(child, _parent)
+JKQTMathTextSqrtNode::JKQTMathTextSqrtNode(JKQTMathText* _parent, JKQTMathTextNode* child__, JKQTMathTextNode *childDegree__):
+ JKQTMathTextMultiChildNode(_parent),
+ child(child__), childDegree(childDegree__)
{
- this->degree=degree;
+ if (child) child->setParentNode(this);
+ if (childDegree) childDegree->setParentNode(this);
}
JKQTMathTextSqrtNode::~JKQTMathTextSqrtNode() {
+ if (child) delete child; child=nullptr;
+ if (childDegree) delete childDegree; childDegree=nullptr;
}
void JKQTMathTextSqrtNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
- QFont fsmall=currentEv.getFont(parentMathText);
- fsmall.setPointSizeF(fsmall.pointSizeF()*parentMathText->getSqrtSmallFontFactor());
- fsmall.setItalic(false);
- const QFontMetricsF fmsmall(fsmall, painter.device());
+ JKQTMathTextEnvironment evSmall=currentEv;
+ evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
+ evSmall.italic=false;
getChild()->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos);
const double descent=overallHeight-baselineHeight;
@@ -60,9 +63,9 @@ void JKQTMathTextSqrtNode::getSizeInternal(QPainter& painter, JKQTMathTextEnviro
overallHeight=newAscent+newDescent;;
baselineHeight=newAscent;
width=width+sqrtwidth;
- if (degree!=2) {
- const QString degreetext=QLocale::c().toString(degree);
- const double degwidth=fmsmall.width(degreetext);
+ if (childDegree) {
+ double degwidth=0, degBH=0, degOH=0, degSP=0;
+ childDegree->getSize(painter, evSmall, degwidth, degBH, degOH, degSP);
const double smalltextIndent=0.6*sqrtwidth;
if (degwidth>smalltextIndent) width=width+(degwidth-smalltextIndent);
}
@@ -72,11 +75,10 @@ double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMat
doDrawBoxes(painter, x, y, currentEv);
const QFont f=currentEv.getFont(parentMathText);
- QFont fsmall=f;
const QFontMetricsF fm(f, painter.device());
- fsmall.setPointSizeF(fsmall.pointSizeF()*parentMathText->getSqrtSmallFontFactor());
- fsmall.setItalic(false);
- const QFontMetricsF fmsmall(fsmall, painter.device());
+ JKQTMathTextEnvironment evSmall=currentEv;
+ evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
+ evSmall.italic=false;
double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0;
getChild()->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos);
@@ -87,9 +89,10 @@ double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMat
const double linewidth=fm.lineWidth();
const double tinyhookSize=sqrtwidth*0.1;
const double smalltextIndent=0.6*sqrtwidth;
- const QString degreetext=(degree!=2)?QLocale::c().toString(degree):"";
- const double degwidth=fmsmall.width(degreetext);
- const double degheight=fmsmall.boundingRect(degreetext).height();
+
+ double degwidth=0, degBH=0, degOH=0, degSP=0;
+ if (childDegree) childDegree->getSize(painter, evSmall, degwidth, degBH, degOH, degSP);
+ const double degheight=degOH;
const double degree_overwidth=(degwidth>smalltextIndent)?(degwidth-smalltextIndent):0.0;
//painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@@ -111,7 +114,7 @@ double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMat
const double x_hookbottom=(!useAltForm)?(x_start+0.33*sqrtwidth):(x_start+0.66*sqrtwidth);
const double x_hooktop=(!useAltForm)?(x_start+sqrtwidth):x_hookbottom;
const double x_smalltextend=x_start+smalltextIndent;
- const double y_smalltext=y_top+fmsmall.ascent()+(fabs(y_top-(y_tinyhooktop-linewidth))-degheight)/2.0;
+ const double y_smalltext=y_top+degBH+(fabs(y_top-(y_tinyhooktop-linewidth))-degheight)/2.0;
if (sqrtwidth>0) {
QPainterPath path;
path.moveTo(x_start, y_tinyhooktop+tinyhookSize);
@@ -125,17 +128,25 @@ double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMat
painter.setPen(p);
painter.drawPath(path);
}
- if (degree!=2) {
- painter.setFont(fsmall);
- painter.drawText(QPointF(x_smalltextend-degwidth, y_smalltext), degreetext);
+ if (childDegree) {
+ childDegree->draw(painter, x_smalltextend-degwidth, y_smalltext, evSmall);
}
return xnew;
}
bool JKQTMathTextSqrtNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) {
+ bool ok=true;
+ if (childDegree) {
+ JKQTMathTextEnvironment evSmall=currentEv;
+ evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
+ evSmall.italic=false;
+ html=html+"";
+ ok=ok&&childDegree->toHtml(html, evSmall, defaultEv);
+ html=html+"";
+ }
html=html+"√";
- bool ok=getChild()->toHtml(html, currentEv, defaultEv);
+ ok=ok&&getChild()->toHtml(html, currentEv, defaultEv);
html=html+" ";
return ok;
}
@@ -145,8 +156,71 @@ QString JKQTMathTextSqrtNode::getTypeName() const
return "MTsqrtNode";
}
-int JKQTMathTextSqrtNode::getDegree() const {
- return this->degree;
+JKQTMathTextNode *JKQTMathTextSqrtNode::getChild()
+{
+ return child;
}
+const JKQTMathTextNode *JKQTMathTextSqrtNode::getChild() const
+{
+ return child;
+}
+
+JKQTMathTextNode *JKQTMathTextSqrtNode::getChildDegree()
+{
+ return childDegree;
+}
+
+const JKQTMathTextNode *JKQTMathTextSqrtNode::getChildDegree() const
+{
+ return childDegree;
+}
+
+JKQTMathTextNode *JKQTMathTextSqrtNode::getChild(int i)
+{
+ if (i==0) return child;
+ if (i==1) return childDegree;
+ return nullptr;
+}
+
+const JKQTMathTextNode *JKQTMathTextSqrtNode::getChild(int i) const
+{
+ if (i==0) return child;
+ if (i==1) return childDegree;
+ return nullptr;
+}
+
+JKQTMathTextNode *JKQTMathTextSqrtNode::replaceChild(int i, JKQTMathTextNode *newChild)
+{
+ if (i==0) {
+ JKQTMathTextNode* c=child;
+ child=newChild;
+ if (child) child->setParentNode(this);
+ return c;
+ }
+ if (i==1) {
+ JKQTMathTextNode* c=childDegree;
+ childDegree=newChild;
+ if (childDegree) childDegree->setParentNode(this);
+ return c;
+ }
+}
+
+int JKQTMathTextSqrtNode::childCount() const
+{
+ if (childDegree) return 2;
+ return 1;
+}
+
+void JKQTMathTextSqrtNode::clearChildren(bool deleteChildren)
+{
+ if (child) {
+ if (deleteChildren) delete child;
+ child=nullptr;
+ }
+ if (childDegree) {
+ if (deleteChildren) delete childDegree;
+ childDegree=nullptr;
+ }
+}
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h
index a14da4087d..52948eddd1 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h
@@ -40,9 +40,9 @@ class JKQTMathText; // forward
* \image html jkqtmathtext/jkqtmathtext_sqrt.png
* \image html jkqtmathtext/jkqtmathtext_cbrt.png
*/
-class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSqrtNode: public JKQTMathTextSingleChildNode {
+class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSqrtNode: public JKQTMathTextMultiChildNode {
public:
- JKQTMathTextSqrtNode(JKQTMathText* parent, JKQTMathTextNode* child, int degree=2);
+ JKQTMathTextSqrtNode(JKQTMathText* parent, JKQTMathTextNode* child__, JKQTMathTextNode* childDegree__=nullptr);
virtual ~JKQTMathTextSqrtNode() override;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
@@ -50,13 +50,34 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSqrtNode: public JKQTMathTextSingleChi
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override ;
- /** \copydoc degree */
- int getDegree() const;
+
+ /** \copydoc child */
+ JKQTMathTextNode* getChild();
+ /** \copydoc child */
+ const JKQTMathTextNode* getChild() const;
+ /** \copydoc childDegree */
+ JKQTMathTextNode* getChildDegree();
+ /** \copydoc childDegree */
+ const JKQTMathTextNode* getChildDegree() const;
+
+ /** \copydoc JKQTMathTextMultiChildNode::getChild() */
+ virtual JKQTMathTextNode* getChild(int i) override;
+ /** \copydoc JKQTMathTextMultiChildNode::getChild() */
+ virtual const JKQTMathTextNode* getChild(int i) const override;
+ /** \copydoc JKQTMathTextMultiChildNode::getChild() */
+ virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) override;
+ /** \copydoc JKQTMathTextMultiChildNode::getChild() */
+ virtual int childCount() const override;
+ /** \copydoc JKQTMathTextMultiChildNode::getChild() */
+ virtual void clearChildren(bool deleteChildren=true) override;
+
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
- /** \brief degree of the radical (shown of !=2) */
- int degree;
+ /** \brief child node for the part under the root */
+ JKQTMathTextNode* child;
+ /** \brief second child node for the degree of the root (or nullptr if nothing) */
+ JKQTMathTextNode* childDegree;
};
#endif // JKQTMATHTEXTSQRTNODE_H