2022-06-08 21:38:26 +08:00
|
|
|
/*
|
|
|
|
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This software is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
|
|
|
the Free Software Foundation, either version 2.1 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License (LGPL) for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "jkqtmathtext/nodes/jkqtmathtextfracnode.h"
|
2022-06-09 05:52:22 +08:00
|
|
|
#include "jkqtmathtext/nodes/jkqtmathtextbracenode.h"
|
2022-06-08 21:38:26 +08:00
|
|
|
#include "jkqtmathtext/jkqtmathtexttools.h"
|
|
|
|
#include "jkqtmathtext/jkqtmathtext.h"
|
|
|
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
|
|
|
#include "jkqtcommon/jkqtpstringtools.h"
|
|
|
|
#include <cmath>
|
|
|
|
#include <QFontMetricsF>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QFontDatabase>
|
|
|
|
#include <QFontInfo>
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QFont>
|
|
|
|
|
|
|
|
|
2022-07-07 04:44:02 +08:00
|
|
|
QHash<QString, JKQTMathTextFracNode::FracType> JKQTMathTextFracNode::instructions;
|
|
|
|
|
|
|
|
|
|
|
|
void JKQTMathTextFracNode::fillInstructions()
|
|
|
|
{
|
2023-06-30 19:52:17 +08:00
|
|
|
static std::mutex sMutex;
|
|
|
|
std::lock_guard<std::mutex> lock(sMutex);
|
2022-07-07 04:44:02 +08:00
|
|
|
if (instructions.size()>0) return;
|
|
|
|
instructions["frac"]=MTFMfrac;
|
|
|
|
instructions["dfrac"] = MTFMdfrac;
|
|
|
|
instructions["cfrac"]=MTFMdfrac;
|
|
|
|
instructions["sfrac"] = MTFMsfrac;
|
|
|
|
instructions["slantfrac"] = MTFMsfrac;
|
|
|
|
instructions["xfrac"]=MTFMsfrac;
|
|
|
|
instructions["stfrac"] = MTFMstfrac;
|
|
|
|
instructions["nicefrac"] = MTFMstfrac;
|
|
|
|
instructions["slanttextfrac"] = MTFMstfrac;
|
|
|
|
instructions["xtfrac"]=MTFMstfrac;
|
|
|
|
instructions["tfrac"]=MTFMtfrac;
|
|
|
|
instructions["stackrel"]=MTFMstackrel;
|
|
|
|
instructions["underbrace"]=MTFMunderbrace;
|
|
|
|
instructions["underbracket"]=MTFMunderbracket;
|
|
|
|
instructions["underset"]=MTFMunderset;
|
|
|
|
instructions["overbrace"]=MTFMoverbrace;
|
|
|
|
instructions["overbracket"]=MTFMoverbracket;
|
|
|
|
instructions["overset"]=MTFMoverset;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
|
2022-06-10 02:32:16 +08:00
|
|
|
QString JKQTMathTextFracNode::FracType2String(JKQTMathTextFracNode::FracType mode)
|
|
|
|
{
|
|
|
|
switch(mode) {
|
|
|
|
case JKQTMathTextFracNode::MTFMfrac:
|
|
|
|
return "frac";
|
|
|
|
case JKQTMathTextFracNode::MTFMdfrac:
|
|
|
|
return "dfrac";
|
|
|
|
case JKQTMathTextFracNode::MTFMsfrac:
|
|
|
|
return "sfrac";
|
|
|
|
case JKQTMathTextFracNode::MTFMstfrac:
|
|
|
|
return "stfrac";
|
|
|
|
case JKQTMathTextFracNode::MTFMtfrac:
|
|
|
|
return "tfrac";
|
|
|
|
case JKQTMathTextFracNode::MTFMunderbrace:
|
|
|
|
return "underbrace";
|
|
|
|
case JKQTMathTextFracNode::MTFMoverbrace:
|
|
|
|
return "overbrace";
|
2022-06-28 16:15:54 +08:00
|
|
|
case JKQTMathTextFracNode::MTFMunderbracket:
|
|
|
|
return "underbracket";
|
|
|
|
case JKQTMathTextFracNode::MTFMoverbracket:
|
|
|
|
return "overbracket";
|
2022-06-10 02:32:16 +08:00
|
|
|
case JKQTMathTextFracNode::MTFMunderset:
|
|
|
|
return "underset";
|
|
|
|
case JKQTMathTextFracNode::MTFMoverset:
|
|
|
|
return "overset";
|
|
|
|
case JKQTMathTextFracNode::MTFMstackrel:
|
|
|
|
return "stackrel";
|
|
|
|
}
|
|
|
|
return "unknown";
|
|
|
|
}
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-07-07 04:44:02 +08:00
|
|
|
JKQTMathTextFracNode::FracType JKQTMathTextFracNode::InstructionName2FracType(const QString &mode)
|
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
return instructions.value(mode, MTFMfrac);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JKQTMathTextFracNode::supportsInstructionName(const QString &instructionName)
|
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
return instructions.contains(instructionName);
|
|
|
|
}
|
|
|
|
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
|
2022-06-10 02:32:16 +08:00
|
|
|
JKQTMathTextFracNode::JKQTMathTextFracNode(JKQTMathText* _parent, JKQTMathTextNode* child_top, JKQTMathTextNode* child_bottom, JKQTMathTextFracNode::FracType mode):
|
2022-06-09 05:52:22 +08:00
|
|
|
JKQTMathTextDualChildNode(child_top, child_bottom, _parent)
|
2022-06-08 21:38:26 +08:00
|
|
|
{
|
|
|
|
this->mode=mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextFracNode::~JKQTMathTextFracNode() {
|
|
|
|
}
|
|
|
|
|
|
|
|
QString JKQTMathTextFracNode::getTypeName() const
|
|
|
|
{
|
|
|
|
return "MTfracNode";
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
|
2022-08-19 18:16:00 +08:00
|
|
|
FracType fracmode=this->mode;
|
|
|
|
if (currentEv.isMathTextStyle()) {
|
|
|
|
if (fracmode==MTFMfrac) fracmode=MTFMtfrac;
|
|
|
|
if (fracmode==MTFMsfrac) fracmode=MTFMstfrac;
|
|
|
|
}
|
2022-06-09 17:32:57 +08:00
|
|
|
const QFont f=currentEv.getFont(parentMathText);
|
|
|
|
const QFontMetricsF fm(f, painter.device());
|
2022-06-08 21:38:26 +08:00
|
|
|
JKQTMathTextEnvironment ev1=currentEv;
|
|
|
|
JKQTMathTextEnvironment ev2=currentEv;
|
|
|
|
|
2022-06-09 05:52:22 +08:00
|
|
|
const double xheight=fm.xHeight(); //tightBoundingRect("x").height();
|
|
|
|
const double line_ascent=xheight/2.0;
|
2022-07-22 04:17:37 +08:00
|
|
|
//const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
2022-06-09 17:32:57 +08:00
|
|
|
const double xwidth=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width();
|
|
|
|
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
2022-06-28 03:09:22 +08:00
|
|
|
const double braceheight=fm.xHeight()*parentMathText->getUnderbraceBraceSizeXFactor();
|
|
|
|
const double braceseparation=fm.xHeight()*parentMathText->getUnderbraceSeparationXFactor();
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-19 18:16:00 +08:00
|
|
|
if (fracmode==JKQTMathTextFracNode::MTFMunderbrace || fracmode==JKQTMathTextFracNode::MTFMoverbrace||fracmode==JKQTMathTextFracNode::MTFMunderbracket || fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev2.fontSize=ev2.fontSize*parentMathText->getUnderbraceFactor();
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset || fracmode==JKQTMathTextFracNode::MTFMoverset) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev2.fontSize=ev2.fontSize*parentMathText->getUndersetFactor();
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev1.fontSize=ev1.fontSize*getFracScalingFactor();
|
|
|
|
ev2.fontSize=ev2.fontSize*getFracScalingFactor();
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMtfrac || fracmode==JKQTMathTextFracNode::MTFMstfrac) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev1.fontSize=ev1.fontSize*getFracScalingFactor()*0.7;
|
|
|
|
ev2.fontSize=ev2.fontSize*getFracScalingFactor()*0.7;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-08-12 22:50:26 +08:00
|
|
|
const QFontMetricsF fmev1(ev1.getFont(parentMathText), painter.device());
|
|
|
|
const QRectF AeTBR1=fmev1.tightBoundingRect("A");
|
|
|
|
const double asc1=AeTBR1.height();
|
|
|
|
const QFontMetricsF fmev2(ev2.getFont(parentMathText), painter.device());
|
|
|
|
const QRectF AeTBR2=fmev2.tightBoundingRect("A");
|
|
|
|
const double asc2=AeTBR2.height();
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize size1=child1->getSize(painter, ev1);
|
|
|
|
JKQTMathTextNodeSize size2=child2->getSize(painter, ev2);
|
|
|
|
if (asc1>size1.baselineHeight) {
|
|
|
|
const double oldDescent=size1.overallHeight-size1.baselineHeight;
|
|
|
|
size1.baselineHeight=asc1;
|
|
|
|
size1.overallHeight=size1.baselineHeight+oldDescent;
|
2022-08-12 22:50:26 +08:00
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
if (asc2>size2.baselineHeight) {
|
|
|
|
const double oldDescent=size2.overallHeight-size2.baselineHeight;
|
|
|
|
size2.baselineHeight=asc2;
|
|
|
|
size2.overallHeight=size2.baselineHeight+oldDescent;
|
2022-08-12 22:50:26 +08:00
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
const double descent1=size1.overallHeight-size1.baselineHeight;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize size;
|
|
|
|
size.overallHeight=0;
|
|
|
|
size.baselineHeight=0;
|
|
|
|
size.width=0;
|
2022-08-19 18:16:00 +08:00
|
|
|
if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMdfrac || fracmode==JKQTMathTextFracNode::MTFMtfrac || fracmode==JKQTMathTextFracNode::MTFMstackrel) {
|
2022-06-09 05:52:22 +08:00
|
|
|
const double top_ascent=line_ascent+xheight*parentMathText->getFracShiftFactor();
|
|
|
|
const double bot_ascent=line_ascent-xheight*parentMathText->getFracShiftFactor();
|
2022-08-17 05:05:04 +08:00
|
|
|
const double newascent=size1.overallHeight+top_ascent;
|
|
|
|
const double newdescent=size2.overallHeight-bot_ascent;
|
|
|
|
size.width=qMax(size1.width, size2.width);
|
2022-08-19 18:16:00 +08:00
|
|
|
if (fracmode!=JKQTMathTextFracNode::MTFMstackrel) size.width+=xwidth/2.0;
|
2022-08-17 05:05:04 +08:00
|
|
|
size.strikeoutPos=line_ascent;
|
2022-06-09 05:52:22 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
size.overallHeight=newascent+newdescent;
|
|
|
|
size.baselineHeight=newascent;
|
2022-06-09 05:52:22 +08:00
|
|
|
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMstfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
|
2022-06-09 05:52:22 +08:00
|
|
|
const double top_ascent=line_ascent;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double newascent=size1.overallHeight+top_ascent;
|
|
|
|
const double newdescent=qMax(size2.overallHeight-size2.baselineHeight, qheight-xheight);
|
|
|
|
size.width=size1.width+size2.width+xwidth*0.666;
|
|
|
|
size.strikeoutPos=line_ascent;
|
2022-06-09 05:52:22 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
size.overallHeight=newascent+newdescent;
|
|
|
|
size.baselineHeight=newascent;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderbrace || fracmode==JKQTMathTextFracNode::MTFMunderbracket) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const double newdescent=descent1+size2.overallHeight+braceheight+2.0*braceseparation;
|
|
|
|
size.overallHeight=newdescent+size1.baselineHeight;
|
|
|
|
size.baselineHeight=size1.baselineHeight;
|
|
|
|
size.width=qMax(size1.width, size2.width)+xwidth;
|
|
|
|
size.strikeoutPos=line_ascent;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMoverbrace || fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
|
2022-08-17 05:05:04 +08:00
|
|
|
size.overallHeight=size1.overallHeight+size2.overallHeight+braceheight+2.0*braceseparation;
|
|
|
|
size.baselineHeight=size1.baselineHeight+size2.overallHeight+braceheight+2.0*braceseparation;
|
|
|
|
size.width=qMax(size1.width, size2.width)+xwidth;
|
|
|
|
size.strikeoutPos=line_ascent;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset) {
|
2022-08-17 05:05:04 +08:00
|
|
|
size.overallHeight=size1.overallHeight+size2.overallHeight+xheight/6.0;
|
|
|
|
size.baselineHeight=size1.baselineHeight;
|
|
|
|
size.width=qMax(size1.width, size2.width)+xwidth;
|
|
|
|
size.strikeoutPos=line_ascent;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMoverset) {
|
2022-08-17 05:05:04 +08:00
|
|
|
size.overallHeight=size1.overallHeight+size1.overallHeight+xheight/6.0;
|
|
|
|
size.baselineHeight=size1.baselineHeight+size2.overallHeight+xheight/6.0;
|
|
|
|
size.width=qMax(size1.width, size2.width)+xwidth;
|
|
|
|
size.strikeoutPos=line_ascent;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
return size;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-07-22 04:17:37 +08:00
|
|
|
int JKQTMathTextFracNode::getNestingLevel(bool /*sameType*/) const
|
2022-06-09 05:52:22 +08:00
|
|
|
{
|
|
|
|
QList<const JKQTMathTextFracNode*> parents=getParents<JKQTMathTextFracNode>();
|
|
|
|
int cnt=0;
|
|
|
|
for (auto& p: parents) {
|
|
|
|
if (p && p->getMode()==getMode()) cnt++;
|
|
|
|
}
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
double JKQTMathTextFracNode::getFracScalingFactor() const
|
|
|
|
{
|
2022-06-10 02:32:16 +08:00
|
|
|
if (mode!=JKQTMathTextFracNode::MTFMdfrac) {
|
2022-06-09 05:52:22 +08:00
|
|
|
const int level=getNestingLevel(true);
|
|
|
|
if (level>=1) return parentMathText->getFracNestedFactor();
|
|
|
|
}
|
|
|
|
return parentMathText->getFracFactor();
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
2022-08-19 18:16:00 +08:00
|
|
|
FracType fracmode=this->mode;
|
|
|
|
if (currentEv.isMathTextStyle()) {
|
|
|
|
if (fracmode==MTFMfrac) fracmode=MTFMtfrac;
|
|
|
|
if (fracmode==MTFMsfrac) fracmode=MTFMstfrac;
|
|
|
|
}
|
|
|
|
|
2022-06-08 21:38:26 +08:00
|
|
|
doDrawBoxes(painter, x, y, currentEv);
|
2022-06-09 17:32:57 +08:00
|
|
|
const QFont f=currentEv.getFont(parentMathText);
|
2022-06-09 05:52:22 +08:00
|
|
|
const QFontMetricsF fm(f, painter.device());
|
2022-06-08 21:38:26 +08:00
|
|
|
JKQTMathTextEnvironment ev1=currentEv;
|
|
|
|
JKQTMathTextEnvironment ev2=currentEv;
|
|
|
|
|
|
|
|
|
2022-06-09 17:32:57 +08:00
|
|
|
const double xheight=fm.xHeight();
|
|
|
|
const double xwidth=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width();
|
2022-07-06 04:03:08 +08:00
|
|
|
const double linewideth=fm.lineWidth();
|
2022-06-09 17:32:57 +08:00
|
|
|
const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
|
|
|
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
2022-06-28 03:09:22 +08:00
|
|
|
const double braceheight=fm.xHeight()*parentMathText->getUnderbraceBraceSizeXFactor();
|
|
|
|
const double braceseparation=fm.xHeight()*parentMathText->getUnderbraceSeparationXFactor();
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-19 18:16:00 +08:00
|
|
|
if (fracmode==JKQTMathTextFracNode::MTFMunderbrace || fracmode==JKQTMathTextFracNode::MTFMoverbrace||fracmode==JKQTMathTextFracNode::MTFMunderbracket || fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev2.fontSize=ev2.fontSize*parentMathText->getUnderbraceFactor();
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset || fracmode==JKQTMathTextFracNode::MTFMoverset) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev2.fontSize=ev2.fontSize*parentMathText->getUndersetFactor();
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev1.fontSize=ev1.fontSize*getFracScalingFactor();
|
|
|
|
ev2.fontSize=ev2.fontSize*getFracScalingFactor();
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMtfrac || fracmode==JKQTMathTextFracNode::MTFMstfrac) {
|
2022-06-09 05:52:22 +08:00
|
|
|
ev1.fontSize=ev1.fontSize*getFracScalingFactor()*0.7;
|
|
|
|
ev2.fontSize=ev2.fontSize*getFracScalingFactor()*0.7;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-12 22:50:26 +08:00
|
|
|
const QFontMetricsF fmev1(ev1.getFont(parentMathText), painter.device());
|
|
|
|
const QRectF AeTBR1=fmev1.tightBoundingRect("A");
|
|
|
|
const double asc1=AeTBR1.height();
|
|
|
|
const QFontMetricsF fmev2(ev2.getFont(parentMathText), painter.device());
|
|
|
|
const QRectF AeTBR2=fmev2.tightBoundingRect("A");
|
|
|
|
const double asc2=AeTBR2.height();
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize size1=child1->getSize(painter, ev1);
|
|
|
|
JKQTMathTextNodeSize size2=child2->getSize(painter, ev2);
|
|
|
|
if (asc1>size1.baselineHeight) {
|
|
|
|
const double oldDescent=size1.overallHeight-size1.baselineHeight;
|
|
|
|
size1.baselineHeight=asc1;
|
|
|
|
size1.overallHeight=size1.baselineHeight+oldDescent;
|
2022-08-12 22:50:26 +08:00
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
if (asc2>size2.baselineHeight) {
|
|
|
|
const double oldDescent=size2.overallHeight-size2.baselineHeight;
|
|
|
|
size2.baselineHeight=asc2;
|
|
|
|
size2.overallHeight=size2.baselineHeight+oldDescent;
|
2022-08-12 22:50:26 +08:00
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
const double ascent1=size1.baselineHeight;
|
|
|
|
const double descent1=size1.overallHeight-size1.baselineHeight;
|
|
|
|
const double ascent2=size2.baselineHeight;
|
|
|
|
const double descent2=size2.overallHeight-size2.baselineHeight;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-28 03:09:22 +08:00
|
|
|
const double yline=y-xheight*0.5;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
//double overallHeight=size1.overallHeight+size2.overallHeight+xh;
|
|
|
|
//double baselineHeight=3.0*xh/2.0+size1.overallHeight;
|
|
|
|
const double maxWidth=qMax(size1.width, size2.width);
|
2022-06-09 05:52:22 +08:00
|
|
|
double deltaWidth=0;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
QPen p=painter.pen();
|
|
|
|
p.setColor(ev1.color);
|
|
|
|
p.setStyle(Qt::SolidLine);
|
2022-06-09 17:32:57 +08:00
|
|
|
p.setWidthF(qMax(parentMathText->ABS_MIN_LINEWIDTH, linewideth));
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
|
|
|
painter.setPen(p);
|
2022-08-19 18:16:00 +08:00
|
|
|
if (fracmode==JKQTMathTextFracNode::MTFMfrac || fracmode==JKQTMathTextFracNode::MTFMdfrac || fracmode==JKQTMathTextFracNode::MTFMtfrac) {
|
2022-06-09 17:32:57 +08:00
|
|
|
deltaWidth=xwidth/2.0;
|
2022-07-06 04:03:08 +08:00
|
|
|
const QLineF l(x+p.widthF()*2.0, yline, x+maxWidth+deltaWidth-p.widthF()*2.0, yline);
|
2022-06-08 21:38:26 +08:00
|
|
|
if (l.length()>0) painter.drawLine(l);
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+deltaWidth/2.0+(maxWidth-size1.width)/2.0, yline-xheight*(parentMathText->getFracShiftFactor())-descent1, ev1);
|
|
|
|
child2->draw(painter, x+deltaWidth/2.0+(maxWidth-size2.width)/2.0, yline+xheight*(parentMathText->getFracShiftFactor())+ascent2, ev2);
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMstackrel) {
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+(maxWidth-size1.width)/2.0, yline-xheight*(parentMathText->getFracShiftFactor())-descent1, ev1);
|
|
|
|
child2->draw(painter, x+(maxWidth-size2.width)/2.0, yline+xheight*(parentMathText->getFracShiftFactor())+ascent2, ev2);
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMstfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) {
|
2022-08-12 22:50:26 +08:00
|
|
|
deltaWidth=xwidth*0.666;
|
2022-06-09 17:32:57 +08:00
|
|
|
child1->draw(painter, x, yline, ev1);
|
2022-08-17 05:05:04 +08:00
|
|
|
child2->draw(painter, x+size1.width+deltaWidth, y, ev2);
|
|
|
|
const QLineF l(x+size1.width+deltaWidth, y-Mheight, x+size1.width, y+(qheight-xheight));
|
2022-06-08 21:38:26 +08:00
|
|
|
if (l.length()>0) painter.drawLine(l);
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderset) {
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
|
|
|
|
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, y+descent1+xheight/6.0+ascent2, ev2);
|
2022-06-09 17:32:57 +08:00
|
|
|
deltaWidth=xwidth;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderbrace) {
|
2022-06-28 03:09:22 +08:00
|
|
|
const double ybrace=y+descent1+braceseparation+braceheight/2.0;
|
|
|
|
const double ybot=y+descent1+2.0*braceseparation+braceheight+ascent2;
|
2022-06-27 05:42:06 +08:00
|
|
|
{
|
2022-08-17 05:05:04 +08:00
|
|
|
const QPainterPath path=JKQTMathTextMakeHBracePath(x+xwidth/2.0+(size1.width)/2.0, ybrace, maxWidth, braceheight, p.width());
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(0.0001);
|
|
|
|
painter.fillPath(path, QBrush(ev1.color));
|
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
|
|
|
|
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ybot, ev2);
|
2022-06-09 17:32:57 +08:00
|
|
|
deltaWidth=xwidth;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMunderbracket) {
|
2022-06-28 16:15:54 +08:00
|
|
|
const double ybrace=y+descent1+braceseparation+braceheight/2.0;
|
|
|
|
const double ybot=y+descent1+2.0*braceseparation+braceheight+ascent2;
|
|
|
|
{
|
|
|
|
QPainterPath path;
|
|
|
|
const double y1=ybrace-braceheight/2.0;
|
|
|
|
const double y2=ybrace+braceheight/2.0;
|
|
|
|
const double x1=x+xwidth/2.0+p.width()/2.0;
|
|
|
|
const double x2=x+xwidth/2.0+maxWidth-p.width()/2.0;
|
|
|
|
path.moveTo(x1, y1);
|
|
|
|
path.lineTo(x1, y2);
|
|
|
|
path.lineTo(x2, y2);
|
|
|
|
path.lineTo(x2, y1);
|
|
|
|
painter.drawPath(path);
|
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
|
|
|
|
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ybot, ev2);
|
2022-06-28 16:15:54 +08:00
|
|
|
deltaWidth=xwidth;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMoverset) {
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
|
|
|
|
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, y-ascent1-xheight/6.0-descent2, ev2);
|
2022-06-09 17:32:57 +08:00
|
|
|
deltaWidth=xwidth;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMoverbrace) {
|
2022-06-28 03:09:22 +08:00
|
|
|
const double ybrace=y-ascent1-braceheight/2.0-braceseparation;
|
|
|
|
const double ytop=y-ascent1-2.0*braceseparation-braceheight-descent2;
|
2022-06-08 21:38:26 +08:00
|
|
|
{
|
|
|
|
painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();});
|
2022-08-17 05:05:04 +08:00
|
|
|
painter.translate(x+xwidth/2.0+(size1.width)/2.0, ybrace);
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.rotate(180);
|
2022-06-28 03:09:22 +08:00
|
|
|
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0, maxWidth, braceheight, p.widthF());
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(0.0001);
|
|
|
|
painter.fillPath(path, QBrush(ev1.color));
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
|
|
|
|
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ytop, ev2);
|
2022-06-28 16:15:54 +08:00
|
|
|
deltaWidth=xwidth;
|
2022-08-19 18:16:00 +08:00
|
|
|
} else if (fracmode==JKQTMathTextFracNode::MTFMoverbracket) {
|
2022-06-28 16:15:54 +08:00
|
|
|
const double ybrace=y-ascent1-braceheight/2.0-braceseparation;
|
|
|
|
const double ytop=y-ascent1-2.0*braceseparation-braceheight-descent2;
|
|
|
|
{
|
|
|
|
QPainterPath path;
|
|
|
|
const double y1=ybrace+braceheight/2.0;
|
|
|
|
const double y2=ybrace-braceheight/2.0;
|
|
|
|
const double x1=x+xwidth/2.0+p.width()/2.0;
|
|
|
|
const double x2=x+xwidth/2.0+maxWidth-p.width()/2.0;
|
|
|
|
path.moveTo(x1, y1);
|
|
|
|
path.lineTo(x1, y2);
|
|
|
|
path.lineTo(x2, y2);
|
|
|
|
path.lineTo(x2, y1);
|
|
|
|
painter.drawPath(path);
|
|
|
|
}
|
2022-08-17 05:05:04 +08:00
|
|
|
child1->draw(painter, x+xwidth/2.0+(maxWidth-size1.width)/2.0, y, ev1);
|
|
|
|
child2->draw(painter, x+xwidth/2.0+(maxWidth-size2.width)/2.0, ytop, ev2);
|
2022-06-09 17:32:57 +08:00
|
|
|
deltaWidth=xwidth;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-19 18:16:00 +08:00
|
|
|
if (fracmode==JKQTMathTextFracNode::MTFMstfrac || fracmode==JKQTMathTextFracNode::MTFMsfrac) return x+size1.width+size2.width+deltaWidth;
|
2022-06-09 05:52:22 +08:00
|
|
|
else return x+maxWidth+deltaWidth;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
bool JKQTMathTextFracNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*currentEv*/, JKQTMathTextEnvironment /*defaultEv*/) const {
|
2022-06-08 21:38:26 +08:00
|
|
|
bool ok=false;
|
|
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2022-06-10 02:32:16 +08:00
|
|
|
JKQTMathTextFracNode::FracType JKQTMathTextFracNode::getMode() const {
|
2022-06-08 21:38:26 +08:00
|
|
|
return this->mode;
|
|
|
|
}
|