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/jkqtmathtextinstructionnode.h"
|
|
|
|
#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-09 05:15:42 +08:00
|
|
|
JKQTMathTextInstruction1Node::JKQTMathTextInstruction1Node(JKQTMathText* _parent, const QString& _instructionName, JKQTMathTextNode* child, const QStringList& _parameters):
|
|
|
|
JKQTMathTextSingleChildNode(child, _parent),
|
|
|
|
instructionName(_instructionName),
|
|
|
|
parameters(_parameters)
|
2022-06-08 21:38:26 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextInstruction1Node::~JKQTMathTextInstruction1Node() {
|
|
|
|
}
|
|
|
|
|
2022-07-09 05:15:42 +08:00
|
|
|
const QString& JKQTMathTextInstruction1Node::getInstructionName() const {
|
|
|
|
return this->instructionName;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QStringList &JKQTMathTextInstruction1Node::getParameters() const {
|
|
|
|
return this->parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-25 05:22:54 +08:00
|
|
|
|
|
|
|
JKQTMathTextSimpleInstructionNode::JKQTMathTextSimpleInstructionNode(JKQTMathText *_parent, const QString &_name, const QStringList &_parameters):
|
|
|
|
JKQTMathTextNode(_parent),
|
|
|
|
instructionName(_name),
|
|
|
|
parameters(_parameters)
|
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextSimpleInstructionNode::~JKQTMathTextSimpleInstructionNode()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QString JKQTMathTextSimpleInstructionNode::getTypeName() const
|
|
|
|
{
|
|
|
|
return QLatin1String("JKQTMathTextSimpleInstructionNode(")+instructionName+")";
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
double JKQTMathTextSimpleInstructionNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
2022-07-25 05:22:54 +08:00
|
|
|
{
|
|
|
|
doDrawBoxes(painter, x, y, currentEv);
|
|
|
|
fillInstructions();
|
|
|
|
QFont f=currentEv.getFont(parentMathText);
|
|
|
|
f.setStyleStrategy(QFont::PreferDefault);
|
|
|
|
const QFontMetricsF fm(f);
|
|
|
|
const QString txt=executeInstruction();
|
|
|
|
const QRectF bb=fm.boundingRect(txt);
|
2022-08-19 18:16:00 +08:00
|
|
|
painter.setPen(currentEv.color);
|
2022-07-25 05:22:54 +08:00
|
|
|
painter.setFont(f);
|
|
|
|
painter.drawText(x,y,txt);
|
|
|
|
return x+bb.width();
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
bool JKQTMathTextSimpleInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const
|
2022-07-25 05:22:54 +08:00
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
const QString txt=executeInstruction();
|
|
|
|
html+=txt;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString &JKQTMathTextSimpleInstructionNode::getInstructionName() const
|
|
|
|
{
|
|
|
|
return instructionName;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QStringList &JKQTMathTextSimpleInstructionNode::getParameters() const
|
|
|
|
{
|
|
|
|
return parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JKQTMathTextSimpleInstructionNode::supportsInstructionName(const QString &instructionName)
|
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
return instructions.contains(instructionName);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t JKQTMathTextSimpleInstructionNode::countParametersOfInstruction(const QString &instructionName)
|
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize JKQTMathTextSimpleInstructionNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
|
2022-07-25 05:22:54 +08:00
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
QFont f=currentEv.getFont(parentMathText);
|
|
|
|
f.setStyleStrategy(QFont::PreferDefault);
|
|
|
|
const QFontMetricsF fm(f);
|
|
|
|
const QString txt=executeInstruction();
|
|
|
|
const QRectF bb=fm.boundingRect(txt);
|
2022-08-17 05:05:04 +08:00
|
|
|
JKQTMathTextNodeSize s;
|
|
|
|
s.width=bb.width();
|
|
|
|
s.baselineHeight=-bb.y();
|
|
|
|
s.overallHeight=bb.height();
|
|
|
|
s.strikeoutPos=fm.strikeOutPos();
|
|
|
|
return s;
|
2022-07-25 05:22:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
QHash<QString, JKQTMathTextSimpleInstructionNode::InstructionProperties> JKQTMathTextSimpleInstructionNode::instructions;
|
|
|
|
|
|
|
|
void JKQTMathTextSimpleInstructionNode::fillInstructions()
|
|
|
|
{
|
2023-06-30 19:52:17 +08:00
|
|
|
static std::mutex sMutex;
|
|
|
|
std::lock_guard<std::mutex> lock(sMutex);
|
|
|
|
if (instructions.size()>0) return;
|
2022-07-25 05:22:54 +08:00
|
|
|
{
|
|
|
|
InstructionProperties i([](const QStringList& parameters) -> QString {
|
|
|
|
bool ok=false;
|
2022-07-26 05:29:32 +08:00
|
|
|
qlonglong code=parameters.value(0, "0").toLongLong(&ok, 16);
|
2022-07-25 05:22:54 +08:00
|
|
|
ok=ok&&(code>=0);
|
2022-07-27 04:27:16 +08:00
|
|
|
if (ok&&(code>=0)&&(code<=0xFFFFFFFF)) return QString::fromStdString(jkqtp_UnicodeToUTF8(static_cast<uint32_t>(code)));
|
|
|
|
else return QString();
|
2022-07-25 05:22:54 +08:00
|
|
|
}, 1);
|
|
|
|
instructions["unicode"]= i;
|
2022-07-27 04:27:16 +08:00
|
|
|
instructions["usym"]= i;
|
2022-07-25 05:22:54 +08:00
|
|
|
}
|
2022-07-26 05:29:32 +08:00
|
|
|
{
|
|
|
|
InstructionProperties i([](const QStringList& parameters) -> QString {
|
|
|
|
bool ok=false;
|
|
|
|
qlonglong code=parameters.value(0, "0").toLongLong(&ok, 16);
|
|
|
|
ok=ok&&(code>=0);
|
|
|
|
if (ok) {
|
|
|
|
QByteArray bytes;
|
|
|
|
while (code!=0) {
|
|
|
|
bytes.prepend(static_cast<char>(code&0xFF));
|
|
|
|
code=code>>8;
|
|
|
|
}
|
|
|
|
return QString::fromUtf8(bytes);
|
|
|
|
}
|
|
|
|
return QChar(0);
|
|
|
|
}, 1);
|
|
|
|
instructions["utfeight"]= i;
|
|
|
|
}
|
2022-07-25 05:22:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
QString JKQTMathTextSimpleInstructionNode::executeInstruction() const
|
|
|
|
{
|
|
|
|
fillInstructions();
|
|
|
|
return instructions.value(getInstructionName(), InstructionProperties()).evaluator(getParameters());
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextSimpleInstructionNode::InstructionProperties::InstructionProperties():
|
|
|
|
NParams(0),
|
|
|
|
evaluator([](const QStringList&) { return QString(); })
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
JKQTMathTextSimpleInstructionNode::InstructionProperties::InstructionProperties(const EvaluateInstructionFunctor &_evaluator, size_t _NParams):
|
|
|
|
NParams(_NParams),
|
|
|
|
evaluator(_evaluator)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|