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/jkqtmathtextbracenode.h"
|
|
|
|
#include "jkqtmathtext/jkqtmathtexttools.h"
|
|
|
|
#include "jkqtmathtext/jkqtmathtext.h"
|
|
|
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
|
|
|
#include "jkqtcommon/jkqtpstringtools.h"
|
2024-01-09 00:16:31 +08:00
|
|
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
2022-06-08 21:38:26 +08:00
|
|
|
#include <cmath>
|
|
|
|
#include <QFontMetricsF>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QFontDatabase>
|
|
|
|
#include <QFontInfo>
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QFont>
|
|
|
|
#include <QPainterPath>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-06-19 21:11:06 +08:00
|
|
|
JKQTMathTextBraceNode::JKQTMathTextBraceNode(JKQTMathText* _parent, JKQTMathTextBraceType openbrace, JKQTMathTextBraceType closebrace, JKQTMathTextNode* child):
|
2022-06-09 05:52:22 +08:00
|
|
|
JKQTMathTextSingleChildNode(child, _parent)
|
2022-06-08 21:38:26 +08:00
|
|
|
{
|
|
|
|
this->openbrace=openbrace;
|
|
|
|
this->closebrace=closebrace;
|
|
|
|
}
|
|
|
|
|
2022-06-09 05:52:22 +08:00
|
|
|
|
2022-06-08 21:38:26 +08:00
|
|
|
JKQTMathTextBraceNode::~JKQTMathTextBraceNode() {
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize JKQTMathTextBraceNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
|
|
|
|
return getSizeInternalAndBrace(painter, currentEv);
|
2022-06-09 20:30:15 +08:00
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextBraceNode::NodeSize JKQTMathTextBraceNode::getSizeInternalAndBrace(QPainter &painter, JKQTMathTextEnvironment currentEv) const
|
2022-06-09 20:30:15 +08:00
|
|
|
{
|
2022-08-17 05:05:04 +08:00
|
|
|
NodeSize s;
|
|
|
|
const NodeSize childSize=getChild()->getSize(painter, currentEv);
|
2024-01-09 00:16:31 +08:00
|
|
|
const QFont f=currentEv.getFont(parentMathText);
|
|
|
|
const double minChildHeight=JKQTMathTextGetTightBoundingRect(f, "l", painter.device()).height();
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-14 03:56:09 +08:00
|
|
|
double cAscentAboveStrike=0;
|
|
|
|
double cDescentBelowStrike=0;
|
2022-08-17 05:05:04 +08:00
|
|
|
cAscentAboveStrike=qMax(minChildHeight-childSize.strikeoutPos, childSize.baselineHeight-childSize.strikeoutPos);
|
|
|
|
cDescentBelowStrike=qMax(childSize.strikeoutPos, childSize.getDescent()+childSize.strikeoutPos);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-09 20:30:15 +08:00
|
|
|
//qDebug()<<"getSizeInternalAndBrace(): showOpeningBrace="<<showOpeningBrace<<", openbrace="<<openbrace<<", showClosingBrace="<<showClosingBrace<<", closebrace="<<closebrace;
|
|
|
|
//qDebug()<<"getSizeInternalAndBrace(): child: baselineHeight="<<baselineHeight<<", strikeoutPos="<<strikeoutPos<<", overallHeight="<<overallHeight;
|
|
|
|
//qDebug()<<"getSizeInternalAndBrace(): child: cAscentAboveStrike="<<cAscentAboveStrike<<", cDescentBelowStrike="<<cDescentBelowStrike;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-09 20:30:15 +08:00
|
|
|
const double heightAboveBelowStrike=qMax(cAscentAboveStrike, cDescentBelowStrike);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
s.width=childSize.width;
|
|
|
|
s.strikeoutPos=childSize.strikeoutPos;
|
|
|
|
s.baselineHeight=childSize.strikeoutPos+heightAboveBelowStrike*parentMathText->getBraceFactor();
|
|
|
|
s.overallHeight=2.0*heightAboveBelowStrike*parentMathText->getBraceFactor(); //fm.height();
|
2022-06-09 20:30:15 +08:00
|
|
|
|
|
|
|
//qDebug()<<"getSizeInternalAndBrace(): heightAboveBelowStrike="<<heightAboveBelowStrike<<", baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight;
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
calcBraceSizes(s, painter, currentEv, childSize);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
if (openbrace!=MTBTNone && openbrace!=MTBTAny) s.width+=s.openBraceWidth;
|
|
|
|
if (closebrace!=MTBTNone && closebrace!=MTBTAny) s.width+=s.closeBraceWidth;
|
|
|
|
return s;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
2024-01-09 00:16:31 +08:00
|
|
|
#ifdef JKQTBP_AUTOTIMER
|
|
|
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextBraceNode[]::draw()"));
|
|
|
|
#endif
|
2022-06-08 21:38:26 +08:00
|
|
|
//std::cout<<"drawing brace-node: '"<<openbrace.toStdString()<<"' ... '"<<closebrace.toStdString()<<"'\n";
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
const NodeSize nodesize=getSizeInternalAndBrace(painter, currentEv);
|
|
|
|
doDrawBoxes(painter, x, y, nodesize);
|
2024-01-09 00:16:31 +08:00
|
|
|
const QFont f=currentEv.getFont(parentMathText);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2024-01-09 00:16:31 +08:00
|
|
|
const double lw=JKQTMathTextGetFontLineWidth(f, painter.device());
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-09 20:30:15 +08:00
|
|
|
double xnew=x;
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-09 05:52:22 +08:00
|
|
|
const QPen pold=painter.pen();
|
2022-06-08 21:38:26 +08:00
|
|
|
QPen p=pold;
|
|
|
|
p.setWidthF(lw);
|
|
|
|
p.setColor(currentEv.color);
|
2022-06-27 05:42:06 +08:00
|
|
|
p.setCapStyle(Qt::FlatCap);
|
|
|
|
p.setJoinStyle(Qt::MiterJoin);
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.setPen(p);
|
2022-08-14 03:56:09 +08:00
|
|
|
const double paren_fraction=0.75;
|
2022-06-27 05:42:06 +08:00
|
|
|
const double absnorm_linewidth_factor=0.75;
|
|
|
|
const double paren_topwidth=lw*0.75;
|
2022-08-14 03:56:09 +08:00
|
|
|
const double paren_centerwidth=lw*1.75;
|
|
|
|
const double angle_centerwidth=lw*1.55;
|
2022-06-19 21:11:06 +08:00
|
|
|
{
|
|
|
|
bool showOpeningBrace=true;
|
2023-07-01 21:57:57 +08:00
|
|
|
const double xbrace1=xnew+lw*2.0;
|
|
|
|
const double xbrace2=xnew+qMin(paren_fraction*nodesize.openBraceWidth, nodesize.openBraceWidth-lw);
|
2022-08-17 05:05:04 +08:00
|
|
|
const double xbraceC=xnew+nodesize.openBraceWidth/2.0;
|
2022-06-10 03:37:06 +08:00
|
|
|
if (openbrace==MTBTParenthesis) {
|
2022-06-09 20:30:15 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-06-27 05:42:06 +08:00
|
|
|
const QPointF pb1(xbrace2-paren_topwidth/2.0, y1);
|
|
|
|
const QPointF pbc1(xbrace1-paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
|
|
|
|
const QPointF ptc1(xbrace1-paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
|
|
|
|
const QPointF pt1(xbrace2-paren_topwidth/2.0, y2);
|
|
|
|
const QPointF pt2(xbrace2+paren_topwidth/2.0, y2);
|
|
|
|
const QPointF ptc2(xbrace1+paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
|
|
|
|
const QPointF pbc2(xbrace1+paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
|
|
|
|
const QPointF pb2(xbrace2+paren_topwidth/2.0, y1);
|
|
|
|
path.moveTo(pb1);
|
|
|
|
path.cubicTo(pbc1, ptc1, pt1);
|
|
|
|
path.lineTo(pt2);
|
|
|
|
path.cubicTo(ptc2, pbc2, pb2);
|
|
|
|
path.closeSubpath();
|
2022-08-14 03:56:09 +08:00
|
|
|
painter.fillPath(path, QBrush(currentEv.color, Qt::SolidPattern));
|
2022-06-28 03:09:22 +08:00
|
|
|
/*painter.setPen("blue");
|
2022-06-27 05:42:06 +08:00
|
|
|
painter.drawLine(pb1,pbc1);
|
|
|
|
painter.drawLine(pt1,ptc1);
|
|
|
|
painter.drawLine(pb2,pbc2);
|
2022-06-28 03:09:22 +08:00
|
|
|
painter.drawLine(pt2,ptc2);*/
|
|
|
|
} else if (openbrace==MTBTAngleBracket) {
|
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-06-28 03:09:22 +08:00
|
|
|
const double yc=(y1+y2)/2.0;
|
|
|
|
const QPointF pb1(xbrace2-paren_topwidth/2.0, y1);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QPointF pc1(xbrace1-angle_centerwidth/2.0, yc);
|
2022-06-28 03:09:22 +08:00
|
|
|
const QPointF pt1(xbrace2-paren_topwidth/2.0, y2);
|
|
|
|
const QPointF pt2(xbrace2+paren_topwidth/2.0, y2);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QPointF pc2(xbrace1+angle_centerwidth/2.0, yc);
|
2022-06-28 03:09:22 +08:00
|
|
|
const QPointF pb2(xbrace2+paren_topwidth/2.0, y1);
|
|
|
|
path.moveTo(pb1);
|
|
|
|
path.lineTo(pc1);
|
|
|
|
path.lineTo(pt1);
|
|
|
|
path.lineTo(pt2);
|
|
|
|
path.lineTo(pc2);
|
|
|
|
path.lineTo(pb2);
|
|
|
|
path.closeSubpath();
|
2022-08-14 03:56:09 +08:00
|
|
|
painter.fillPath(path, QBrush(currentEv.color, Qt::SolidPattern));
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (openbrace==MTBTSquareBracket) {
|
2022-06-09 20:30:15 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight)-lw/2.0;
|
|
|
|
const double y2=y-nodesize.baselineHeight+lw/2.0;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace2, y1);
|
2022-06-09 20:30:15 +08:00
|
|
|
path.lineTo(xbrace1, y1);
|
|
|
|
path.lineTo(xbrace1, y2);
|
2022-08-14 03:56:09 +08:00
|
|
|
path.lineTo(xbrace2, y2);
|
2022-06-09 20:30:15 +08:00
|
|
|
painter.drawPath(path);
|
2022-06-27 03:17:42 +08:00
|
|
|
} else if (openbrace==MTBTTopCorner) {
|
|
|
|
QPainterPath path;
|
2022-08-14 03:56:09 +08:00
|
|
|
const double dx=fabs(xbrace2-xbrace1);
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y-nodesize.baselineHeight+lw/2.0;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace2, y1);
|
2022-06-27 03:17:42 +08:00
|
|
|
path.lineTo(xbrace1, y1);
|
|
|
|
path.lineTo(xbrace1, y1+dx);
|
|
|
|
painter.drawPath(path);
|
|
|
|
} else if (openbrace==MTBTBottomCorner) {
|
|
|
|
QPainterPath path;
|
2022-08-14 03:56:09 +08:00
|
|
|
const double dx=fabs(xbrace2-xbrace1);
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight)-lw/2.0;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace2, y1);
|
2022-06-27 03:17:42 +08:00
|
|
|
path.lineTo(xbrace1, y1);
|
|
|
|
path.lineTo(xbrace1, y1-dx);
|
|
|
|
painter.drawPath(path);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (openbrace==MTBTCurlyBracket) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodesize.overallHeight, nodesize.openBraceWidth*paren_fraction, p.widthF());
|
2022-06-09 20:30:15 +08:00
|
|
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
2022-08-17 05:05:04 +08:00
|
|
|
painter.translate(xbraceC, y-nodesize.baselineHeight+nodesize.overallHeight/2.0);
|
2022-06-09 20:30:15 +08:00
|
|
|
painter.rotate(90);
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(0.0001);
|
2022-08-14 03:56:09 +08:00
|
|
|
painter.fillPath(path, QBrush(currentEv.color));
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (openbrace==MTBTFloorBracket) {
|
2022-06-09 20:30:15 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight)-lw/2.0;
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace2, y1);
|
2022-06-09 20:30:15 +08:00
|
|
|
path.lineTo(xbrace1, y1);
|
|
|
|
path.lineTo(xbrace1, y2);
|
|
|
|
painter.drawPath(path);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (openbrace==MTBTCeilBracket) {
|
2022-06-09 20:30:15 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight+lw/2.0;
|
2022-06-09 20:30:15 +08:00
|
|
|
path.moveTo(xbrace1, y1);
|
|
|
|
path.lineTo(xbrace1, y2);
|
2022-08-14 03:56:09 +08:00
|
|
|
path.lineTo(xbrace2, y2);
|
2022-06-09 20:30:15 +08:00
|
|
|
painter.drawPath(path);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (openbrace==MTBTSingleLine) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-08-14 03:56:09 +08:00
|
|
|
const QLineF l(xbraceC, y1, xbraceC, y2);
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
|
|
|
|
painter.setPen(plocal);
|
2022-06-09 20:30:15 +08:00
|
|
|
if (l.length()>0) painter.drawLine(l);
|
2022-06-27 05:42:06 +08:00
|
|
|
painter.setPen(p);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (openbrace==MTBTDoubleLine) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
|
|
|
|
painter.setPen(plocal);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QLineF l(xbraceC-lw, y1, xbraceC-lw, y2);
|
2022-06-09 20:30:15 +08:00
|
|
|
if (l.length()>0) painter.drawLine(l);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QLineF l2(xbraceC+lw, y1, xbraceC+lw, y2);
|
2022-06-09 20:30:15 +08:00
|
|
|
if (l2.length()>0) painter.drawLine(l2);
|
2022-06-27 05:42:06 +08:00
|
|
|
painter.setPen(p);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else {
|
|
|
|
showOpeningBrace=false;
|
|
|
|
}
|
|
|
|
if (showOpeningBrace) {
|
2022-08-17 05:05:04 +08:00
|
|
|
xnew=xnew+nodesize.openBraceWidth;
|
2022-06-09 20:30:15 +08:00
|
|
|
}
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
painter.setPen(pold);
|
|
|
|
|
2022-06-20 04:36:38 +08:00
|
|
|
xnew= getChild()->draw(painter, xnew, y, currentEv);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-19 21:11:06 +08:00
|
|
|
{
|
|
|
|
bool showClosingBrace=true;
|
2023-07-01 21:57:57 +08:00
|
|
|
const double xbrace1=qMax(xnew+nodesize.closeBraceWidth-paren_fraction*nodesize.closeBraceWidth, xnew+lw);
|
|
|
|
const double xbrace2=xnew+nodesize.closeBraceWidth-lw*2.0;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double xbraceC=xnew+nodesize.closeBraceWidth/2.0;
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.setPen(p);
|
2022-06-19 21:11:06 +08:00
|
|
|
if (closebrace==MTBTParenthesis) {
|
2022-06-08 21:38:26 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-06-27 05:42:06 +08:00
|
|
|
const QPointF pb1(xbrace1-paren_topwidth/2.0, y1);
|
|
|
|
const QPointF pbc1(xbrace2-paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
|
|
|
|
const QPointF ptc1(xbrace2-paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
|
|
|
|
const QPointF pt1(xbrace1-paren_topwidth/2.0, y2);
|
|
|
|
const QPointF pt2(xbrace1+paren_topwidth/2.0, y2);
|
|
|
|
const QPointF ptc2(xbrace2+paren_centerwidth/2.0, (y1+y2)/2.0-fabs(y1-y2)/6.0);
|
|
|
|
const QPointF pbc2(xbrace2+paren_centerwidth/2.0, (y1+y2)/2.0+fabs(y1-y2)/6.0);
|
|
|
|
const QPointF pb2(xbrace1+paren_topwidth/2.0, y1);
|
|
|
|
path.moveTo(pb1);
|
|
|
|
path.cubicTo(pbc1, ptc1, pt1);
|
|
|
|
path.lineTo(pt2);
|
|
|
|
path.cubicTo(ptc2, pbc2, pb2);
|
|
|
|
path.closeSubpath();
|
2022-08-14 03:56:09 +08:00
|
|
|
painter.fillPath(path, QBrush(currentEv.color, Qt::SolidPattern));
|
2022-06-27 05:42:06 +08:00
|
|
|
/*painter.setPen("blue");
|
|
|
|
painter.drawLine(pb1,pbc1);
|
|
|
|
painter.drawLine(pt1,ptc1);
|
|
|
|
painter.drawLine(pb2,pbc2);
|
|
|
|
painter.drawLine(pt2,ptc2);*/
|
2022-06-28 03:09:22 +08:00
|
|
|
} else if (closebrace==MTBTAngleBracket) {
|
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-06-28 03:09:22 +08:00
|
|
|
const double yc=(y1+y2)/2.0;
|
|
|
|
const QPointF pb1(xbrace1-paren_topwidth/2.0, y1);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QPointF pc1(xbrace2-angle_centerwidth/2.0, yc);
|
2022-06-28 03:09:22 +08:00
|
|
|
const QPointF pt1(xbrace1-paren_topwidth/2.0, y2);
|
|
|
|
const QPointF pt2(xbrace1+paren_topwidth/2.0, y2);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QPointF pc2(xbrace2+angle_centerwidth/2.0, yc);
|
2022-06-28 03:09:22 +08:00
|
|
|
const QPointF pb2(xbrace1+paren_topwidth/2.0, y1);
|
|
|
|
path.moveTo(pb1);
|
|
|
|
path.lineTo(pc1);
|
|
|
|
path.lineTo(pt1);
|
|
|
|
path.lineTo(pt2);
|
|
|
|
path.lineTo(pc2);
|
|
|
|
path.lineTo(pb2);
|
|
|
|
path.closeSubpath();
|
2022-08-14 03:56:09 +08:00
|
|
|
painter.fillPath(path, QBrush(currentEv.color, Qt::SolidPattern));
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (closebrace==MTBTSquareBracket) {
|
2022-06-08 21:38:26 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight)-lw/2.0;
|
|
|
|
const double y2=y-nodesize.baselineHeight+lw/2.0;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace1, y1);
|
2022-06-09 20:30:15 +08:00
|
|
|
path.lineTo(xbrace2, y1);
|
|
|
|
path.lineTo(xbrace2, y2);
|
2022-08-14 03:56:09 +08:00
|
|
|
path.lineTo(xbrace1, y2);
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.drawPath(path);
|
2022-06-27 03:17:42 +08:00
|
|
|
} else if (closebrace==MTBTBottomCorner) {
|
|
|
|
QPainterPath path;
|
2022-08-14 03:56:09 +08:00
|
|
|
const double dx=fabs(xbrace1-xbrace2);
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight)-lw/2.0;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace1, y1);
|
2022-06-27 03:17:42 +08:00
|
|
|
path.lineTo(xbrace2, y1);
|
|
|
|
path.lineTo(xbrace2, y1-dx);
|
|
|
|
painter.drawPath(path);
|
|
|
|
} else if (closebrace==MTBTTopCorner) {
|
|
|
|
QPainterPath path;
|
2022-08-14 03:56:09 +08:00
|
|
|
const double dx=fabs(xbrace1-xbrace2);
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y-nodesize.baselineHeight+lw/2.0;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace1, y1);
|
2022-06-27 03:17:42 +08:00
|
|
|
path.lineTo(xbrace2, y1);
|
|
|
|
path.lineTo(xbrace2, y1+dx);
|
|
|
|
painter.drawPath(path);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (closebrace==MTBTCurlyBracket) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodesize.overallHeight, nodesize.closeBraceWidth*paren_fraction, p.widthF());
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
2022-08-17 05:05:04 +08:00
|
|
|
painter.translate(xbraceC, y-nodesize.baselineHeight+nodesize.overallHeight/2.0);
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.rotate(270);
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(0.0001);
|
2022-08-14 03:56:09 +08:00
|
|
|
painter.fillPath(path, QBrush(currentEv.color));
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (closebrace==MTBTFloorBracket) {
|
2022-06-08 21:38:26 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight)-lw/2.0;
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-08-14 03:56:09 +08:00
|
|
|
path.moveTo(xbrace1, y1);
|
2022-06-09 20:30:15 +08:00
|
|
|
path.lineTo(xbrace2, y1);
|
|
|
|
path.lineTo(xbrace2, y2);
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.drawPath(path);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (closebrace==MTBTCeilBracket) {
|
2022-06-08 21:38:26 +08:00
|
|
|
QPainterPath path;
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight+lw/2.0;
|
2022-06-09 20:30:15 +08:00
|
|
|
path.moveTo(xbrace2, y1);
|
|
|
|
path.lineTo(xbrace2, y2);
|
2022-08-14 03:56:09 +08:00
|
|
|
path.lineTo(xbrace1, y2);
|
2022-06-08 21:38:26 +08:00
|
|
|
painter.drawPath(path);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (closebrace==MTBTSingleLine) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-08-14 03:56:09 +08:00
|
|
|
const QLineF l(xbraceC, y1, xbraceC, y2);
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
|
|
|
|
painter.setPen(plocal);
|
2022-06-08 21:38:26 +08:00
|
|
|
if (l.length()>0) painter.drawLine(l);
|
2022-06-27 05:42:06 +08:00
|
|
|
painter.setPen(p);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else if (closebrace==MTBTDoubleLine) {
|
2022-08-17 05:05:04 +08:00
|
|
|
const double y1=y+(nodesize.overallHeight-nodesize.baselineHeight);
|
|
|
|
const double y2=y-nodesize.baselineHeight;
|
2022-08-14 03:56:09 +08:00
|
|
|
const QLineF l(xbraceC-lw, y1, xbraceC-lw, y2);
|
2022-06-27 05:42:06 +08:00
|
|
|
QPen plocal=p;
|
|
|
|
plocal.setWidthF(plocal.widthF()*absnorm_linewidth_factor);
|
|
|
|
painter.setPen(plocal);
|
2022-06-08 21:38:26 +08:00
|
|
|
if (l.length()>0) painter.drawLine(l);
|
2022-08-14 03:56:09 +08:00
|
|
|
const QLineF l2(xbraceC+lw, y1, xbraceC+lw, y2);
|
2022-06-09 20:30:15 +08:00
|
|
|
if (l2.length()>0) painter.drawLine(l2);
|
2022-06-27 05:42:06 +08:00
|
|
|
painter.setPen(p);
|
2022-06-19 21:11:06 +08:00
|
|
|
} else {
|
|
|
|
showClosingBrace=false;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
painter.setPen(pold);
|
2022-06-19 21:11:06 +08:00
|
|
|
if (showClosingBrace) {
|
2022-08-17 05:05:04 +08:00
|
|
|
xnew=xnew+nodesize.closeBraceWidth;
|
2022-06-19 21:11:06 +08:00
|
|
|
}
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-06-09 20:30:15 +08:00
|
|
|
return xnew;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
bool JKQTMathTextBraceNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
|
2022-06-10 03:37:06 +08:00
|
|
|
QString ob;
|
|
|
|
QString cb;
|
2022-06-19 21:11:06 +08:00
|
|
|
if (openbrace==MTBTAngleBracket) ob="⟨";
|
|
|
|
else if (openbrace==MTBTFloorBracket) ob="⌊";
|
|
|
|
else if (openbrace==MTBTCeilBracket) ob="⌈";
|
|
|
|
else if (openbrace==MTBTParenthesis) ob="(";
|
|
|
|
else if (openbrace==MTBTSquareBracket) ob="[";
|
|
|
|
else if (openbrace==MTBTCurlyBracket) ob="{";
|
|
|
|
else if (openbrace==MTBTSingleLine) ob="|";
|
|
|
|
else if (openbrace==MTBTDoubleLine) ob="||";
|
2022-06-27 03:17:42 +08:00
|
|
|
else if (openbrace==MTBTTopCorner) ob="⌜";
|
|
|
|
else if (openbrace==MTBTBottomCorner) ob="⌞";
|
2022-06-19 21:11:06 +08:00
|
|
|
if (closebrace==MTBTAngleBracket) cb="⟩";
|
|
|
|
else if (closebrace==MTBTFloorBracket) cb="⌋";
|
|
|
|
else if (closebrace==MTBTCeilBracket) cb="⌉";
|
|
|
|
else if (closebrace==MTBTParenthesis) cb=")";
|
|
|
|
else if (closebrace==MTBTSquareBracket) cb="]";
|
|
|
|
else if (closebrace==MTBTCurlyBracket) cb="}";
|
|
|
|
else if (closebrace==MTBTSingleLine) cb="|";
|
|
|
|
else if (closebrace==MTBTDoubleLine) cb="||";
|
2022-06-27 03:17:42 +08:00
|
|
|
else if (closebrace==MTBTTopCorner) ob="⌝";
|
|
|
|
else if (closebrace==MTBTBottomCorner) ob="⌟";
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
html=html+ob;
|
|
|
|
|
2022-06-20 04:36:38 +08:00
|
|
|
bool ok=getChild()->toHtml(html, currentEv, defaultEv);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
|
|
|
html=html+cb;
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2022-06-09 05:52:22 +08:00
|
|
|
QString JKQTMathTextBraceNode::getTypeName() const
|
2022-06-08 21:38:26 +08:00
|
|
|
{
|
2022-06-19 21:11:06 +08:00
|
|
|
return QLatin1String("MTbraceNode(")+JKQTMathTextBraceType2String(openbrace)+" "+JKQTMathTextBraceType2String(closebrace)+")";
|
2022-06-09 05:52:22 +08:00
|
|
|
}
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-06-19 21:11:06 +08:00
|
|
|
JKQTMathTextBraceType JKQTMathTextBraceNode::getOpenbrace() const {
|
2022-06-09 05:52:22 +08:00
|
|
|
return this->openbrace;
|
2022-06-08 21:38:26 +08:00
|
|
|
}
|
|
|
|
|
2022-06-19 21:11:06 +08:00
|
|
|
JKQTMathTextBraceType JKQTMathTextBraceNode::getClosebrace() const {
|
2022-06-09 05:52:22 +08:00
|
|
|
return this->closebrace;
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
|
|
|
|
|
|
|
|
JKQTMathTextBraceNode::NodeSize::NodeSize():
|
|
|
|
JKQTMathTextNodeSize(),
|
|
|
|
openBraceWidth(0.0),
|
|
|
|
openBraceHeight(0.0),
|
|
|
|
closeBraceWidth(0.0),
|
|
|
|
closeBraceHeight(0.0)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextBraceNode::NodeSize::NodeSize(const JKQTMathTextNodeSize &other):
|
|
|
|
JKQTMathTextNodeSize(other),
|
|
|
|
openBraceWidth(0.0),
|
|
|
|
openBraceHeight(0.0),
|
|
|
|
closeBraceWidth(0.0),
|
|
|
|
closeBraceHeight(0.0)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextBraceNode::NodeSize &JKQTMathTextBraceNode::NodeSize::operator=(const JKQTMathTextNodeSize &other)
|
|
|
|
{
|
|
|
|
JKQTMathTextNodeSize::operator=(other);
|
|
|
|
openBraceWidth=0.0;
|
|
|
|
openBraceHeight=0.0;
|
|
|
|
closeBraceWidth=0.0;
|
|
|
|
closeBraceHeight=0.0;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextBraceNode::NodeSize &JKQTMathTextBraceNode::NodeSize::operator=(const NodeSize &other)
|
|
|
|
{
|
|
|
|
JKQTMathTextNodeSize::operator=(dynamic_cast<const JKQTMathTextNodeSize&>(other));
|
|
|
|
openBraceWidth=other.openBraceWidth;
|
|
|
|
openBraceHeight=other.openBraceHeight;
|
|
|
|
closeBraceWidth=other.closeBraceWidth;
|
|
|
|
closeBraceHeight=other.closeBraceHeight;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextBraceNode::NodeSize::NodeSize(const NodeSize &other):
|
|
|
|
JKQTMathTextNodeSize(dynamic_cast<const JKQTMathTextNodeSize&>(other)),
|
|
|
|
openBraceWidth(other.openBraceWidth),
|
|
|
|
openBraceHeight(other.openBraceHeight),
|
|
|
|
closeBraceWidth(other.closeBraceWidth),
|
|
|
|
closeBraceHeight(other.closeBraceHeight)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void JKQTMathTextBraceNode::calcBraceSizes(NodeSize& out, QPainter &painter, const JKQTMathTextEnvironment &ev, const JKQTMathTextNodeSize &childSize) const
|
2022-06-09 20:30:15 +08:00
|
|
|
{
|
2024-01-09 00:16:31 +08:00
|
|
|
const QFont f=ev.getFont(parentMathText);
|
|
|
|
const QSizeF openBraceS=calcBraceSize(f, painter.device(), openbrace, childSize);
|
|
|
|
const QSizeF closeBraceS=calcBraceSize(f, painter.device(), closebrace, childSize);
|
2022-08-17 05:05:04 +08:00
|
|
|
out.openBraceWidth=openBraceS.width();
|
|
|
|
out.openBraceHeight=openBraceS.width();
|
|
|
|
out.closeBraceWidth=closeBraceS.width();
|
|
|
|
out.closeBraceHeight=closeBraceS.width();
|
|
|
|
}
|
|
|
|
|
2024-01-09 00:16:31 +08:00
|
|
|
QSizeF JKQTMathTextBraceNode::calcBraceSize(const QFont &f, QPaintDevice *pd, JKQTMathTextBraceType bracetype, const JKQTMathTextNodeSize &childSize) const
|
2022-08-17 05:05:04 +08:00
|
|
|
{
|
|
|
|
double braceWidth=0.0;
|
|
|
|
double braceHeight=0.0;
|
2024-01-09 00:16:31 +08:00
|
|
|
const double lw=JKQTMathTextGetFontLineWidth(f, pd);
|
2022-08-14 03:56:09 +08:00
|
|
|
const double dblline_distance=2.0*lw;
|
2022-08-17 05:05:04 +08:00
|
|
|
braceHeight=childSize.overallHeight*parentMathText->getBraceFactor();
|
|
|
|
braceWidth=lw*5.0;
|
|
|
|
if (bracetype==MTBTCurlyBracket) braceWidth=lw*6.5;
|
|
|
|
if (bracetype==MTBTParenthesis) braceWidth=lw*6.0;
|
|
|
|
if (bracetype==MTBTDoubleLine) braceWidth=dblline_distance+3.0*lw;
|
|
|
|
if (bracetype==MTBTSingleLine) braceWidth=3.0*lw;
|
2023-07-01 21:57:57 +08:00
|
|
|
if (bracetype==MTBTSquareBracket || bracetype==MTBTCeilBracket || bracetype==MTBTFloorBracket) braceWidth=7.0*lw;
|
2022-08-17 05:05:04 +08:00
|
|
|
|
2024-01-09 00:16:31 +08:00
|
|
|
const double overSizeFactor=braceHeight/JKQTMathTextGetFontHeight(f, pd);
|
2022-08-17 05:05:04 +08:00
|
|
|
if (overSizeFactor>1.2) braceWidth=braceWidth*sqrt(overSizeFactor);
|
2022-06-08 21:38:26 +08:00
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
return QSizeF(braceWidth, braceHeight);
|
|
|
|
}
|