- reworked how MTsubscriptNode/MTsuperscriptNode operate, also when the previous node was a brace (i.e. special shifts of sub/superscript)

- improved documentation
- fixed a bug in \overbrace
This commit is contained in:
Jan W. Krieger 2019-02-10 22:21:19 +01:00
parent 3050debd16
commit 2400245e94
11 changed files with 468 additions and 386 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -8,6 +8,7 @@ TestForm::TestForm(QWidget *parent) :
ui(new Ui::TestForm) ui(new Ui::TestForm)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->cmbTestset->addItem("subsuperscript test", "$r_{123}^2$\\ \\ $r^2_{123}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_{123}^2$\\ \\ $\\left(\\stackrel{a}{b}\\right)^2_{123}$\\ \\ $r_{\\frac{1}{2}}^2$\\ \\ $r^2_{\\frac{1}{2}}$\\ \\ $r^{\\frac{1}{2}}_2$\\ \\ $r_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)_2^{\\frac{1}{2}}$\\ \\ $\\left(\\stackrel{a}{b}\\right)^{\\frac{1}{2}}_2$");
ui->cmbTestset->addItem("simple relations", "$a{\\leq}b$, $a{\\geq}b$, $a{\\equiv}b$, $a=b$, $a{\\neq}b$, $a<b$, $a>b$"); ui->cmbTestset->addItem("simple relations", "$a{\\leq}b$, $a{\\geq}b$, $a{\\equiv}b$, $a=b$, $a{\\neq}b$, $a<b$, $a>b$");
ui->cmbTestset->addItem("simple relations in different modes", "math: $a{\\leq}b$, math/no braces: $a\\leq b$, no math: a{\\leq}b, no math/no braces: a\\leq b"); ui->cmbTestset->addItem("simple relations in different modes", "math: $a{\\leq}b$, math/no braces: $a\\leq b$, no math: a{\\leq}b, no math/no braces: a\\leq b");
ui->cmbTestset->addItem("named symbols 1", "ll: $\\ll$\\ gg: $\\gg$\\ leq: $\\leq$\\ geq: $\\geq$\\ pm: $\\pm$\\ mp: $\\mp$\\ "); ui->cmbTestset->addItem("named symbols 1", "ll: $\\ll$\\ gg: $\\gg$\\ leq: $\\leq$\\ geq: $\\geq$\\ pm: $\\pm$\\ mp: $\\mp$\\ ");
@ -41,7 +42,6 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("math: bf", "$\\mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); ui->cmbTestset->addItem("math: bf", "$\\mathbf{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$");
ui->cmbTestset->addItem("math: rm", "$\\mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); ui->cmbTestset->addItem("math: rm", "$\\mathrm{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$");
ui->cmbTestset->addItem("math: cal", "$\\mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$"); ui->cmbTestset->addItem("math: cal", "$\\mathcal{ABCDEFGHIJKLMNOPQRSTUVWXYZ120}$");
ui->cmbTestset->addItem("subsuperscript test", "$r_{123}^2$\\ \\ $r^2_{123}$\\ \\ $\\left(a\\right)_{123}^2$\\ \\ $\\left(a\\right)^2_{123}$\\ \\ $r_{\\frac{1}{2}}^2$\\ \\ $r^2_{\\frac{1}{2}}$\\ \\ $r^{\\frac{1}{2}}_2$\\ \\ $r_2^{\\frac{1}{2}}$\\ \\ $\\left(a\\right)_2^{\\frac{1}{2}}$\\ \\ $\\left(a\\right)^{\\frac{1}{2}}_2$");
ui->cmbTestset->addItem("subscript test", "$r_{123}\\ \\ r_{\\frac{1}{2}}$"); ui->cmbTestset->addItem("subscript test", "$r_{123}\\ \\ r_{\\frac{1}{2}}$");
ui->cmbTestset->addItem("subscript0 test", "$r_{123}$"); ui->cmbTestset->addItem("subscript0 test", "$r_{123}$");
ui->cmbTestset->addItem("subscript1 test", "$r_{123}\\ $"); ui->cmbTestset->addItem("subscript1 test", "$r_{123}\\ $");

View File

@ -198,10 +198,10 @@ JKQTMathText::MTnode::MTnode(JKQTMathText* parent) {
JKQTMathText::MTnode::~MTnode() JKQTMathText::MTnode::~MTnode()
= default; = default;
void JKQTMathText::MTnode::getSize(QPainter &painter, JKQTMathText::MTenvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos) void JKQTMathText::MTnode::getSize(QPainter &painter, JKQTMathText::MTenvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, const MTnodeSize* prevNodeSize)
{ {
double w=width, b=baselineHeight, o=overallHeight, s=strikeoutPos; double w=width, b=baselineHeight, o=overallHeight, s=strikeoutPos;
getSizeInternal(painter, currentEv, w, b, o, s); getSizeInternal(painter, currentEv, w, b, o, s, prevNodeSize);
if (w<1e5) width=w; if (w<1e5) width=w;
if (b<1e5) baselineHeight=b; if (b<1e5) baselineHeight=b;
@ -213,6 +213,10 @@ bool JKQTMathText::MTnode::toHtml(QString &/*html*/, JKQTMathText::MTenvironment
return false; return false;
} }
bool JKQTMathText::MTnode::getDrawBoxes() const {
return this->drawBoxes;
}
void JKQTMathText::MTnode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { void JKQTMathText::MTnode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) {
if (drawBoxes) { if (drawBoxes) {
@ -263,7 +267,7 @@ JKQTMathText::MTtextNode::MTtextNode(JKQTMathText* parent, const QString& textIn
JKQTMathText::MTtextNode::~MTtextNode() = default; JKQTMathText::MTtextNode::~MTtextNode() = default;
void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
QFont f=currentEv.getFont(parent); QFont f=currentEv.getFont(parent);
if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" || if (currentEv.insideMath && (text=="(" || text=="[" || text=="|" || text=="]" || text==")" || text=="<" || text==">" ||
text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) || text==QString(QChar(0x2329)) || text==QString(QChar(0x232A)) || text==QString(QChar(0x2308)) ||
@ -274,7 +278,7 @@ void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::
QString txt=textTransform(text, currentEv, true); QString txt=textTransform(text, currentEv, true);
QFontMetricsF fm(f, painter.device()); QFontMetricsF fm(f, painter.device());
QRectF br=fm.boundingRect(txt); QRectF br=fm.boundingRect(txt);
QRectF tbr=parent->getTBR(f, txt, painter.device()); //fm.tightBoundingRect(txt); QRectF tbr=parent->getTightBoundingRect(f, txt, painter.device()); //fm.tightBoundingRect(txt);
if (txt=="|") { if (txt=="|") {
br=fm.boundingRect("X"); br=fm.boundingRect("X");
tbr=QRect(0,0,fm.width("X"), fm.ascent());//fm.boundingRect("X"); tbr=QRect(0,0,fm.width("X"), fm.ascent());//fm.boundingRect("X");
@ -293,7 +297,7 @@ void JKQTMathText::MTtextNode::getSizeInternal(QPainter& painter, JKQTMathText::
strikeoutPos=fm.strikeOutPos()*1.1; strikeoutPos=fm.strikeOutPos()*1.1;
} }
double JKQTMathText::MTtextNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTtextNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
double width=0; double width=0;
double baselineHeight=0; double baselineHeight=0;
@ -479,7 +483,7 @@ QString JKQTMathText::MTinstruction1Node::getTypeName() const
return QLatin1String("MTinstruction1Node(")+name+")"; return QLatin1String("MTinstruction1Node(")+name+")";
} }
void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
setupMTenvironment(ev); setupMTenvironment(ev);
@ -494,7 +498,7 @@ void JKQTMathText::MTinstruction1Node::getSizeInternal(QPainter& painter, JKQTMa
} }
} }
double JKQTMathText::MTinstruction1Node::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTinstruction1Node::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
@ -578,39 +582,49 @@ JKQTMathText::MTsubscriptNode::~MTsubscriptNode() {
if (child!=nullptr) delete child; if (child!=nullptr) delete child;
} }
void JKQTMathText::MTsubscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTsubscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor();
QFontMetricsF fm(ev.getFont(parent), painter.device());
double shift=parent->getSubShiftFactor()*parent->getTBR(ev.getFont(parent), "M", painter.device()).height();
child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos);
QFontMetricsF fmouter(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(ev.getFont(parent), painter.device());
QRectF tbr=parent->getTBR(currentEv.getFont(parent), "M", painter.device()); QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
overallHeight=tbr.height()+shift+(overallHeight-baselineHeight); double shift=parent->getSubShiftFactor()*tbr.height();
baselineHeight=tbr.height();
strikeoutPos=fmouter.strikeOutPos(); if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) {
if (currentEv.italic) width=width-double(fm.width(' '))*parent->getItalicCorrectionFactor(); shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift);
}
double yshift=baselineHeight-shift;
baselineHeight=shift;
strikeoutPos=fm.strikeOutPos()+yshift;
if (currentEv.italic && prevNodeSize==nullptr) width=width-double(fm.width(' '))*parent->getItalicCorrectionFactor();
} }
double JKQTMathText::MTsubscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTsubscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor();
QFontMetricsF fm(ev.getFont(parent), painter.device()); QFontMetricsF fm(ev.getFont(parent), painter.device());
QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
double shift=parent->getSubShiftFactor()*parent->getTBR(ev.getFont(parent), "M", painter.device()).height(); double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0;
child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos);
double shift=parent->getSubShiftFactor()*tbr.height();
if (prevNodeSize!=nullptr && prevNodeSize->overallHeight-prevNodeSize->baselineHeight>shift) {
qDebug()<<"oldshift="<<shift<<", prevNodeSize->overallHeight="<<prevNodeSize->overallHeight<<", prevNodeSize->baselineHeight="<<prevNodeSize->baselineHeight;
shift=-1.0*(prevNodeSize->overallHeight-prevNodeSize->baselineHeight-shift);
qDebug()<<"newshift="<<shift;
}
double yshift=baselineHeight-shift;
qDebug()<<"baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight<<", strikeoutPos="<<strikeoutPos;
qDebug()<<"shift="<<shift<<", yshift="<<yshift;
double xx=x; double xx=x;
if (currentEv.italic) xx=xx-double(fm.width(' '))*parent->getItalicCorrectionFactor(); if (currentEv.italic && prevNodeSize==nullptr) xx=xx-double(fm.width(' '))*parent->getItalicCorrectionFactor();
return child->draw(painter, xx, y+shift, ev);//+0.5*fm.boundingRect("A").width(); return child->draw(painter, xx, y+yshift, ev);//+0.5*fm.boundingRect("A").width();
}
bool JKQTMathText::MTsubscriptNode::isSubOrSuper()
{
return true;
} }
QString JKQTMathText::MTsubscriptNode::getTypeName() const QString JKQTMathText::MTsubscriptNode::getTypeName() const
@ -648,7 +662,7 @@ JKQTMathText::MTsqrtNode::~MTsqrtNode() {
if (child!=nullptr) delete child; if (child!=nullptr) delete child;
} }
void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
QFontMetricsF fm(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos);
@ -658,7 +672,7 @@ void JKQTMathText::MTsqrtNode::getSizeInternal(QPainter& painter, JKQTMathText::
width=width+fm.boundingRect("A").width()*2; // 1.53 width=width+fm.boundingRect("A").width()*2; // 1.53
} }
double JKQTMathText::MTsqrtNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTsqrtNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
double width=0, baselineHeight=0, overallHeight=0, sp=0; double width=0, baselineHeight=0, overallHeight=0, sp=0;
child->getSize(painter, currentEv, width, baselineHeight, overallHeight, sp); child->getSize(painter, currentEv, width, baselineHeight, overallHeight, sp);
@ -741,14 +755,14 @@ QString JKQTMathText::MTfracNode::getTypeName() const
return "MTfracNode"; return "MTfracNode";
} }
void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
QFontMetricsF fm(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
JKQTMathText::MTenvironment ev1=currentEv; JKQTMathText::MTenvironment ev1=currentEv;
JKQTMathText::MTenvironment ev2=currentEv; JKQTMathText::MTenvironment ev2=currentEv;
double xh=fm.xHeight(); //tightBoundingRect("x").height(); double xh=fm.xHeight(); //tightBoundingRect("x").height();
double sp=xh; double sp=xh;
double Ah=parent->getTBR(currentEv.getFont(parent), "M", painter.device()).height();//fm.ascent(); double Ah=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device()).height();//fm.ascent();
double xw=fm.boundingRect("x").width(); double xw=fm.boundingRect("x").width();
if (mode==MTFMunderbrace || mode==MTFMoverbrace) { if (mode==MTFMunderbrace || mode==MTFMoverbrace) {
@ -813,7 +827,7 @@ void JKQTMathText::MTfracNode::getSizeInternal(QPainter& painter, JKQTMathText::
} }
} }
double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
QFont f=currentEv.getFont(parent); QFont f=currentEv.getFont(parent);
QFontMetricsF fm(f, painter.device()); QFontMetricsF fm(f, painter.device());
@ -821,10 +835,10 @@ double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQ
JKQTMathText::MTenvironment ev2=currentEv; JKQTMathText::MTenvironment ev2=currentEv;
double xh=parent->getTBR(f, "x", painter.device()).height(); //fm.xHeight(); double xh=parent->getTightBoundingRect(f, "x", painter.device()).height(); //fm.xHeight();
double xw=fm.boundingRect("x").width(); double xw=fm.boundingRect("x").width();
double lw=qMax(0.0,ceil(currentEv.fontSize/16.0));//fm.lineWidth(); double lw=qMax(0.0,ceil(currentEv.fontSize/16.0));//fm.lineWidth();
double Ah=parent->getTBR(f, "M", painter.device()).height();//fm.ascent(); double Ah=parent->getTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
double bw=Ah/2.0; double bw=Ah/2.0;
if (mode==MTFMunderbrace || mode==MTFMoverbrace) { if (mode==MTFMunderbrace || mode==MTFMoverbrace) {
@ -885,12 +899,13 @@ double JKQTMathText::MTfracNode::draw(QPainter& painter, double x, double y, JKQ
} else if (mode==MTFMoverbrace) { } else if (mode==MTFMoverbrace) {
double ybrace=y-ascent1-bw/2.0; double ybrace=y-ascent1-bw/2.0;
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); {
painter.translate(x+xw/2.0+(width1)/2.0, ybrace); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.rotate(180); painter.translate(x+xw/2.0+(width1)/2.0, ybrace);
QPainterPath path=makeHBracePath(0,0, width, bw); painter.rotate(180);
painter.drawPath(path); QPainterPath path=makeHBracePath(0,0, width, bw);
painter.drawPath(path);
}
child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1); child1->draw(painter, x+xw/2.0+(width-width1)/2.0, y, ev1);
child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-bw-descent2, ev2); child2->draw(painter, x+xw/2.0+(width-width2)/2.0, y-ascent1-bw-descent2, ev2);
@ -951,7 +966,7 @@ QString JKQTMathText::MTmatrixNode::getTypeName() const
return "MTmatrixNode"; return "MTmatrixNode";
} }
void JKQTMathText::MTmatrixNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTmatrixNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
QFontMetricsF fm(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
JKQTMathText::MTenvironment ev1=currentEv; JKQTMathText::MTenvironment ev1=currentEv;
@ -993,7 +1008,7 @@ void JKQTMathText::MTmatrixNode::getSizeInternal(QPainter& painter, JKQTMathText
strikeoutPos=xh; strikeoutPos=xh;
} }
double JKQTMathText::MTmatrixNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTmatrixNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
QFontMetricsF fm(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
@ -1088,7 +1103,7 @@ JKQTMathText::MTdecoratedNode::~MTdecoratedNode() {
if (child!=nullptr) delete child; if (child!=nullptr) delete child;
} }
void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { 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()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
double wc=fm.boundingRect("A").width(); double wc=fm.boundingRect("A").width();
double dheightfactor=1.0+parent->getDecorationHeightFactor()*2.0; double dheightfactor=1.0+parent->getDecorationHeightFactor()*2.0;
@ -1100,7 +1115,7 @@ void JKQTMathText::MTdecoratedNode::getSizeInternal(QPainter& painter, JKQTMathT
width=width+0.3*wc; width=width+0.3*wc;
} }
double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTdecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
MTenvironment ev=currentEv; MTenvironment ev=currentEv;
double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0; double width=0, baselineHeight=0, overallHeight=0, strikeoutPos=0;
@ -1248,39 +1263,47 @@ JKQTMathText::MTsuperscriptNode::~MTsuperscriptNode() {
if (child!=nullptr) delete child; if (child!=nullptr) delete child;
} }
void JKQTMathText::MTsuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTsuperscriptNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor();
QFontMetricsF fm(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos); child->getSize(painter, ev, width, baselineHeight, overallHeight, strikeoutPos);
double shift=0;//parent->getSuperShiftFactor()*fm.ascent(); double shift=parent->getSuperShiftFactor()*tbr.height();
overallHeight=overallHeight+shift;
strikeoutPos=fm.strikeOutPos(); if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) {
if (currentEv.italic) width=width+double(fm.width(' '))*parent->getItalicCorrectionFactor(); shift=prevNodeSize->baselineHeight-(overallHeight-baselineHeight)-shift;
}
double yshift=shift+overallHeight-baselineHeight;
baselineHeight=overallHeight=overallHeight+shift;
strikeoutPos=strikeoutPos-yshift;
if (currentEv.italic && prevNodeSize==nullptr) width=width+double(fm.width(' '))*parent->getItalicCorrectionFactor();
} }
double JKQTMathText::MTsuperscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTsuperscriptNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor(); ev.fontSize=ev.fontSize*parent->getSubsuperSizeFactor();
double cwidth, cbaselineHeight, coverallheight, cStrikeoutPos; double cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos;
child->getSize(painter, ev, cwidth, cbaselineHeight, coverallheight, cStrikeoutPos); child->getSize(painter, ev, cWidth, cBaselineHeight, cOverallHeight, cStrikeoutPos);
QFontMetricsF fm(currentEv.getFont(parent), painter.device()); QFontMetricsF fm(currentEv.getFont(parent), painter.device());
QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
double shift=parent->getSuperShiftFactor()*tbr.height();
double shift=0;//parent->getSuperShiftFactor()*fm.ascent(); if (prevNodeSize!=nullptr && prevNodeSize->baselineHeight>tbr.height()) {
//double shift=ev.; shift=prevNodeSize->baselineHeight-(cOverallHeight-cBaselineHeight)-shift;
}
double yshift=shift+cOverallHeight-cBaselineHeight;
double xx=x; double xx=x;
if (currentEv.italic) xx=xx+double(fm.width(' '))*parent->getItalicCorrectionFactor(); if (currentEv.italic && prevNodeSize==nullptr) xx=xx+double(fm.width(' '))*parent->getItalicCorrectionFactor();
return child->draw(painter, xx, y-shift, ev);//+0.5*fm.boundingRect("A").width(); return child->draw(painter, xx, y-yshift, ev);//+0.5*fm.boundingRect("A").width();
} }
bool JKQTMathText::MTsuperscriptNode::isSubOrSuper()
{
return true;
}
QString JKQTMathText::MTsuperscriptNode::getTypeName() const QString JKQTMathText::MTsuperscriptNode::getTypeName() const
{ {
@ -1321,7 +1344,7 @@ JKQTMathText::MTbraceNode::~MTbraceNode() {
if (child!=nullptr) delete child; if (child!=nullptr) delete child;
} }
void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos); child->getSize(painter, currentEv, width, baselineHeight, overallHeight, strikeoutPos);
@ -1339,7 +1362,7 @@ void JKQTMathText::MTbraceNode::getSizeInternal(QPainter& painter, JKQTMathText:
} }
double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
//std::cout<<"drawing brace-node: '"<<openbrace.toStdString()<<"' ... '"<<closebrace.toStdString()<<"'\n"; //std::cout<<"drawing brace-node: '"<<openbrace.toStdString()<<"' ... '"<<closebrace.toStdString()<<"'\n";
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
JKQTMathText::MTenvironment ev=currentEv; JKQTMathText::MTenvironment ev=currentEv;
@ -1353,11 +1376,11 @@ double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JK
double bracewidth=0, braceheight=0; double bracewidth=0, braceheight=0;
getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight); getBraceWidth(painter, ev, baselineHeight, overallHeight, bracewidth, braceheight);
double cwidth=0; double cWidth=0;
double cbaselineHeight=0; double cBaselineHeight=0;
double coverallHeight=0, cstrikeoutPos=0; double cOverallHeight=0, cstrikeoutPos=0;
getSize(painter, currentEv, cwidth, cbaselineHeight, coverallHeight, cstrikeoutPos); getSize(painter, currentEv, cWidth, cBaselineHeight, cOverallHeight, cstrikeoutPos);
double lw=qMax(0.25,ceil(currentEv.fontSize/12.0));//fm.lineWidth(); double lw=qMax(0.25,ceil(currentEv.fontSize/12.0));//fm.lineWidth();
@ -1371,62 +1394,62 @@ double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JK
double brace_fraction=0.85; double brace_fraction=0.85;
if (openbrace=="(") { if (openbrace=="(") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+brace_fraction*bracewidth, y1); path.moveTo(xnew+brace_fraction*bracewidth, y1);
path.cubicTo(xnew, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+brace_fraction*bracewidth, y2); path.cubicTo(xnew, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+brace_fraction*bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (openbrace=="[") { } else if (openbrace=="[") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+brace_fraction*bracewidth, y1); path.moveTo(xnew+brace_fraction*bracewidth, y1);
path.lineTo(xnew+lw/2.0, y1); path.lineTo(xnew+lw/2.0, y1);
path.lineTo(xnew+lw/2.0, y2); path.lineTo(xnew+lw/2.0, y2);
path.lineTo(xnew+brace_fraction*bracewidth, y2); path.lineTo(xnew+brace_fraction*bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (openbrace=="{") { } else if (openbrace=="{") {
QPainterPath path=makeHBracePath(0,0,coverallHeight, bracewidth*brace_fraction); QPainterPath path=makeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.translate(xnew+bracewidth*(1.0-brace_fraction), y-cbaselineHeight+coverallHeight/2.0); painter.translate(xnew+bracewidth*(1.0-brace_fraction), y-cBaselineHeight+cOverallHeight/2.0);
painter.rotate(90); painter.rotate(90);
painter.drawPath(path); painter.drawPath(path);
} else if (openbrace=="_") { } else if (openbrace=="_") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+brace_fraction*bracewidth, y1); path.moveTo(xnew+brace_fraction*bracewidth, y1);
path.lineTo(xnew, y1); path.lineTo(xnew, y1);
path.lineTo(xnew, y2); path.lineTo(xnew, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (openbrace=="~") { } else if (openbrace=="~") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew, y1); path.moveTo(xnew, y1);
path.lineTo(xnew, y2); path.lineTo(xnew, y2);
path.lineTo(xnew+brace_fraction*bracewidth, y2); path.lineTo(xnew+brace_fraction*bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (openbrace=="|") { } else if (openbrace=="|") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2);
if (l.length()>0) painter.drawLine(l); if (l.length()>0) painter.drawLine(l);
painter.drawPath(path); painter.drawPath(path);
} else if (openbrace=="#" || openbrace=="||") { } else if (openbrace=="#" || openbrace=="||") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2); QLineF l(xnew+brace_fraction*bracewidth, y1, xnew+brace_fraction*bracewidth, y2);
if (l.length()>0) painter.drawLine(l); if (l.length()>0) painter.drawLine(l);
l=QLineF(xnew+brace_fraction*bracewidth-1.5*lw, y1, xnew+brace_fraction*bracewidth-1.5*lw, y2); l=QLineF(xnew+brace_fraction*bracewidth-1.5*lw, y1, xnew+brace_fraction*bracewidth-1.5*lw, y2);
if (l.length()>0) painter.drawLine(l); if (l.length()>0) painter.drawLine(l);
} else if (openbrace=="<") { } else if (openbrace=="<") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+brace_fraction*bracewidth, y1); path.moveTo(xnew+brace_fraction*bracewidth, y1);
path.lineTo(xnew, (y2+y1)/2.0); path.lineTo(xnew, (y2+y1)/2.0);
path.lineTo(xnew+brace_fraction*bracewidth, y2); path.lineTo(xnew+brace_fraction*bracewidth, y2);
@ -1441,62 +1464,62 @@ double JKQTMathText::MTbraceNode::draw(QPainter& painter, double x, double y, JK
painter.setPen(p); painter.setPen(p);
if (closebrace==")") { if (closebrace==")") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1);
path.cubicTo(xnew+bracewidth, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew+bracewidth, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+(1.0-brace_fraction)*bracewidth, y2); path.cubicTo(xnew+bracewidth, (y1+y2)/2.0+fabs(y1-y2)/6.0, xnew+bracewidth, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xnew+(1.0-brace_fraction)*bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (closebrace=="]") { } else if (closebrace=="]") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1);
path.lineTo(xnew+bracewidth-lw/2.0, y1); path.lineTo(xnew+bracewidth-lw/2.0, y1);
path.lineTo(xnew+bracewidth-lw/2.0, y2); path.lineTo(xnew+bracewidth-lw/2.0, y2);
path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (closebrace=="}") { } else if (closebrace=="}") {
QPainterPath path=makeHBracePath(0,0,coverallHeight, bracewidth*brace_fraction); QPainterPath path=makeHBracePath(0,0,cOverallHeight, bracewidth*brace_fraction);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.translate(xnew+bracewidth*brace_fraction, y-cbaselineHeight+coverallHeight/2.0); painter.translate(xnew+bracewidth*brace_fraction, y-cBaselineHeight+cOverallHeight/2.0);
painter.rotate(270); painter.rotate(270);
painter.drawPath(path); painter.drawPath(path);
} else if (closebrace=="_") { } else if (closebrace=="_") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1);
path.lineTo(xnew+bracewidth, y1); path.lineTo(xnew+bracewidth, y1);
path.lineTo(xnew+bracewidth, y2); path.lineTo(xnew+bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (closebrace=="~") { } else if (closebrace=="~") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+bracewidth, y1); path.moveTo(xnew+bracewidth, y1);
path.lineTo(xnew+bracewidth, y2); path.lineTo(xnew+bracewidth, y2);
path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2);
painter.drawPath(path); painter.drawPath(path);
} else if (closebrace=="|") { } else if (closebrace=="|") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2);
if (l.length()>0) painter.drawLine(l); if (l.length()>0) painter.drawLine(l);
painter.drawPath(path); painter.drawPath(path);
} else if (closebrace=="#" || closebrace=="||") { } else if (closebrace=="#" || closebrace=="||") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2); QLineF l(xnew+(1.0-brace_fraction)*bracewidth, y1, xnew+(1.0-brace_fraction)*bracewidth, y2);
if (l.length()>0) painter.drawLine(l); if (l.length()>0) painter.drawLine(l);
l=QLineF(xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y1, xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y2); l=QLineF(xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y1, xnew+(1.0-brace_fraction)*bracewidth+1.5*lw, y2);
if (l.length()>0) painter.drawLine(l); if (l.length()>0) painter.drawLine(l);
} else if (closebrace==">") { } else if (closebrace==">") {
QPainterPath path; QPainterPath path;
double y1=y+(coverallHeight-cbaselineHeight); double y1=y+(cOverallHeight-cBaselineHeight);
double y2=y-cbaselineHeight; double y2=y-cBaselineHeight;
path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1); path.moveTo(xnew+(1.0-brace_fraction)*bracewidth, y1);
path.lineTo(xnew+bracewidth, (y2+y1)/2.0); path.lineTo(xnew+bracewidth, (y2+y1)/2.0);
path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2); path.lineTo(xnew+(1.0-brace_fraction)*bracewidth, y2);
@ -1595,23 +1618,27 @@ QString JKQTMathText::MTlistNode::getTypeName() const
return "MTlistNode"; return "MTlistNode";
} }
void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
width=0; width=0;
overallHeight=0; overallHeight=0;
baselineHeight=0; baselineHeight=0;
strikeoutPos=0; strikeoutPos=0;
QFontMetricsF fm(currentEv.getFont(parent)); QFontMetricsF fm(currentEv.getFont(parent));
QRectF tbr=parent->getTBR(currentEv.getFont(parent), "M", painter.device()); QRectF tbr=parent->getTightBoundingRect(currentEv.getFont(parent), "M", painter.device());
double xnew=0; double xnew=0;
bool wasBrace=false; bool wasBrace=false;
for (int i=0; i<nodes.size(); i++) { for (int i=0; i<nodes.size(); i++) {
{ MTnodeSize prevNodeSize;
double w1, oh, bh, sp; MTnodeSize* prevNodeSizePtr=nullptr;
nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp);
//qDebug()<<"i="<<i<<" width="<<width<<" baselineHeight="<<baselineHeight<<" overallHeight="<<overallHeight<<" strikeoutPos="<<strikeoutPos<<"\n"<<"### nodes["<<i<<"] = "<<nodes[i]->getTypeName()<< " w="<<w1<<" bh="<<bh<<" oh="<<oh<<" sp="<<sp; if (i>0 && wasBrace) {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos);
prevNodeSizePtr=&prevNodeSize;
} }
bool doDraw=true; bool doDraw=true;
MTsymbolNode* smb=dynamic_cast<MTsymbolNode*>(nodes[i]); MTsymbolNode* smb=dynamic_cast<MTsymbolNode*>(nodes[i]);
// if we find a subscript/superscript node we check whether the next node is super/subscript // if we find a subscript/superscript node we check whether the next node is super/subscript
@ -1620,28 +1647,33 @@ void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<MTsubscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<MTsubscriptNode*>(nodes[i+1])) { // is this subscript?
double w1, w2, oh, bh, sp; double w1, w2, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp); nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr);
double shift=parent->getSuperShiftFactor()*fm.xHeight()+(oh-bh);//(overallHeight-baselineHeight)+(oh-bh);
if (wasBrace) { if (bh>baselineHeight) {
shift=baselineHeight-parent->getSuperShiftFactor()*tbr.height()+(oh-bh); overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=bh;
strikeoutPos=sp;
}
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
} }
//qDebug()<<"super_sub: super: "<<nodes[i]->getTypeName()<<" w1="<<w1<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp;
if (shift+bh>baselineHeight) {
double lheight=overallHeight-baselineHeight;
baselineHeight=shift+bh;
overallHeight=baselineHeight+lheight;
}
i++; i++;
nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp); nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtr);
//qDebug()<<"super_sub: sub: "<<nodes[i]->getTypeName()<<" w2="<<w2<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp; //qDebug()<<"super_sub: sub: "<<nodes[i]->getTypeName()<<" w2="<<w2<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp;
if (shift+oh-bh>overallHeight-baselineHeight) { if (bh>baselineHeight) {
overallHeight=baselineHeight+shift+(oh-bh); overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=bh;
strikeoutPos=sp;
}
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
} }
doDraw=false;
xnew+=qMax(w1+fm.width(" "), w2); xnew+=qMax(w1+fm.width(" "), w2);
doDraw=false;
//qDebug()<<"### super+sub"; //qDebug()<<"### super+sub";
//qDebug()<<"### subsupop: super+sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: super+sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
@ -1650,26 +1682,32 @@ void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<MTsuperscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<MTsuperscriptNode*>(nodes[i+1])) { // is this subscript?
double w1, w2, oh, bh, sp; double w1, w2, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp); nodes[i]->getSize(painter, currentEv, w1, bh, oh, sp, prevNodeSizePtr);
double shift=parent->getSuperShiftFactor()*fm.xHeight()+(oh-bh);//(overallHeight-baselineHeight)+(oh-bh); if (bh>baselineHeight) {
if (wasBrace) { overallHeight=overallHeight+bh-baselineHeight;
shift=baselineHeight-parent->getSuperShiftFactor()*parent->getTBR(currentEv.getFont(parent), "M", painter.device()).height()+(oh-bh); baselineHeight=bh;
strikeoutPos=sp;
}
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
} }
//qDebug()<<"sub_super: sub: "<<nodes[i]->getTypeName()<<" w1="<<w1<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp;
if (shift+oh-bh>overallHeight-baselineHeight) {
overallHeight=baselineHeight+shift+(oh-bh);
}
i++; i++;
nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp); nodes[i]->getSize(painter, currentEv, w2, bh, oh, sp, prevNodeSizePtr);
//qDebug()<<"sub_super: super: "<<nodes[i]->getTypeName()<<" w2="<<w2<<" bh"<<bh<<" oh="<<oh<<" sp="<<sp; if (bh>baselineHeight) {
if (shift+bh>baselineHeight) { overallHeight=overallHeight+bh-baselineHeight;
double lheight=overallHeight-baselineHeight; baselineHeight=bh;
baselineHeight=shift+bh; strikeoutPos=sp;
overallHeight=baselineHeight+lheight; }
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
} }
doDraw=false;
xnew+=qMax(w1, w2+fm.width(" ")); xnew+=qMax(w1, w2+fm.width(" "));
doDraw=false;
//qDebug()<<"### sub+super"; //qDebug()<<"### sub+super";
//qDebug()<<"### subsupop: sub+super1 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight; //qDebug()<<"### subsupop: sub+super1 overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
@ -1770,92 +1808,63 @@ void JKQTMathText::MTlistNode::getSizeInternal(QPainter& painter, JKQTMathText::
if (i<nodes.size() && doDraw) { if (i<nodes.size() && doDraw) {
double w, oh, bh, sp; double w, oh, bh, sp;
nodes[i]->getSize(painter, currentEv, w, bh, oh, sp); nodes[i]->getSize(painter, currentEv, w, bh, oh, sp, prevNodeSizePtr);
double shift=0;
if (dynamic_cast<MTsuperscriptNode*>(nodes[i])) {
//QFontMetricsF fm(currentEv.getFont(parent));
//QRectF tbr=fm.tightBoundingRect("M");
shift=parent->getSuperShiftFactor()*tbr.height()+(oh-bh);//((overallHeight-baselineHeight)+(oh-bh));
if (wasBrace) {
shift=baselineHeight-parent->getSuperShiftFactor()*tbr.height()+(oh-bh);
}
//qDebug()<<"+++ super: bh="<<bh<<" oh="<<oh<<" shift="<<shift<<" wasBrace="<<wasBrace<<" baselineHeight="<<baselineHeight<<" overallHeight="<<overallHeight<<" fm.ascent="<<fm.ascent();
w+=fm.width(" "); //qDebug()<<"### else: bh="<<bh<<" baselineHeight="<<baselineHeight<<" oh="<<oh<<" overallHeight="<<overallHeight;
if (shift+bh>baselineHeight) { if (bh>baselineHeight) {
double lheight=overallHeight-baselineHeight; overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=shift+bh; baselineHeight=bh;
overallHeight=baselineHeight+lheight; strikeoutPos=sp;
}
//qDebug()<<"### super";
//qDebug()<<"### subsupop: super overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} else if (dynamic_cast<MTsubscriptNode*>(nodes[i])) {
//QFontMetricsF fm(currentEv.getFont(parent));
shift=0;//parent->getSuperShiftFactor()*fm.ascent();//((overallHeight-baselineHeight)+(oh-bh));
w+=fm.width(" ");
if (shift+oh-bh>overallHeight-baselineHeight) {
overallHeight=baselineHeight+shift+(oh-bh);
}
//qDebug()<<"### sub";
//qDebug()<<"### subsupop: sub overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} else {
//qDebug()<<"### else: bh="<<bh<<" baselineHeight="<<baselineHeight<<" oh="<<oh<<" overallHeight="<<overallHeight;
if (bh>baselineHeight) {
overallHeight=overallHeight+bh-baselineHeight;
baselineHeight=bh;
strikeoutPos=sp;
}
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
}
//qDebug()<<"### subsupop: else overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
} }
if (baselineHeight+oh-bh>overallHeight) {
overallHeight=baselineHeight+oh-bh;
strikeoutPos=sp;
}
//qDebug()<<"### subsupop: else overallHeight="<<overallHeight<<" baselineHeight="<<baselineHeight;
xnew+=w; xnew+=w;
//qDebug()<<i<<xnew; //qDebug()<<i<<xnew;
//if (baselineHeight+oh+shift>overallHeight) overallHeight=baselineHeight+oh+shift;
/*if (oh+shift-bh>overallHeight-baselineHeight) {
overallHeight=baselineHeight+oh+shift-bh;
}*/
} }
wasBrace=dynamic_cast<MTbraceNode*>(nodes[i]); wasBrace=dynamic_cast<MTbraceNode*>(nodes[i]);
} }
width=xnew; width=xnew;
} }
double JKQTMathText::MTlistNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTlistNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
double ynew=y; double ynew=y;
double xnew=x; double xnew=x;
double cwidth=0, cbaselineHeight=0, coverallHeight=0, cstrieoutPos=0;
//qDebug()<<"listNode: "<<currentEv.fontSize; //qDebug()<<"listNode: "<<currentEv.fontSize;
QFontMetricsF fm(currentEv.getFont(parent)); QFontMetricsF fm(currentEv.getFont(parent));
QRectF tbr=parent->getTBR(currentEv.getFont(parent), "M", painter.device());
bool wasBrace=false; bool wasBrace=false;
for (int i=0; i<nodes.size(); i++) { for (int i=0; i<nodes.size(); i++) {
bool doDraw=true; bool doDraw=true;
MTnodeSize prevNodeSize;
MTnodeSize* prevNodeSizePtr=nullptr;
if (i>0 && wasBrace) {
nodes[i-1]->getSize(painter, currentEv, prevNodeSize.width, prevNodeSize.baselineHeight, prevNodeSize.overallHeight, prevNodeSize.strikeoutPos);
prevNodeSizePtr=&prevNodeSize;
}
MTsymbolNode* smb=dynamic_cast<MTsymbolNode*>(nodes[i]); MTsymbolNode* smb=dynamic_cast<MTsymbolNode*>(nodes[i]);
// if we find a subscript/superscript node we check whether the next node is super/subscript // if we find a subscript/superscript node we check whether the next node is super/subscript
// if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly // if so, we typeset them at the same x-psotion, so sub/superscripts appear correctly
if (dynamic_cast<MTsuperscriptNode*>(nodes[i])) { if (dynamic_cast<MTsuperscriptNode*>(nodes[i])) {
double ccwidth=0, ccbaselineHeight=0, ccoverallHeight=0, ccstrieoutPos=0;
nodes[i]->getSize(painter, currentEv, ccwidth, ccbaselineHeight, ccoverallHeight, ccstrieoutPos);
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<MTsubscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<MTsubscriptNode*>(nodes[i+1])) { // is this subscript?
double shift=-parent->getSuperShiftFactor()*tbr.height();
if (wasBrace) {
shift=-cbaselineHeight+parent->getSuperShiftFactor()*tbr.height();
}
//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+shift-(ccoverallHeight-ccbaselineHeight), currentEv); double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr);
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); double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr);
//i++; //i++;
xnew=qMax(xnew1, xnew2); xnew=qMax(xnew1, xnew2);
doDraw=false; doDraw=false;
@ -1864,20 +1873,13 @@ double JKQTMathText::MTlistNode::draw(QPainter& painter, double x, double y, JKQ
} else if (dynamic_cast<MTsubscriptNode*>(nodes[i])) { } else if (dynamic_cast<MTsubscriptNode*>(nodes[i])) {
if (i+1<nodes.size()) { // is there one mor node behind? if (i+1<nodes.size()) { // is there one mor node behind?
if (dynamic_cast<MTsuperscriptNode*>(nodes[i+1])) { // is this subscript? if (dynamic_cast<MTsuperscriptNode*>(nodes[i+1])) { // is this subscript?
//painter.setPen(QPen("red"));
//painter.drawEllipse(xnew-4,ynew+shift-(ccOverallHeight-ccBaselineHeight)-4,8,8);
double xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr);
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 xnew1=nodes[i]->draw(painter, xnew, ynew, currentEv); double xnew2=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr);
i++;
double ccwidth=0, ccbaselineHeight=0, ccoverallHeight=0, ccstrieoutPos=0;
nodes[i]->getSize(painter, currentEv, ccwidth, ccbaselineHeight, ccoverallHeight, ccstrieoutPos);
//QRectF tbr=fm.tightBoundingRect("M");
double shift=-parent->getSuperShiftFactor()*tbr.height();
if (wasBrace) {
shift=-cbaselineHeight+parent->getSuperShiftFactor()*tbr.height();
}
//painter.setPen(QPen("red"));
//painter.drawEllipse(xnew-4,ynew+shift-(ccoverallHeight-ccbaselineHeight)-4,8,8);
double xnew2=nodes[i]->draw(painter, xnew, ynew+shift-(ccoverallHeight-ccbaselineHeight), currentEv);
//i++; //i++;
xnew=qMax(xnew1, xnew2); xnew=qMax(xnew1, xnew2);
doDraw=false; doDraw=false;
@ -1959,25 +1961,10 @@ double JKQTMathText::MTlistNode::draw(QPainter& painter, double x, double y, JKQ
} }
} }
} }
nodes[i]->getSize(painter, currentEv, cwidth, cbaselineHeight, coverallHeight, cstrieoutPos);
} }
if (i<nodes.size() && doDraw) { if (i<nodes.size() && doDraw) {
if (dynamic_cast<MTsuperscriptNode*>(nodes[i])) { // is this superscript? xnew=nodes[i]->draw(painter, xnew, ynew, currentEv, prevNodeSizePtr);
double ccwidth=0, ccbaselineHeight=0, ccoverallHeight=0, ccstrieoutPos=0;
nodes[i]->getSize(painter, currentEv, ccwidth, ccbaselineHeight, ccoverallHeight, ccstrieoutPos);
//QRectF tbr=fm.tightBoundingRect("M");
double shift=-parent->getSuperShiftFactor()*tbr.height();
if (wasBrace) {
shift=-cbaselineHeight+parent->getSuperShiftFactor()*tbr.height();
}
//painter.setPen(QPen("red"));
//painter.drawEllipse(xnew-4,ynew+shift-(ccoverallHeight-ccbaselineHeight)-4,8,8);
xnew=nodes[i]->draw(painter, xnew, ynew+shift-(ccoverallHeight-ccbaselineHeight), currentEv);
} else {
xnew=nodes[i]->draw(painter, xnew, ynew, currentEv);
}
} }
wasBrace=dynamic_cast<MTbraceNode*>(nodes[i]); wasBrace=dynamic_cast<MTbraceNode*>(nodes[i]);
} }
@ -2746,7 +2733,7 @@ QFont JKQTMathText::MTsymbolNode::getFontName(symbolFont f, QFont& fi) {
return fr; return fr;
} }
void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) { void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText::MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize) {
QFont f=currentEv.getFont(parent); QFont f=currentEv.getFont(parent);
f=getFontName(font, f); f=getFontName(font, f);
f.setPointSizeF(f.pointSizeF()*fontFactor); f.setPointSizeF(f.pointSizeF()*fontFactor);
@ -2757,7 +2744,7 @@ void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText
QFontMetricsF fm(f, painter.device()); QFontMetricsF fm(f, painter.device());
QString symb=symbol; QString symb=symbol;
width=0; width=0;
if (currentEv.insideMath) width=qMax(parent->getTBR(f, symb, painter.device()).width(),parent->getTBR(f, "i", painter.device()).width());//fm.width(symbol); if (currentEv.insideMath) width=qMax(parent->getTightBoundingRect(f, symb, painter.device()).width(),parent->getTightBoundingRect(f, "i", painter.device()).width());//fm.width(symbol);
else width=fm.boundingRect(symb).width();//fm.width(symbol); else width=fm.boundingRect(symb).width();//fm.width(symbol);
width=qMax(fm.width("j"), width); width=qMax(fm.width("j"), width);
@ -2765,20 +2752,20 @@ void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText
width=fm.width("a"); width=fm.width("a");
if (symbolName=="|") width=fm.width("1")*0.8; if (symbolName=="|") width=fm.width("1")*0.8;
else if (symbolName=="infty") width=fm.width("M"); else if (symbolName=="infty") width=fm.width("M");
else if (symbolName=="quad") width=parent->getTBR(f, "M", painter.device()).width(); else if (symbolName=="quad") width=parent->getTightBoundingRect(f, "M", painter.device()).width();
else if (symbolName==" ") width=parent->getTBR(f, "x", painter.device()).width(); else if (symbolName==" ") width=parent->getTightBoundingRect(f, "x", painter.device()).width();
else if (symbolName==";") width=parent->getTBR(f, "x", painter.device()).width()*0.75; else if (symbolName==";") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.75;
else if (symbolName==":") width=parent->getTBR(f, "x", painter.device()).width()*0.5; else if (symbolName==":") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.5;
else if (symbolName==",") width=parent->getTBR(f, "x", painter.device()).width()*0.25; else if (symbolName==",") width=parent->getTightBoundingRect(f, "x", painter.device()).width()*0.25;
else if (symbolName=="!") width=-parent->getTBR(f, "x", painter.device()).width()*0.25; else if (symbolName=="!") width=-parent->getTightBoundingRect(f, "x", painter.device()).width()*0.25;
else if (symbolName=="longleftarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } else if (symbolName=="longleftarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; }
else if (symbolName=="longrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } else if (symbolName=="longrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; }
else if (symbolName=="Longleftarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } else if (symbolName=="Longleftarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; }
else if (symbolName=="Longrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } else if (symbolName=="Longrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; }
else if (symbolName=="longleftrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } else if (symbolName=="longleftrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; }
else if (symbolName=="Longleftrightarrow") { width=parent->getTBR(f, "X", painter.device()).width()*3.5; symb="x"; } else if (symbolName=="Longleftrightarrow") { width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.5; symb="x"; }
} }
QRectF tbr=parent->getTBR(f, symb, painter.device()); QRectF tbr=parent->getTightBoundingRect(f, symb, painter.device());
overallHeight=tbr.height();// fm.height(); overallHeight=tbr.height();// fm.height();
baselineHeight=tbr.height()-tbr.bottom(); baselineHeight=tbr.height()-tbr.bottom();
if (exactAscent) { if (exactAscent) {
@ -2798,7 +2785,7 @@ void JKQTMathText::MTsymbolNode::getSizeInternal(QPainter& painter, JKQTMathText
} }
double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv) { double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv, const MTnodeSize* prevNodeSize) {
doDrawBoxes(painter, x, y, currentEv); doDrawBoxes(painter, x, y, currentEv);
double width=0; double width=0;
double baselineHeight=0; double baselineHeight=0;
@ -2837,7 +2824,7 @@ double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, J
// if the symbol has been recognized in the constructor: draw the symbol // if the symbol has been recognized in the constructor: draw the symbol
painter.drawText(QPointF(x+shift, y+yfactor*overallHeight), symbol); painter.drawText(QPointF(x+shift, y+yfactor*overallHeight), symbol);
double xx=x+shift; double xx=x+shift;
double yy=y-fm.xHeight()-(parent->getTBR(f, "M", painter.device()).height()-fm.xHeight())/3.0; double yy=y-fm.xHeight()-(parent->getTightBoundingRect(f, "M", painter.device()).height()-fm.xHeight())/3.0;
QLineF l(xx, yy, xx+xwi/3.0+((currentEv.italic)?(xwi/3.0):0), yy); QLineF l(xx, yy, xx+xwi/3.0+((currentEv.italic)?(xwi/3.0):0), yy);
if (drawBar&&l.length()>0) painter.drawLine(l); if (drawBar&&l.length()>0) painter.drawLine(l);
@ -2872,43 +2859,43 @@ double JKQTMathText::MTsymbolNode::draw(QPainter& painter, double x, double y, J
} else if (symbolName==",") { // 25% space } else if (symbolName==",") { // 25% space
} else if (symbolName=="!") { // -25% space } else if (symbolName=="!") { // -25% space
} else if (symbolName=="longleftarrow") { } else if (symbolName=="longleftarrow") {
double width=parent->getTBR(f, "X", painter.device()).width()*3.0; double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0;
double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25;
double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0;
QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, false); QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false);
painter.drawPath(path); painter.drawPath(path);
} else if (symbolName=="longrightarrow"){ } else if (symbolName=="longrightarrow"){
double width=parent->getTBR(f, "X", painter.device()).width()*3.0; double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0;
double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25;
double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0;
QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, false, true); QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true);
painter.drawPath(path); painter.drawPath(path);
} else if (symbolName=="Longleftarrow") { } else if (symbolName=="Longleftarrow") {
double width=parent->getTBR(f, "X", painter.device()).width()*3.0; double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0;
double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25;
double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0;
QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, false); QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, false);
painter.drawPath(path); painter.drawPath(path);
} else if (symbolName=="Longrightarrow") { } else if (symbolName=="Longrightarrow") {
double width=parent->getTBR(f, "X", painter.device()).width()*3.0; double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0;
double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25;
double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0;
QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, false, true); QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, false, true);
painter.drawPath(path); painter.drawPath(path);
} else if (symbolName=="longleftrightarrow") { } else if (symbolName=="longleftrightarrow") {
double width=parent->getTBR(f, "X", painter.device()).width()*3.0; double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0;
double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25;
double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0;
QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, true); QPainterPath path=makeArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true);
painter.drawPath(path); painter.drawPath(path);
} else if (symbolName=="Longleftrightarrow") { } else if (symbolName=="Longleftrightarrow") {
double width=parent->getTBR(f, "X", painter.device()).width()*3.0; double width=parent->getTightBoundingRect(f, "X", painter.device()).width()*3.0;
double dx=parent->getTBR(f, "X", painter.device()).width()*0.25; double dx=parent->getTightBoundingRect(f, "X", painter.device()).width()*0.25;
double ypos=y-parent->getTBR(f, "x", painter.device()).height()/2.0; double ypos=y-parent->getTightBoundingRect(f, "x", painter.device()).height()/2.0;
QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTBR(f, "M", painter.device()).height()*0.5, true, true); QPainterPath path=makeDArrow(x+shift+dx, ypos, width, parent->getTightBoundingRect(f, "M", painter.device()).height()*0.5, true, true);
painter.drawPath(path); painter.drawPath(path);
} else { // draw a box to indicate an unavailable symbol } else { // draw a box to indicate an unavailable symbol
QRectF tbr=parent->getTBR(f, "M", painter.device()); QRectF tbr=parent->getTightBoundingRect(f, "M", painter.device());
painter.drawRect(QRectF(x+shift,y-tbr.height(), xwi, tbr.height()*0.8)); painter.drawRect(QRectF(x+shift,y-tbr.height(), xwi, tbr.height()*0.8));
} }
painter.setPen(pold); painter.setPen(pold);
@ -3199,15 +3186,15 @@ JKQTMathText::JKQTMathText(QObject* parent):
default_brace_factor=brace_factor=1.04; default_brace_factor=brace_factor=1.04;
default_subsuper_size_factor=subsuper_size_factor=0.7; default_subsuper_size_factor=subsuper_size_factor=0.7;
default_italic_correction_factor=italic_correction_factor=0.4; default_italic_correction_factor=italic_correction_factor=0.4;
default_sub_shift_factor=sub_shift_factor=0.6; default_sub_shift_factor=sub_shift_factor=0.4;
default_super_shift_factor=super_shift_factor=0.5; default_super_shift_factor=super_shift_factor=0.6;
default_brace_shrink_factor=brace_shrink_factor=0.6; default_brace_shrink_factor=brace_shrink_factor=0.6;
default_fontColor=fontColor=QColor("black"); default_fontColor=fontColor=QColor("black");
default_useSTIXfonts=useSTIXfonts=false; default_useSTIXfonts=useSTIXfonts=false;
default_useXITSfonts=useXITSfonts=false; default_useXITSfonts=useXITSfonts=false;
default_useASANAfonts=useASANAfonts=false; default_useASANAfonts=useASANAfonts=false;
default_frac_factor=frac_factor=0.9; default_frac_factor=frac_factor=0.9;
default_frac_shift_factor=frac_shift_factor=0.5; default_frac_shift_factor=frac_shift_factor=0.4;
default_underbrace_factor=underbrace_factor=0.75; default_underbrace_factor=underbrace_factor=0.75;
default_undersetFactor=undersetFactor=0.7; default_undersetFactor=undersetFactor=0.7;
default_decoration_height_factor=decoration_height_factor=0.2; default_decoration_height_factor=decoration_height_factor=0.2;
@ -4039,7 +4026,7 @@ JKQTMathText::MTnode* JKQTMathText::parseLatexString(bool get, const QString& qu
QList<JKQTMathText::tbrData> JKQTMathText::tbrs=QList<JKQTMathText::tbrData>(); QList<JKQTMathText::tbrData> JKQTMathText::tbrs=QList<JKQTMathText::tbrData>();
QHash<JKQTMathText::tbrDataH, QRectF> JKQTMathText::tbrh=QHash<JKQTMathText::tbrDataH, QRectF>(); QHash<JKQTMathText::tbrDataH, QRectF> JKQTMathText::tbrh=QHash<JKQTMathText::tbrDataH, QRectF>();
QRectF JKQTMathText::getTBR(const QFont &fm, const QString &text, QPaintDevice *pd) QRectF JKQTMathText::getTightBoundingRect(const QFont &fm, const QString &text, QPaintDevice *pd)
{ {
JKQTMathText::tbrDataH dh(fm, text, pd); JKQTMathText::tbrDataH dh(fm, text, pd);
if (pd) { if (pd) {
@ -4406,3 +4393,5 @@ void initJKQTMathTextResources()
{ {
Q_INIT_RESOURCE(xits); Q_INIT_RESOURCE(xits);
} }
JKQTMathText::MTnodeSize::MTnodeSize(): width(0), baselineHeight(0),overallHeight(0),strikeoutPos() {}

View File

@ -666,51 +666,110 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
protected: protected:
/** \brief the available fonts */ /** \brief the available fonts */
enum MTenvironmentFont { MTEroman, MTEsans, MTEtypewriter, MTEscript, MTEblackboard, MTEcaligraphic }; enum MTenvironmentFont {
MTEroman,
MTEsans,
MTEtypewriter,
MTEscript,
MTEblackboard,
MTEcaligraphic
};
/** \brief describes the current drawing environment (base fontname ...) */ /** \brief describes the current drawing environment (base fontname ...) */
struct MTenvironment { struct MTenvironment {
MTenvironment(); MTenvironment();
/** \brief current font color */
QColor color; QColor color;
/** \brief current font */
MTenvironmentFont font; MTenvironmentFont font;
/** \brief current font size [pt] */
double fontSize; double fontSize;
/** \brief is the text currently bold? */
bool bold; bool bold;
/** \brief is the text currently italic? */
bool italic; bool italic;
/** \brief is the text currently in small caps? */
bool smallCaps; bool smallCaps;
/** \brief is the text currently underlined? */
bool underlined; bool underlined;
/** \brief is the text currently overlined? */
bool overline; bool overline;
/** \brief is the text currently stroke through? */
bool strike; bool strike;
/** \brief is the text currently are we inside a math environment? */
bool insideMath; bool insideMath;
/** \brief build a QFont object from the settings in this object */
QFont getFont(JKQTMathText* parent) const; QFont getFont(JKQTMathText* parent) const;
/** \brief generate a HTML prefix that formats the text after it according to the settings in this object
*
* \param defaultEv environment before applying the current object (to detect changes)
* \see toHtmlAfter()
*/
QString toHtmlStart(MTenvironment defaultEv) const; QString toHtmlStart(MTenvironment defaultEv) const;
/** \brief generate a HTML postfix that formats the text in front of it according to the settings in this object
*
* \param defaultEv environment before applying the current object (to detect changes)
* \see toHtmlAfter()
*/
QString toHtmlAfter(MTenvironment defaultEv) const; QString toHtmlAfter(MTenvironment defaultEv) const;
}; };
/** \brief beschreibt die Größe eines Knotens */
struct MTnodeSize {
MTnodeSize();
double width;
double baselineHeight;
double overallHeight;
double strikeoutPos;
};
public: public:
/** \brief subclass representing one node in the syntax tree */ /** \brief subclass representing one node in the syntax tree
*
* \image html jkqtmathtext_node_geo.png
*/
class MTnode { class MTnode {
public: public:
MTnode(JKQTMathText* parent); MTnode(JKQTMathText* parent);
virtual ~MTnode(); virtual ~MTnode();
/** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal() */ /** \brief determine the size of the node, calls getSizeInternal() implementation of the actual type \see getSizeInternal()
void getSize(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos); *
/** \brief draw the contents at the designated position. returns the x position which to use for the next part of the text */ * \param painter painter to use for determining the size
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv)=0; * \param currentEv current environment object
/** \brief returns true if node is subscript or superscript node */ * \param[out] width width of the block/node
virtual bool isSubOrSuper() { return false; } * \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline
/** \brief convert node to HTML and returns \c true on success */ * \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[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 getSize(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr);
/** \brief draw the contents at the designated position
*
* \param painter QPainter to use
* \param x x-position, where the drawing starts [Pixel]
* \param y Y-position of the baseline, where the drawing starts [Pixel]
* \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings
* \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 ...)
* \return the x position which to use for the next part of the text
*/
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr)=0;
/** \brief convert node to HTML and returns \c true on success
* \param[out] html new HTML code is APPENDED to this string
* \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings
* \param defaultEv JKQTMathText::MTenvironment object describing the default drawing environment/settings when starting to interpret a node tree
* \return \c true on success
*/
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv);
/*! \brief returns the property drawBoxes ( \copybrief drawBoxes ). /** \brief returns the drawing of colored boxes (for DEBUGGING) around the actual output of the node is enabled */
\details Description of the parameter drawBoxes is: <BLOCKQUOTE>\copydoc drawBoxes </BLOCKQUOTE>. bool getDrawBoxes() const;
\see drawBoxes for more information */ /** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */
inline bool getDrawBoxes() const {
return this->drawBoxes;
}
virtual void setDrawBoxes(bool draw); virtual void setDrawBoxes(bool draw);
/** \brief return the name of this class as a string */
virtual QString getTypeName() const; virtual QString getTypeName() const;
protected: protected:
/** \brief determine the size of the node, overwrite this function in derived classes /** \brief determine the size of the node, overwrite this function in derived classes
@ -721,12 +780,22 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
* \param[out] baselineHeight distance from the bottom of the block/node-box to the baseline * \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] 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] strikeoutPos position of the strikeout-line
* \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 ...)
* *
*/ */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos)=0; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr)=0;
/** \brief parent JKQTMathText object (required for several drawing operations */
JKQTMathText* parent; JKQTMathText* parent;
/** \brief enables the drawing of colored boxes (for DEBUGGING) around the actual output of the node */
bool drawBoxes; bool drawBoxes;
/** \brief draws colored boxes (for DEBUGGING) around the actual output of the node
*
* \param painter QPainter to use
* \param x x-position, where the drawing starts [Pixel]
* \param y Y-position of the baseline, where the drawing starts [Pixel]
* \param currentEv JKQTMathText::MTenvironment object describing the current drawing environment/settings
*/
void doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv); void doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv);
}; };
@ -734,9 +803,11 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTtextNode: public MTnode { class MTtextNode: public MTnode {
public: public:
MTtextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); MTtextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false);
virtual ~MTtextNode(); virtual ~MTtextNode() override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
/** \copydoc MTnode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/*! \brief returns the property text ( \copybrief text ). /*! \brief returns the property text ( \copybrief text ).
\details Description of the parameter text is: <BLOCKQUOTE>\copydoc text </BLOCKQUOTE>. \details Description of the parameter text is: <BLOCKQUOTE>\copydoc text </BLOCKQUOTE>.
\see text for more information */ \see text for more information */
@ -746,8 +817,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
virtual QString getTypeName() const override ; virtual QString getTypeName() const override ;
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
QString text; 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); virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false);
}; };
@ -755,28 +827,35 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTplainTextNode: public MTtextNode { class MTplainTextNode: public MTtextNode {
public: public:
MTplainTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false); MTplainTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false);
virtual QString getTypeName() const; /** \copydoc MTnode::getTypeName() */
virtual QString getTypeName() const override;
protected: protected:
virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false); /** \copydoc MTtextNode::textTransform() */
virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false) override;
}; };
/** \brief subclass representing one whitepsace node in the syntax tree */ /** \brief subclass representing one whitepsace node in the syntax tree */
class MTwhitespaceNode: public MTtextNode { class MTwhitespaceNode: public MTtextNode {
public: public:
MTwhitespaceNode(JKQTMathText* parent); MTwhitespaceNode(JKQTMathText* parent);
virtual ~MTwhitespaceNode(); virtual ~MTwhitespaceNode() override;
virtual QString getTypeName() const; /** \copydoc MTnode::getTypeName() */
virtual QString getTypeName() const override;
/** \brief convert node to HTML and returns \c true on success */ /** \brief convert node to HTML and returns \c true on success */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); /** \copydoc MTnode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
}; };
/** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree */ /** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree */
class MTsymbolNode: public MTnode { class MTsymbolNode: public MTnode {
public: public:
MTsymbolNode(JKQTMathText* parent, const QString& name, bool addWhitespace); MTsymbolNode(JKQTMathText* parent, const QString& name, bool addWhitespace);
virtual ~MTsymbolNode(); virtual ~MTsymbolNode() override;
virtual QString getTypeName() const; /** \copydoc MTnode::getTypeName() */
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); virtual QString getTypeName() const override;
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); /** \copydoc MTnode::draw() */
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
/** \copydoc MTnode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/*! \brief returns the property symbolName ( \copybrief symbolName ). /*! \brief returns the property symbolName ( \copybrief symbolName ).
\details Description of the parameter symbolName is: <BLOCKQUOTE>\copydoc symbolName </BLOCKQUOTE>. \details Description of the parameter symbolName is: <BLOCKQUOTE>\copydoc symbolName </BLOCKQUOTE>.
\see symbolName for more information */ \see symbolName for more information */
@ -785,7 +864,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
/** \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 symbol; QString symbol;
/** \brief the symbol name supplied to the constructor */ /** \brief the symbol name supplied to the constructor */
@ -812,18 +891,20 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
}; };
/** \brief subclass representing a list of nodes in the syntax tree /** \brief subclass representing a list of nodes in the syntax tree
*
* \image html jkqtmathtext_MTlistNode_getSizeInternal_frac.png
*/ */
class MTlistNode: public MTnode { class MTlistNode: public MTnode {
public: public:
MTlistNode(JKQTMathText* parent); MTlistNode(JKQTMathText* parent);
virtual ~MTlistNode(); virtual ~MTlistNode() override;
virtual QString getTypeName() const; /** \copydoc MTnode::getTypeName() */
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); virtual QString getTypeName() const override;
/** \copydoc MTnode::draw() */
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
void addNode(MTnode* n) { nodes.append(n); } void addNode(MTnode* n) { nodes.append(n); }
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); /** \copydoc MTnode::toHtml() */
virtual void setDrawBoxes(bool draw); virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/** \copydoc MTnode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
/*! \brief returns the property nodes ( \copybrief nodes ). /*! \brief returns the property nodes ( \copybrief nodes ).
\details Description of the parameter nodes is: <BLOCKQUOTE>\copydoc nodes </BLOCKQUOTE>. \details Description of the parameter nodes is: <BLOCKQUOTE>\copydoc nodes </BLOCKQUOTE>.
\see nodes for more information */ \see nodes for more information */
@ -832,7 +913,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
QList<MTnode*> nodes; QList<MTnode*> nodes;
QSet<QString> subsupOperations; QSet<QString> subsupOperations;
}; };
@ -841,16 +922,18 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTinstruction1Node: public MTnode { class MTinstruction1Node: public MTnode {
public: public:
MTinstruction1Node(JKQTMathText* parent, const QString& name, MTnode* child, const QStringList& parameters=QStringList()); MTinstruction1Node(JKQTMathText* parent, const QString& name, MTnode* child, const QStringList& parameters=QStringList());
virtual ~MTinstruction1Node(); virtual ~MTinstruction1Node() override;
virtual QString getTypeName() const; /** \copydoc MTnode::getTypeName() */
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); 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 convert node to HTML and returns \c true on success */ /** \brief convert node to HTML and returns \c true on success */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); /** \copydoc MTnode::toHtml() */
virtual void setDrawBoxes(bool draw); virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/*! \brief returns the property child ( \copybrief child ). /** \copydoc MTnode::setDrawBoxes() */
\details Description of the parameter child is: <BLOCKQUOTE>\copydoc child </BLOCKQUOTE>. virtual void setDrawBoxes(bool draw) override;
\see child for more information */ /*! \brief returns the child node */
inline MTnode* getChild() const { inline MTnode* getChild() const {
return this->child; return this->child;
} }
/*! \brief returns the property name ( \copybrief name ). /*! \brief returns the property name ( \copybrief name ).
@ -867,7 +950,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
bool setupMTenvironment(JKQTMathText::MTenvironment &ev); bool setupMTenvironment(JKQTMathText::MTenvironment &ev);
MTnode* child; MTnode* child;
@ -877,49 +960,56 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
/** \brief subclass representing an subscript node with exactly one argument in the syntax tree */ /** \brief subclass representing an subscript node with exactly one argument in the syntax tree
*
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png
*/
class MTsubscriptNode: public MTnode { class MTsubscriptNode: public MTnode {
public: public:
MTsubscriptNode(JKQTMathText* parent, MTnode* child); MTsubscriptNode(JKQTMathText* parent, MTnode* child);
virtual ~MTsubscriptNode(); virtual ~MTsubscriptNode() override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
/** \brief returns true if node is subscript or superscript node */ virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual bool isSubOrSuper() ; /** \copydoc MTnode::getTypeName() */
virtual QString getTypeName() const; virtual QString getTypeName() const override; /*! \brief returns the child node */
/*! \brief returns the property child ( \copybrief child ). inline MTnode* getChild() const {
\details Description of the parameter child is: <BLOCKQUOTE>\copydoc child </BLOCKQUOTE>.
\see child for more information */
inline MTnode* getChild() const {
return this->child; return this->child;
} }
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); /** \copydoc MTnode::toHtml() */
virtual void setDrawBoxes(bool draw); virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/** \copydoc MTnode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
MTnode* child; MTnode* child;
}; };
/** \brief subclass representing an superscript node with exactly one argument in the syntax tree */ /** \brief subclass representing an superscript node with exactly one argument in the syntax tree
*
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png
*
* \note a MTlistNode might modify the positioning slightly for special cases (e.g. \c \\int , \c \\sum ... or after braces)
*/
class MTsuperscriptNode: public MTnode { class MTsuperscriptNode: public MTnode {
public: public:
MTsuperscriptNode(JKQTMathText* parent, MTnode* child); MTsuperscriptNode(JKQTMathText* parent, MTnode* child);
virtual ~MTsuperscriptNode(); virtual ~MTsuperscriptNode() override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
/** \brief returns true if node is subscript or superscript node */ virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual bool isSubOrSuper(); /*! \brief returns the child node */
/*! \brief returns the property child ( \copybrief child ).
\details Description of the parameter child is: <BLOCKQUOTE>\copydoc child </BLOCKQUOTE>.
\see child for more information */
inline MTnode* getChild() const { inline MTnode* getChild() const {
return this->child; return this->child;
} }
virtual QString getTypeName() const; /** \copydoc MTnode::getTypeName() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual QString getTypeName() const override;
virtual void setDrawBoxes(bool draw); /** \copydoc MTnode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/** \copydoc MTnode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
MTnode* child; MTnode* child;
}; };
@ -927,15 +1017,17 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTbraceNode: public MTnode { class MTbraceNode: public MTnode {
public: public:
MTbraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, MTnode* child, bool showRightBrace=true); MTbraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, MTnode* child, bool showRightBrace=true);
virtual ~MTbraceNode(); virtual ~MTbraceNode() override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual void setDrawBoxes(bool draw); /** \copydoc MTnode::toHtml() */
virtual QString getTypeName() const; virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/*! \brief returns the property child ( \copybrief child ). /** \copydoc MTnode::setDrawBoxes() */
\details Description of the parameter child is: <BLOCKQUOTE>\copydoc child </BLOCKQUOTE>. virtual void setDrawBoxes(bool draw) override;
\see child for more information */ /** \copydoc MTnode::getTypeName() */
inline MTnode* getChild() const { virtual QString getTypeName() const override;
/*! \brief returns the child node */
inline MTnode* getChild() const {
return this->child; return this->child;
} }
/*! \brief returns the property openbrace ( \copybrief openbrace ). /*! \brief returns the property openbrace ( \copybrief openbrace ).
@ -958,7 +1050,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
MTnode* child; MTnode* child;
QString openbrace; QString openbrace;
QString closebrace; QString closebrace;
@ -972,15 +1064,16 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTsqrtNode: public MTnode { class MTsqrtNode: public MTnode {
public: public:
MTsqrtNode(JKQTMathText* parent, MTnode* child, int degree=2); MTsqrtNode(JKQTMathText* parent, MTnode* child, int degree=2);
virtual ~MTsqrtNode(); virtual ~MTsqrtNode() override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual void setDrawBoxes(bool draw); /** \copydoc MTnode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/** \copydoc MTnode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
virtual QString getTypeName() const ; virtual QString getTypeName() const ;
/*! \brief returns the property child ( \copybrief child ). /*! \brief returns the child node */
\details Description of the parameter child is: <BLOCKQUOTE>\copydoc child </BLOCKQUOTE>. inline MTnode* getChild() const {
\see child for more information */
inline MTnode* getChild() const {
return this->child; return this->child;
} }
/*! \brief returns the property degree ( \copybrief degree ). /*! \brief returns the property degree ( \copybrief degree ).
@ -991,7 +1084,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
MTnode* child; MTnode* child;
int degree; int degree;
}; };
@ -1013,21 +1106,20 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTfracNode: public MTnode { class MTfracNode: public MTnode {
public: public:
MTfracNode(JKQTMathText* parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode); MTfracNode(JKQTMathText* parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode);
virtual ~MTfracNode(); virtual ~MTfracNode() override;
virtual QString getTypeName() const ; virtual QString getTypeName() const ;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual void setDrawBoxes(bool draw); /** \copydoc MTnode::toHtml() */
/*! \brief returns the property child1 ( \copybrief child1 ). virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
\details Description of the parameter child1 is: <BLOCKQUOTE>\copydoc child1 </BLOCKQUOTE>. /** \copydoc MTnode::setDrawBoxes() */
\see child1 for more information */ virtual void setDrawBoxes(bool draw) override;
inline MTnode* getChild1() const { /*! \brief returns the 1st child node */
inline MTnode* getChild1() const {
return this->child1; return this->child1;
} }
/*! \brief returns the property child2 ( \copybrief child2 ). /*! \brief returns the 2nd child node */
\details Description of the parameter child2 is: <BLOCKQUOTE>\copydoc child2 </BLOCKQUOTE>. inline MTnode* getChild2() const {
\see child2 for more information */
inline MTnode* getChild2() const {
return this->child2; return this->child2;
} }
/*! \brief returns the property mode ( \copybrief mode ). /*! \brief returns the property mode ( \copybrief mode ).
@ -1038,7 +1130,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
MTnode* child1; MTnode* child1;
MTnode* child2; MTnode* child2;
MTfracMode mode; MTfracMode mode;
@ -1049,13 +1141,12 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
public: public:
MTmatrixNode(JKQTMathText* parent, QVector<QVector<MTnode*> > children); MTmatrixNode(JKQTMathText* parent, QVector<QVector<MTnode*> > children);
virtual ~MTmatrixNode() override; virtual ~MTmatrixNode() override;
/** \copydoc MTnode::getTypeName() */
virtual QString getTypeName() const override; virtual QString getTypeName() const override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv) override; virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override; virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/*! \brief returns the property children ( \copybrief children ). /*! \brief returns the child nodes */
\details Description of the parameter children is: <BLOCKQUOTE>\copydoc children </BLOCKQUOTE>. inline QVector<QVector<MTnode*> > getChildren() const {
\see children for more information */
inline QVector<QVector<MTnode*> > getChildren() const {
return this->children; return this->children;
} }
/*! \brief returns the property columns ( \copybrief columns ). /*! \brief returns the property columns ( \copybrief columns ).
@ -1072,8 +1163,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
virtual void setDrawBoxes(bool draw); /** \copydoc MTnode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
QVector<QVector<MTnode*> > children; QVector<QVector<MTnode*> > children;
int columns; int columns;
int lines; int lines;
@ -1099,15 +1191,16 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
class MTdecoratedNode: public MTnode { class MTdecoratedNode: public MTnode {
public: public:
MTdecoratedNode(JKQTMathText* parent, MTdecoration decoration, MTnode* child); MTdecoratedNode(JKQTMathText* parent, MTdecoration decoration, MTnode* child);
virtual ~MTdecoratedNode(); virtual ~MTdecoratedNode() override;
virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv); /** \copydoc MTnode::draw() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv); virtual double draw(QPainter& painter, double x, double y, MTenvironment currentEv, const MTnodeSize* prevNodeSize=nullptr) override;
virtual void setDrawBoxes(bool draw); /** \copydoc MTnode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
/** \copydoc MTnode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
virtual QString getTypeName() const ; virtual QString getTypeName() const ;
/*! \brief returns the property child ( \copybrief child ). /*! \brief returns the child node */
\details Description of the parameter child is: <BLOCKQUOTE>\copydoc child </BLOCKQUOTE>. inline MTnode* getChild() const {
\see child for more information */
inline MTnode* getChild() const {
return this->child; return this->child;
} }
/*! \brief returns the property decoration ( \copybrief decoration ). /*! \brief returns the property decoration ( \copybrief decoration ).
@ -1118,7 +1211,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
} }
protected: protected:
/** \copydoc MTnode::getSizeInternal() */ /** \copydoc MTnode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos) override; virtual void getSizeInternal(QPainter& painter, MTenvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const MTnodeSize* prevNodeSize=nullptr) override;
MTnode* child; MTnode* child;
MTdecoration decoration; MTdecoration decoration;
}; };
@ -1386,7 +1479,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
}; };
static QList<JKQTMathText::tbrData> tbrs; static QList<JKQTMathText::tbrData> tbrs;
static QHash<JKQTMathText::tbrDataH, QRectF> tbrh; static QHash<JKQTMathText::tbrDataH, QRectF> tbrh;
static QRectF getTBR(const QFont &fm, const QString& text, QPaintDevice *pd); static QRectF getTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd);
}; };