mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 10:01:38 +08:00
NEW/REWORKED: extended the set of functions like JKQTMathTextGetTightBoundingRect(): These use an internal, thread-safe cache and capsule calls to QFontMetricsF-instances. This significantly improves speed in (parallelized) plotting.
This commit is contained in:
parent
3fee9609fb
commit
09e07cb12a
@ -97,10 +97,10 @@ This test results in the following numbers (on my AMD Ryzen5 8/16-core laptop):
|
|||||||
<b>VERSION:</b> 5.0.0
|
<b>VERSION:</b> 5.0.0
|
||||||
<b>BUILD MODE:</b> Release
|
<b>BUILD MODE:</b> Release
|
||||||
|
|
||||||
<u><b>SERIAL RESULTS:</b></u><br/>runtime, overall = 1896.0ms<br/>single runtimes = (236.9 +/- 379.1) ms<br/>speedup = 1.00x<br/>threads / available = 1 / 16<br/><br/>
|
<u><b>SERIAL RESULTS:</b></u><br/>runtime, overall = 3399.6ms<br/>single runtimes = (141.6 +/- 366.9) ms<br/>speedup = 1.00x<br/>threads / available = 1 / 16<br/><br/><br/>
|
||||||
|
|
||||||
<u><b>PARALLEL RESULTS:</b></u><br/>
|
<u><b>PARALLEL RESULTS:</b></u><br/>
|
||||||
runtime, overall = 624.7ms<br/>single runtimes = (564.3 +/- 107.7) ms<br/>speedup = 7.23x<br/>threads / available = 8 / 16<br/><br/><b>speedup vs. serial = 3.0x</b>
|
runtime, overall = 526.7ms<br/>single runtimes = (166.4 +/- 9.9) ms<br/>speedup = 7.58x<br/>threads / available = 8 / 16<br/>batch runs = 3<br/><br/><b>speedup vs. serial = 6.5x</b>
|
||||||
|
|
||||||
[comment]:RESULTS_END
|
[comment]:RESULTS_END
|
||||||
|
|
||||||
@ -108,8 +108,9 @@ runtime, overall = 624.7ms<br/>single runtimes = (564.3 +/- 107.7) ms<br/>speedu
|
|||||||
|
|
||||||
From this data you can observe:
|
From this data you can observe:
|
||||||
- The plotting parallelizes nicely, i.e. the speedup ist >7x on a 8-core-machine. This is the speedup calculated as sum of runtimes of each thread, divided by the runtime of all threads in parallel.
|
- The plotting parallelizes nicely, i.e. the speedup ist >7x on a 8-core-machine. This is the speedup calculated as sum of runtimes of each thread, divided by the runtime of all threads in parallel.
|
||||||
- BUT: the speedup of serialized plotting vs. parallel plotting is way smaller: It is only 2-3x. Also the runtime in each thread is about 3x longer than in the serialized example. This can be explained by the (significant) overhead due to shared caches (and therefore synchronization) between the plotters. This may be reworked in future!
|
- BUT: the speedup of serialized plotting vs. parallel plotting is a biz smaller: It is only 6-7x. Also the runtime in each thread is a bit longer than in the serialized example. This can be explained by the overhead due to shared caches (and therefore synchronization) between the plotters (e.g. using JKQTMathTextGetBoundingRect() within JKQTMathText).
|
||||||
- The variance in runtimes in the (initial) serial test-run is larger than in the parallel run. This is due to filling of the internal caches during the first plotting!
|
- The variance in runtimes in the (initial) serial test-run is larger than in the parallel run. This is due to filling of the internal caches during the first plotting!
|
||||||
|
- NOTE: The parallel vs. serial speedup significantly depends on the complexity of the text rendering (i.e. usage of JKQTMathText). Therefore rendinering more complex textxs with more and more complex LaTeX markup, will result in smalle speedups!
|
||||||
.
|
.
|
||||||
|
|
||||||
Finally the application displays the plots:
|
Finally the application displays the plots:
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define NUM_PLOTS 8
|
#define NUM_PLOTS 8
|
||||||
#define NUM_GRAPHS 6
|
#define NUM_GRAPHS 6
|
||||||
#define NUM_DATAPOINTS 1000
|
#define NUM_DATAPOINTS 1000
|
||||||
|
#define NUM_REPEATS 3
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@ -33,11 +34,21 @@ int main(int argc, char* argv[])
|
|||||||
mainWin->setCentralWidget(main=new QWidget(mainWin));
|
mainWin->setCentralWidget(main=new QWidget(mainWin));
|
||||||
|
|
||||||
QString markdownFile="";
|
QString markdownFile="";
|
||||||
|
QString labelTemplate="Plot %1: $f(x)=\\cos\\left(x+\\sfrac{%1\\pi}{8}\\right)$";
|
||||||
|
QByteArray mdMATCH="RESULTS";
|
||||||
for (int i=1; i<argc; i++) {
|
for (int i=1; i<argc; i++) {
|
||||||
if (QString(argv[i]).startsWith("--mdfile=")) {
|
if (QString(argv[i]).startsWith("--mdfile=")) {
|
||||||
markdownFile=QString::fromLatin1(argv[i]).right(QString::fromLatin1(argv[i]).size()-9);
|
markdownFile=QString::fromLatin1(argv[i]).right(QString::fromLatin1(argv[i]).size()-9);
|
||||||
if (markdownFile.startsWith('"')) markdownFile.remove('"');
|
if (markdownFile.startsWith('"')) markdownFile.remove('"');
|
||||||
}
|
}
|
||||||
|
if (QString(argv[i]).startsWith("--complexlabel")) {
|
||||||
|
labelTemplate="Plot %1: $f(x)=\\cos\\left(x+\\sfrac{%1\\pi}{8}\\right)$";
|
||||||
|
mdMATCH="COMPLEXRESULTS";
|
||||||
|
}
|
||||||
|
if (QString(argv[i]).startsWith("--simplelabel")) {
|
||||||
|
labelTemplate="Plot %1: $f(x)=\\cos(x+%1\\pi/8)$";
|
||||||
|
mdMATCH="COMPLEXRESULTS";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -72,40 +83,45 @@ int main(int argc, char* argv[])
|
|||||||
lay_serial->addWidget(pic_serial.last(), 1);
|
lay_serial->addWidget(pic_serial.last(), 1);
|
||||||
lay_parallel->addWidget(pic_parallel.last(), 1);
|
lay_parallel->addWidget(pic_parallel.last(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
QElapsedTimer timer;
|
|
||||||
QList<double> runtimesSerial;
|
|
||||||
timer.start();
|
|
||||||
for (int i=0; i<NUM_PLOTS; i++) {
|
|
||||||
double dur=0;
|
|
||||||
filenamesSerial<<PlottingThread::plotAndSave("serial", i, NUM_GRAPHS, NUM_DATAPOINTS, &dur);
|
|
||||||
runtimesSerial<<dur/1e6;
|
|
||||||
}
|
|
||||||
const double durSerialNano=timer.nsecsElapsed();
|
|
||||||
qDebug()<<"durSerial = "<<durSerialNano/1e6<<"ms";
|
|
||||||
|
|
||||||
QList<double> runtimesParallel;
|
QList<double> runtimesParallel;
|
||||||
QList<QSharedPointer<PlottingThread>> threads;
|
QList<double> runtimesSerial;
|
||||||
for (int i=0; i<NUM_PLOTS; i++) {
|
double durSerialNano=0;
|
||||||
qDebug()<<" creating thread "<<i;
|
double durParallelNano=0;
|
||||||
threads.append(QSharedPointer<PlottingThread>::create("parallel",i, NUM_GRAPHS, NUM_DATAPOINTS, nullptr));
|
for (int run=0; run<NUM_REPEATS; run++) {
|
||||||
}
|
filenamesParallel.clear();
|
||||||
timer.start();
|
|
||||||
for (int i=0; i<NUM_PLOTS; i++) {
|
QElapsedTimer timer;
|
||||||
qDebug()<<" staring thread "<<i;
|
timer.start();
|
||||||
threads[i]->start();
|
for (int i=0; i<NUM_PLOTS; i++) {
|
||||||
}
|
double dur=0;
|
||||||
for (int i=0; i<NUM_PLOTS; i++) {
|
filenamesSerial<<PlottingThread::plotAndSave("serial", i, NUM_GRAPHS, NUM_DATAPOINTS, labelTemplate, &dur);
|
||||||
qDebug()<<" waiting for thread "<<i;
|
runtimesSerial<<dur/1e6;
|
||||||
if (threads[i]->wait()) {
|
}
|
||||||
filenamesParallel<<threads[i]->getFilename();
|
durSerialNano+=timer.nsecsElapsed();
|
||||||
runtimesParallel<<threads[i]->getRuntimeNanosends()/1e6;
|
qDebug()<<"durSerial = "<<durSerialNano/1e6<<"ms";
|
||||||
}
|
|
||||||
}
|
QList<QSharedPointer<PlottingThread>> threads;
|
||||||
const double durParallelNano=timer.nsecsElapsed();
|
for (int i=0; i<NUM_PLOTS; i++) {
|
||||||
qDebug()<<"durParallel = "<<durParallelNano/1e6<<"ms";
|
qDebug()<<" creating thread "<<i;
|
||||||
|
threads.append(QSharedPointer<PlottingThread>::create("parallel",i, NUM_GRAPHS, NUM_DATAPOINTS, labelTemplate, nullptr));
|
||||||
|
}
|
||||||
|
timer.start();
|
||||||
|
for (int i=0; i<NUM_PLOTS; i++) {
|
||||||
|
qDebug()<<" staring thread "<<i;
|
||||||
|
threads[i]->start();
|
||||||
|
}
|
||||||
|
for (int i=0; i<NUM_PLOTS; i++) {
|
||||||
|
qDebug()<<" waiting for thread "<<i;
|
||||||
|
if (threads[i]->wait()) {
|
||||||
|
filenamesParallel<<threads[i]->getFilename();
|
||||||
|
runtimesParallel<<threads[i]->getRuntimeNanosends()/1e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
durParallelNano+=timer.nsecsElapsed();
|
||||||
|
qDebug()<<"durParallel["<<run+1<<"] = "<<durParallelNano/1e6<<"ms";
|
||||||
|
threads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
threads.clear();
|
|
||||||
|
|
||||||
for (int ii=0; ii<NUM_SHOWN_PLOTS; ii++) {
|
for (int ii=0; ii<NUM_SHOWN_PLOTS; ii++) {
|
||||||
int i=ii;
|
int i=ii;
|
||||||
@ -114,8 +130,8 @@ int main(int argc, char* argv[])
|
|||||||
pic_parallel[ii]->setPixmap(QPixmap(filenamesParallel[i], "PNG"));
|
pic_parallel[ii]->setPixmap(QPixmap(filenamesParallel[i], "PNG"));
|
||||||
}
|
}
|
||||||
QString ser_result, par_result;
|
QString ser_result, par_result;
|
||||||
labSerialResult->setText(ser_result=QString("runtime, overall = %1ms<br/>single runtimes = (%2 +/- %3) ms<br/>speedup = %4x<br/>threads / available = %5 / %6<br/><br/> ").arg(durSerialNano/1e6,0,'f',1).arg(jkqtpstatAverage(runtimesSerial.begin(), runtimesSerial.end()),0,'f',1).arg(jkqtpstatStdDev(runtimesSerial.begin(), runtimesSerial.end()),0,'f',1).arg(jkqtpstatSum(runtimesSerial.begin(), runtimesSerial.end())/(durSerialNano/1e6),0,'f',2).arg(1).arg(std::thread::hardware_concurrency()));
|
labSerialResult->setText(ser_result=QString("runtime, overall = %1ms<br/>single runtimes = (%2 +/- %3) ms<br/>speedup = %4x<br/>threads / available = %5 / %6<br/><br/><br/> ").arg(durSerialNano/1e6,0,'f',1).arg(jkqtpstatAverage(runtimesSerial.begin(), runtimesSerial.end()),0,'f',1).arg(jkqtpstatStdDev(runtimesSerial.begin(), runtimesSerial.end()),0,'f',1).arg(jkqtpstatSum(runtimesSerial.begin(), runtimesSerial.end())/(durSerialNano/1e6),0,'f',2).arg(1).arg(std::thread::hardware_concurrency()));
|
||||||
labParallelResult->setText(par_result=QString("runtime, overall = %1ms<br/>single runtimes = (%2 +/- %3) ms<br/>speedup = %4x<br/>threads / available = %5 / %6<br/><br/><b>speedup vs. serial = %7x</b>").arg(durParallelNano/1e6,0,'f',1).arg(jkqtpstatAverage(runtimesParallel.begin(), runtimesParallel.end()),0,'f',1).arg(jkqtpstatStdDev(runtimesParallel.begin(), runtimesParallel.end()),0,'f',1).arg(jkqtpstatSum(runtimesParallel.begin(), runtimesParallel.end())/(durParallelNano/1e6),0,'f',2).arg(NUM_PLOTS).arg(std::thread::hardware_concurrency()).arg(durSerialNano/durParallelNano,0,'f',1));
|
labParallelResult->setText(par_result=QString("runtime, overall = %1ms<br/>single runtimes = (%2 +/- %3) ms<br/>speedup = %4x<br/>threads / available = %5 / %6<br/>batch runs = %8<br/><br/><b>speedup vs. serial = %7x</b>").arg(durParallelNano/1e6,0,'f',1).arg(jkqtpstatAverage(runtimesParallel.begin(), runtimesParallel.end()),0,'f',1).arg(jkqtpstatStdDev(runtimesParallel.begin(), runtimesParallel.end()),0,'f',1).arg(jkqtpstatSum(runtimesParallel.begin(), runtimesParallel.end())/(durParallelNano/1e6),0,'f',2).arg(NUM_PLOTS).arg(std::thread::hardware_concurrency()).arg(durSerialNano/durParallelNano,0,'f',1).arg(NUM_REPEATS));
|
||||||
mainWin->show();
|
mainWin->show();
|
||||||
|
|
||||||
if (!markdownFile.isEmpty()) {
|
if (!markdownFile.isEmpty()) {
|
||||||
@ -126,11 +142,11 @@ int main(int argc, char* argv[])
|
|||||||
md=f.readAll();
|
md=f.readAll();
|
||||||
qDebug()<<" read "<<md.size()<<" bytes";
|
qDebug()<<" read "<<md.size()<<" bytes";
|
||||||
f.close();
|
f.close();
|
||||||
const auto istart=md.indexOf("[comment]:RESULTS");
|
const auto istart=md.indexOf("[comment]:"+mdMATCH);
|
||||||
const auto iend=md.indexOf("[comment]:RESULTS_END");
|
const auto iend=md.indexOf("[comment]:"+mdMATCH+"_END");
|
||||||
qDebug()<<" istart="<<istart<<", iend="<<iend;
|
qDebug()<<" istart="<<istart<<", iend="<<iend;
|
||||||
if (istart>=0 && iend>istart) {
|
if (istart>=0 && iend>istart) {
|
||||||
const QByteArray newResults="[comment]:RESULTS\n\n<b>VERSION:</b> "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_VERSION)
|
const QByteArray newResults="[comment]:"+mdMATCH+"\n\n<b>VERSION:</b> "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_VERSION)
|
||||||
+"\n<b>BUILD MODE:</b> "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_BUILDTYPE)
|
+"\n<b>BUILD MODE:</b> "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_BUILDTYPE)
|
||||||
+"\n\n<u><b>SERIAL RESULTS:</b></u><br/>"+ser_result.toUtf8()
|
+"\n\n<u><b>SERIAL RESULTS:</b></u><br/>"+ser_result.toUtf8()
|
||||||
+"\n\n<u><b>PARALLEL RESULTS:</b></u><br/>\n"+par_result.toUtf8()+"\n\n";
|
+"\n\n<u><b>PARALLEL RESULTS:</b></u><br/>\n"+par_result.toUtf8()+"\n\n";
|
||||||
|
@ -14,17 +14,18 @@
|
|||||||
class PlottingThread: public QThread {
|
class PlottingThread: public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
inline PlottingThread(const QString& filenamepart, int plotindex, int NUM_GRAPHS, int NUM_DATAPOINTS, QObject* parent):
|
inline PlottingThread(const QString& filenamepart, int plotindex, int NUM_GRAPHS, int NUM_DATAPOINTS, const QString& labeltemplate, QObject* parent):
|
||||||
QThread(parent),
|
QThread(parent),
|
||||||
m_plotindex(plotindex),
|
m_plotindex(plotindex),
|
||||||
m_runtimeNanoseconds(0),
|
m_runtimeNanoseconds(0),
|
||||||
m_filenamepart(filenamepart),
|
m_filenamepart(filenamepart),
|
||||||
m_filename(),
|
m_filename(),
|
||||||
m_NUM_GRAPHS(NUM_GRAPHS),
|
m_NUM_GRAPHS(NUM_GRAPHS),
|
||||||
m_NUM_DATAPOINTS(NUM_DATAPOINTS)
|
m_NUM_DATAPOINTS(NUM_DATAPOINTS),
|
||||||
|
m_labeltemplate(labeltemplate)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline static QString plotAndSave(const QString& filenamepart, int plotIndex, int NUM_GRAPHS, int NUM_DATAPOINTS, double* runtimeNanoseconds=nullptr) {
|
inline static QString plotAndSave(const QString& filenamepart, int plotIndex, int NUM_GRAPHS, int NUM_DATAPOINTS, const QString& labeltemplate, double* runtimeNanoseconds=nullptr) {
|
||||||
QElapsedTimer timer;
|
QElapsedTimer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
const QString filename=QDir(QDir::tempPath()).absoluteFilePath(QString("testimg_%1_%2.png").arg(filenamepart).arg(plotIndex));
|
const QString filename=QDir(QDir::tempPath()).absoluteFilePath(QString("testimg_%1_%2.png").arg(filenamepart).arg(plotIndex));
|
||||||
@ -36,15 +37,15 @@ public:
|
|||||||
JKQTPXYLineGraph* g;
|
JKQTPXYLineGraph* g;
|
||||||
plot.addGraph(g=new JKQTPXYLineGraph(&plot));
|
plot.addGraph(g=new JKQTPXYLineGraph(&plot));
|
||||||
g->setXColumn(colX);
|
g->setXColumn(colX);
|
||||||
g->setYColumn(plot.getDatastore()->addColumnCalculatedFromColumn(colX, [&](double x) { return cos(x+double(i)/8.0*JKQTPSTATISTICS_PI)+rng.generateDouble()*0.2-0.1;}));
|
g->setYColumn(plot.getDatastore()->addColumnCalculatedFromColumn(colX, [&](double x) { return cos(x+double(i+plotIndex)/8.0*JKQTPSTATISTICS_PI)+rng.generateDouble()*0.2-0.1;}));
|
||||||
g->setTitle(QString("Plot %1: $f(x)=\\cos\\leftx+\\frac{%1\\pi}{8}\\right)").arg(i+1));
|
g->setTitle(labeltemplate.arg(i+plotIndex+1));
|
||||||
g->setDrawLine(true);
|
g->setDrawLine(true);
|
||||||
g->setSymbolType(JKQTPNoSymbol);
|
g->setSymbolType(JKQTPNoSymbol);
|
||||||
|
|
||||||
}
|
}
|
||||||
plot.setPlotLabel(QString("Test Plot %1").arg(plotIndex+1));
|
plot.setPlotLabel(QString("Test Plot %1 (%2)").arg(plotIndex+1).arg(filenamepart));
|
||||||
plot.getXAxis()->setAxisLabel("x-axis");
|
plot.getXAxis()->setAxisLabel("x-axis $x$");
|
||||||
plot.getYAxis()->setAxisLabel("y-axis");
|
plot.getYAxis()->setAxisLabel("y-axis $f(x)$");
|
||||||
plot.zoomToFit();
|
plot.zoomToFit();
|
||||||
plot.saveAsPixelImage(filename, false, "PNG");
|
plot.saveAsPixelImage(filename, false, "PNG");
|
||||||
|
|
||||||
@ -59,15 +60,16 @@ public:
|
|||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
inline virtual void run() {
|
inline virtual void run() {
|
||||||
m_filename=plotAndSave(m_filenamepart, m_plotindex, m_NUM_GRAPHS, m_NUM_DATAPOINTS, &m_runtimeNanoseconds);
|
m_filename=plotAndSave(m_filenamepart, m_plotindex, m_NUM_GRAPHS, m_NUM_DATAPOINTS, m_labeltemplate, &m_runtimeNanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_plotindex;
|
int m_plotindex;
|
||||||
double m_runtimeNanoseconds;
|
double m_runtimeNanoseconds;
|
||||||
QString m_filename;
|
QString m_filename;
|
||||||
QString m_filenamepart;
|
const QString m_filenamepart;
|
||||||
const int m_NUM_GRAPHS;
|
const int m_NUM_GRAPHS;
|
||||||
const int m_NUM_DATAPOINTS;
|
const int m_NUM_DATAPOINTS;
|
||||||
|
const QString m_labeltemplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MULTITHREADED_THREAD_H
|
#endif // MULTITHREADED_THREAD_H
|
||||||
|
@ -71,6 +71,14 @@ class JKQTMathTextVerticalListNode; // forward
|
|||||||
- \ref jkqtmathtext_supportedlatex for a description of the supported LaTeX subset
|
- \ref jkqtmathtext_supportedlatex for a description of the supported LaTeX subset
|
||||||
.
|
.
|
||||||
|
|
||||||
|
\section JKQTMathTextUsageThreadSafety Thread-Safety/Re-Entrancy Guarantees
|
||||||
|
All functions in this class are reentrant. Therefore different instances off JKQTMathtext can be used in parallel in different threads.
|
||||||
|
DO NOT however use the same instance from multiple threads, as the functions are not thread-safe!
|
||||||
|
|
||||||
|
Also note that there are certain caches that reuse information (e.g. about fonts) from previous runs, which allow different instances
|
||||||
|
(also over different threads) to profit from each other. On the other hand, this strategy requires a bit of overhead due to synchronization,
|
||||||
|
but usually the speedup outweighs the overhead significantly!
|
||||||
|
|
||||||
|
|
||||||
\section JKQTMathTextUsage Usage
|
\section JKQTMathTextUsage Usage
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtexttools.h"
|
#include "jkqtmathtext/jkqtmathtexttools.h"
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpcachingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#include <QFontInfo>
|
#include <QFontInfo>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
|
#include <QReadWriteLock>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
@ -877,81 +879,239 @@ QPainterPath JKQTMathTextMakeHBracePath(double x, double ybrace, double width, d
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JKQTMathTextTBRData::JKQTMathTextTBRData(const QFont &f, const QString &text, QPaintDevice *pd):
|
|
||||||
fm(f, pd)
|
|
||||||
{
|
|
||||||
this->text=text;
|
|
||||||
this->tbr=this->fm.tightBoundingRect(text);
|
|
||||||
this->f=f;
|
|
||||||
//this->pd=pd;
|
|
||||||
if (pd) {
|
|
||||||
ldpiX=pd->logicalDpiX();
|
|
||||||
ldpiY=pd->logicalDpiY();
|
|
||||||
pdpiX=pd->physicalDpiX();
|
|
||||||
pdpiY=pd->physicalDpiY();
|
|
||||||
} else {
|
|
||||||
ldpiX=0;
|
|
||||||
ldpiY=0;
|
|
||||||
pdpiX=0;
|
|
||||||
pdpiY=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTMathTextTBRData::operator==(const JKQTMathTextTBRData &other) const
|
namespace {
|
||||||
{
|
|
||||||
return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
struct JKQTMathTextCacheKeyBase {
|
||||||
|
inline explicit JKQTMathTextCacheKeyBase(const QFont& f_, QPaintDevice *pd):
|
||||||
JKQTMathTextTBRDataH::JKQTMathTextTBRDataH(const QFont &f, const QString &text, QPaintDevice *pd)
|
f(f_)
|
||||||
{
|
{
|
||||||
this->text=text;
|
if (pd) {
|
||||||
this->f=f;
|
ldpiX=pd->logicalDpiX();
|
||||||
if (pd) {
|
ldpiY=pd->logicalDpiY();
|
||||||
ldpiX=pd->logicalDpiX();
|
pdpiX=pd->physicalDpiX();
|
||||||
ldpiY=pd->logicalDpiY();
|
pdpiY=pd->physicalDpiY();
|
||||||
pdpiX=pd->physicalDpiX();
|
} else {
|
||||||
pdpiY=pd->physicalDpiY();
|
ldpiX=0;
|
||||||
} else {
|
ldpiY=0;
|
||||||
ldpiX=0;
|
pdpiX=0;
|
||||||
ldpiY=0;
|
pdpiY=0;
|
||||||
pdpiX=0;
|
|
||||||
pdpiY=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTMathTextTBRDataH::operator==(const JKQTMathTextTBRDataH &other) const
|
|
||||||
{
|
|
||||||
return ldpiX==other.ldpiX && ldpiY==other.ldpiY && text==other.text && f==other.f;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QRectF JKQTMathTextGetTightBoundingRect(const QFont &fm, const QString &text, QPaintDevice *pd)
|
|
||||||
{
|
|
||||||
thread_local QList<JKQTMathTextTBRData> JKQTMathText_tbrs=QList<JKQTMathTextTBRData>();
|
|
||||||
thread_local QHash<JKQTMathTextTBRDataH, QRectF> JKQTMathText_tbrh=QHash<JKQTMathTextTBRDataH, QRectF>();
|
|
||||||
|
|
||||||
JKQTMathTextTBRDataH dh(fm, text, pd);
|
|
||||||
if (pd) {
|
|
||||||
if (JKQTMathText_tbrh.contains(dh)) return JKQTMathText_tbrh[dh];
|
|
||||||
/*for (int i=0; i<tbrs.size(); i++) {
|
|
||||||
if (tbrs[i].f==fm && tbrs[i].text==text && (tbrs[i].ldpiX==pd->logicalDpiX() && tbrs[i].ldpiY==pd->logicalDpiY() && tbrs[i].pdpiX==pd->physicalDpiX() && tbrs[i].pdpiY==pd->physicalDpiY())) {
|
|
||||||
//qDebug()<<" ### "<<fm<<pd<<tbrs[i].text<<tbrs[i].tbr;
|
|
||||||
return tbrs[i].tbr;
|
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
} else {
|
QFont f;
|
||||||
//qDebug()<<"warning no pd";
|
int ldpiX, ldpiY, pdpiX, pdpiY;
|
||||||
|
|
||||||
|
inline bool operator==(const JKQTMathTextCacheKeyBase& other) const{
|
||||||
|
return ldpiX==other.ldpiX && ldpiY==other.ldpiY && pdpiX==other.pdpiX && pdpiY==other.pdpiY && f==other.f;
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||||
|
inline size_t qHash(const JKQTMathTextCacheKeyBase& data, size_t seed=0) {
|
||||||
|
#else
|
||||||
|
inline uint qHash(const JKQTMathTextCacheKeyBase& data) {
|
||||||
|
const size_t seed=0;
|
||||||
|
#endif
|
||||||
|
return qHash(data.f)+::qHash(data.ldpiX,seed)+::qHash(data.ldpiY)+::qHash(data.pdpiX)+::qHash(data.pdpiY);
|
||||||
}
|
}
|
||||||
JKQTMathTextTBRData d(fm, text, pd);
|
|
||||||
JKQTMathText_tbrs.append(d);
|
struct JKQTMathTextCacheKeyBaseExt: public JKQTMathTextCacheKeyBase {
|
||||||
JKQTMathText_tbrh[dh]=d.tbr;
|
inline explicit JKQTMathTextCacheKeyBaseExt(const QFont& f_, QPaintDevice *pd_):
|
||||||
//qDebug()<<"TBRs lits: "<<tbrs.size();
|
JKQTMathTextCacheKeyBase(f_,pd_), pd(pd_)
|
||||||
//qDebug()<<"+++ "<<fm<<pd<<d.text<<d.tbr;
|
{}
|
||||||
return d.tbr;
|
|
||||||
|
QPaintDevice *pd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class TText=QString>
|
||||||
|
struct JKQTMathTextTBRDataH: public JKQTMathTextCacheKeyBase {
|
||||||
|
inline explicit JKQTMathTextTBRDataH(const QFont& f_, const TText& text_, QPaintDevice *pd):
|
||||||
|
JKQTMathTextCacheKeyBase(f_, pd), text(text_)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
TText text;
|
||||||
|
|
||||||
|
inline bool operator==(const JKQTMathTextTBRDataH& other) const{
|
||||||
|
return JKQTMathTextCacheKeyBase::operator==(other) && text==other.text;
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class TText=QString>
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||||
|
inline size_t qHash(const JKQTMathTextTBRDataH<TText>& data, size_t /*seed=0*/) {
|
||||||
|
#else
|
||||||
|
inline uint qHash(const JKQTMathTextTBRDataH<TText>& data) {
|
||||||
|
#endif
|
||||||
|
return qHash(data.f)+qHash(data.text)+::qHash(data.ldpiX)+::qHash(data.ldpiY)+::qHash(data.pdpiX)+::qHash(data.pdpiY);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class TText=QString>
|
||||||
|
struct JKQTMathTextTBRDataHExt: public JKQTMathTextTBRDataH<TText> {
|
||||||
|
inline explicit JKQTMathTextTBRDataHExt(const QFont& f_, const TText& text_, QPaintDevice *pd_):
|
||||||
|
JKQTMathTextTBRDataH<TText>(f_,text_,pd_), pd(pd_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QPaintDevice *pd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QRectF JKQTMathTextGetTightBoundingRect(const QFont &f, const QString &text, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
//thread_local JKQTPDataCache<QRectF,JKQTMathTextTBRDataH,false,JKQTMathTextTBRDataHExt> cache(
|
||||||
|
static JKQTPDataCache<QRectF,JKQTMathTextTBRDataH<QString>,true,JKQTMathTextTBRDataHExt<QString>> cache(
|
||||||
|
[](const JKQTMathTextTBRDataHExt<QString>& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.tightBoundingRect(key.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, text, pd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF JKQTMathTextGetBoundingRect(const QFont &f, const QString &text, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
//thread_local JKQTPDataCache<QRectF,JKQTMathTextTBRDataH,false,JKQTMathTextTBRDataHExt> cache(
|
||||||
|
static JKQTPDataCache<QRectF,JKQTMathTextTBRDataH<QString>,true,JKQTMathTextTBRDataHExt<QString>> cache(
|
||||||
|
[](const JKQTMathTextTBRDataHExt<QString>& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.boundingRect(key.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, text, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetHorAdvance(const QFont &f, const QString &text, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
//thread_local JKQTPDataCache<double,JKQTMathTextTBRDataH,false,JKQTMathTextTBRDataHExt> cache(
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextTBRDataH<QString>,true,JKQTMathTextTBRDataHExt<QString>> cache(
|
||||||
|
[](const JKQTMathTextTBRDataHExt<QString>& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
#if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
return fm.horizontalAdvance(key.text);
|
||||||
|
#else
|
||||||
|
return fm.width(key.text);
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, text, pd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetRightBearing(const QFont &f, const QChar &text, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
//thread_local JKQTPDataCache<double,JKQTMathTextTBRDataH,false,JKQTMathTextTBRDataHExt> cache(
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextTBRDataH<QChar>,true,JKQTMathTextTBRDataHExt<QChar>> cache(
|
||||||
|
[](const JKQTMathTextTBRDataHExt<QChar>& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.rightBearing(key.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, text, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetLeftBearing(const QFont &f, const QChar &text, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
//thread_local JKQTPDataCache<double,JKQTMathTextTBRDataH,false,JKQTMathTextTBRDataHExt> cache(
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextTBRDataH<QChar>,true,JKQTMathTextTBRDataHExt<QChar>> cache(
|
||||||
|
[](const JKQTMathTextTBRDataHExt<QChar>& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.leftBearing(key.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, text, pd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontAscent(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.ascent();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontDescent(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.descent();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontHeight(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.height();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontLineWidth(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.lineWidth();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontLeading(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.leading();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontLineSpacing(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.lineSpacing();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal JKQTMathTextGetFontStrikoutPos(const QFont &f, QPaintDevice *pd)
|
||||||
|
{
|
||||||
|
static JKQTPDataCache<qreal,JKQTMathTextCacheKeyBase,true,JKQTMathTextCacheKeyBaseExt> cache(
|
||||||
|
[](const JKQTMathTextCacheKeyBaseExt& key) {
|
||||||
|
const QFontMetricsF fm(key.f, key.pd);
|
||||||
|
return fm.strikeOutPos();
|
||||||
|
});
|
||||||
|
|
||||||
|
return cache.get_inline(f, pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFont JKQTMathTextGetNonItalic(const QFont &font)
|
QFont JKQTMathTextGetNonItalic(const QFont &font)
|
||||||
@ -1048,12 +1208,12 @@ JKQTMathTextBlackboradDrawingMode String2JKQTMathTextBlackboradDrawingMode(QStri
|
|||||||
|
|
||||||
void JKQTMathTextDrawStringSimBlackboard(QPainter &painter, const QFont &f, const QColor& color, double x, double y, const QString &txt)
|
void JKQTMathTextDrawStringSimBlackboard(QPainter &painter, const QFont &f, const QColor& color, double x, double y, const QString &txt)
|
||||||
{
|
{
|
||||||
const QFontMetricsF fm(f, painter.device());
|
const qreal lw=JKQTMathTextGetFontLineWidth(f, painter.device());
|
||||||
const QPen p(color, fm.lineWidth()/4.0, Qt::SolidLine);
|
const QPen p(color, lw/4.0, Qt::SolidLine);
|
||||||
painter.setPen(p);
|
painter.setPen(p);
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
path.addText(QPointF(x, y), f, txt);
|
path.addText(QPointF(x, y), f, txt);
|
||||||
path.addText(QPointF(x+fm.lineWidth()/2.0, y), f, txt);
|
path.addText(QPointF(x+lw/2.0, y), f, txt);
|
||||||
painter.drawPath(path);
|
painter.drawPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,3 +1234,4 @@ JKQTMathTextLineSpacingMode String2JKQTMathTextLineSpacingMode(QString tokenName
|
|||||||
if (tokenName=="minimal" || tokenName=="min" || tokenName=="minimum") return MTSMMinimalSpacing;
|
if (tokenName=="minimal" || tokenName=="min" || tokenName=="minimum") return MTSMMinimalSpacing;
|
||||||
return MTSMDefaultSpacing;
|
return MTSMDefaultSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,8 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QFontMetricsF>
|
||||||
class JKQTMathText; // forward
|
class JKQTMathText; // forward
|
||||||
|
|
||||||
|
|
||||||
@ -471,41 +472,173 @@ JKQTMATHTEXT_LIB_EXPORT QPainterPath JKQTMathTextMakeDArrow(double x, double y,
|
|||||||
*/
|
*/
|
||||||
JKQTMATHTEXT_LIB_EXPORT void JKQTMathTextDrawStringSimBlackboard(QPainter& painter, const QFont& f, const QColor &color, double x, double y, const QString& txt);
|
JKQTMATHTEXT_LIB_EXPORT void JKQTMathTextDrawStringSimBlackboard(QPainter& painter, const QFont& f, const QColor &color, double x, double y, const QString& txt);
|
||||||
|
|
||||||
struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRData {
|
|
||||||
explicit JKQTMathTextTBRData(const QFont& f, const QString& text, QPaintDevice *pd);
|
|
||||||
QFontMetricsF fm;
|
|
||||||
QString text;
|
|
||||||
QRectF tbr;
|
|
||||||
QFont f;
|
|
||||||
int ldpiX, ldpiY, pdpiX, pdpiY;
|
|
||||||
//QPaintDevice *pd;
|
|
||||||
|
|
||||||
bool operator==(const JKQTMathTextTBRData& other) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTBRDataH {
|
|
||||||
explicit JKQTMathTextTBRDataH(const QFont& f, const QString& text, QPaintDevice *pd);
|
|
||||||
QString text;
|
|
||||||
QFont f;
|
|
||||||
int ldpiX, ldpiY, pdpiX, pdpiY;
|
|
||||||
|
|
||||||
bool operator==(const JKQTMathTextTBRDataH& other) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
/** \brief calculates the tight bounding rectangle around \a text
|
||||||
inline size_t qHash(const JKQTMathTextTBRDataH& data, size_t /*seed=0*/) {
|
* (from <a href="https://doc.qt.io/qt/qfontmetricsf.html#tightBoundingRect">QFontMetricsF::tightBoundingRect()</a>),
|
||||||
#else
|
* uses internal (thread-local) hashing to not redo a calculation that has already been performed
|
||||||
inline uint qHash(const JKQTMathTextTBRDataH& data) {
|
|
||||||
#endif
|
|
||||||
return qHash(data.f.family())+qHash(data.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief calculates the tight bounding rectangle around \a text, uses internal hashing to not redo a calculation that has already been performed
|
|
||||||
* \ingroup jkqtmathtext_tools
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font the text should be set in
|
||||||
|
* \param text the text of which the properties are calculated
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
*/
|
*/
|
||||||
JKQTMATHTEXT_LIB_EXPORT QRectF JKQTMathTextGetTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd);
|
JKQTMATHTEXT_LIB_EXPORT QRectF JKQTMathTextGetTightBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the bounding rectangle around \a text
|
||||||
|
* (from (using <a href="https://doc.qt.io/qt/qfontmetricsf.html#boundingRect">QFontMetricsF::boundingRect()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font the text should be set in
|
||||||
|
* \param text the text of which the properties are calculated
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT QRectF JKQTMathTextGetBoundingRect(const QFont &fm, const QString& text, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the horizontal advance of \a text
|
||||||
|
* (from <a href="https://doc.qt.io/qt/qfontmetricsf.html#horizontalAdvance">QFontMetricsF::horizontalAdvance()</a>
|
||||||
|
* or \c QFontMetricsF::width() if it is not yet available in your Qt version),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font the text should be set in
|
||||||
|
* \param text the text of which the properties are calculated
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetHorAdvance(const QFont &fm, const QString& text, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the left bearing of \a text
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#leftBearing">QFontMetricsF::leftBearing()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font the text should be set in
|
||||||
|
* \param text the character of which the properties are calculated
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetLeftBearing(const QFont &fm, const QChar& text, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the right bearing of \a text
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#rightBearing">QFontMetricsF::rightBearing()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font the text should be set in
|
||||||
|
* \param text the character of which the properties are calculated
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetRightBearing(const QFont &fm, const QChar& text, QPaintDevice *pd);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief calculates the strikeout-pos of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#strikeoutPos">QFontMetricsF::strikeoutPos()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontStrikoutPos(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the line width of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#lineWidth">QFontMetricsF::lineWidth()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontLineWidth(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the ascent of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#ascent">QFontMetricsF::ascent()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontAscent(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the descent of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#descent">QFontMetricsF::descent()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontDescent(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief calculates the height of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#height">QFontMetricsF::height()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontHeight(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the leading of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#leading">QFontMetricsF::leading()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontLeading(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
/** \brief calculates the line spacing of \a font
|
||||||
|
* (from <a href="https://doc.qt.io/qt-6/qfontmetricsf.html#lineSpacing">QFontMetricsF::lineSpacing()</a>),
|
||||||
|
* uses internal hashing to not redo a calculation that has already been performed
|
||||||
|
* \ingroup jkqtmathtext_tools
|
||||||
|
*
|
||||||
|
* \param fm font for which to calculate
|
||||||
|
* \param pd (or \c nullptr) the currently used <a href="https://doc.qt.io/qt-6/qpaintdevice.html">QPaintDevice</a>
|
||||||
|
* (e.g. from <a href="https://doc.qt.io/qt/qpainter.html#device">QPainter::device()</a> )
|
||||||
|
*
|
||||||
|
* \note This function is thread-safe and uses the same cache for all threads (so they profit from eachother)
|
||||||
|
*/
|
||||||
|
JKQTMATHTEXT_LIB_EXPORT qreal JKQTMathTextGetFontLineSpacing(const QFont &fm, QPaintDevice *pd);
|
||||||
|
|
||||||
|
|
||||||
/** \brief returns a copy of \a f, but with the italic-property set to \c false
|
/** \brief returns a copy of \a f, but with the italic-property set to \c false
|
||||||
* \ingroup jkqtmathtext_tools
|
* \ingroup jkqtmathtext_tools
|
||||||
*/
|
*/
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QFontInfo>
|
#include <QFontInfo>
|
||||||
@ -60,9 +60,9 @@ JKQTMathTextNodeSize JKQTMathTextBoxInstructionNode::getSizeInternal(QPainter& p
|
|||||||
inst.modifier(ev, getParameters());
|
inst.modifier(ev, getParameters());
|
||||||
const QPen p=inst.pen(ev, getParameters(), parentMathText);
|
const QPen p=inst.pen(ev, getParameters(), parentMathText);
|
||||||
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
|
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
|
||||||
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)), painter.device());
|
const QFont fNonItalic=JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText));
|
||||||
const double lw=p.widthF();
|
const double lw=p.widthF();
|
||||||
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
|
const double padding=inst.paddingFactor*JKQTMathTextGetBoundingRect(fNonItalic, "x", painter.device()).width();
|
||||||
|
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
JKQTMathTextNodeSize s;
|
JKQTMathTextNodeSize s;
|
||||||
@ -74,6 +74,9 @@ JKQTMathTextNodeSize JKQTMathTextBoxInstructionNode::getSizeInternal(QPainter& p
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextBoxInstructionNode[]::draw()"));
|
||||||
|
#endif
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
|
|
||||||
@ -81,10 +84,10 @@ double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double
|
|||||||
inst.modifier(ev, getParameters());
|
inst.modifier(ev, getParameters());
|
||||||
const QPen p=inst.pen(ev, getParameters(), parentMathText);
|
const QPen p=inst.pen(ev, getParameters(), parentMathText);
|
||||||
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
|
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
|
||||||
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)), painter.device());
|
const QFont fNonItalic=JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText));
|
||||||
const double lw=p.widthF();
|
const double lw=p.widthF();
|
||||||
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
|
const double padding=inst.paddingFactor*JKQTMathTextGetBoundingRect(fNonItalic, "x", painter.device()).width();
|
||||||
const double rr=inst.roundingFactor*fmNonItalic.tightBoundingRect("x").width();
|
const double rr=inst.roundingFactor*JKQTMathTextGetBoundingRect(fNonItalic, "x", painter.device()).width();
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -116,10 +119,10 @@ bool JKQTMathTextBoxInstructionNode::toHtml(QString &html, JKQTMathTextEnvironme
|
|||||||
inst.modifier(ev, getParameters());
|
inst.modifier(ev, getParameters());
|
||||||
const QPen p=inst.pen(ev, getParameters(), parentMathText);
|
const QPen p=inst.pen(ev, getParameters(), parentMathText);
|
||||||
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
|
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
|
||||||
const QFontMetricsF fmNonItalic(JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText)));
|
const QFont fNonItalic=JKQTMathTextGetNonItalic(currentEv.getFont(parentMathText));
|
||||||
//const double lw=p.widthF();
|
//const double lw=p.widthF();
|
||||||
const double padding=inst.paddingFactor*fmNonItalic.tightBoundingRect("x").width();
|
const double padding=inst.paddingFactor*JKQTMathTextGetBoundingRect(fNonItalic, "x", nullptr).width();
|
||||||
//const double rr=inst.roundingFactor*fmNonItalic.tightBoundingRect("x").width();
|
//const double rr=inst.roundingFactor*JKQTMathTextGetBoundingRect(fNonItalic, "x", painter.device()).width();
|
||||||
QString s=QString("padding: %1px").arg(padding);
|
QString s=QString("padding: %1px").arg(padding);
|
||||||
if (p!=Qt::NoPen) {
|
if (p!=Qt::NoPen) {
|
||||||
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
|
if (s.size()>0 && s.right(2)!="; ") s=s+"; ";
|
||||||
@ -310,7 +313,7 @@ JKQTMathTextBoxInstructionNode::InstructionProperties::ModifyEnvironmentFunctor
|
|||||||
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/){};
|
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/){};
|
||||||
|
|
||||||
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::DefaultPen=
|
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::DefaultPen=
|
||||||
[](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, JKQTMathText* parent){ return QPen(ev.color, QFontMetricsF(ev.getFont(parent)).lineWidth(), Qt::SolidLine); };
|
[](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, JKQTMathText* parent){ return QPen(ev.color, JKQTMathTextGetFontLineWidth(ev.getFont(parent),nullptr), Qt::SolidLine); };
|
||||||
|
|
||||||
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoPen=
|
JKQTMathTextBoxInstructionNode::InstructionProperties::GetBoxPenFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoPen=
|
||||||
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/, JKQTMathText* /*parent*/){ return Qt::NoPen; };
|
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/, JKQTMathText* /*parent*/){ return Qt::NoPen; };
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -55,8 +56,8 @@ JKQTMathTextBraceNode::NodeSize JKQTMathTextBraceNode::getSizeInternalAndBrace(Q
|
|||||||
{
|
{
|
||||||
NodeSize s;
|
NodeSize s;
|
||||||
const NodeSize childSize=getChild()->getSize(painter, currentEv);
|
const NodeSize childSize=getChild()->getSize(painter, currentEv);
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const double minChildHeight=fm.tightBoundingRect("l").height();
|
const double minChildHeight=JKQTMathTextGetTightBoundingRect(f, "l", painter.device()).height();
|
||||||
|
|
||||||
double cAscentAboveStrike=0;
|
double cAscentAboveStrike=0;
|
||||||
double cDescentBelowStrike=0;
|
double cDescentBelowStrike=0;
|
||||||
@ -84,13 +85,16 @@ JKQTMathTextBraceNode::NodeSize JKQTMathTextBraceNode::getSizeInternalAndBrace(Q
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextBraceNode[]::draw()"));
|
||||||
|
#endif
|
||||||
//std::cout<<"drawing brace-node: '"<<openbrace.toStdString()<<"' ... '"<<closebrace.toStdString()<<"'\n";
|
//std::cout<<"drawing brace-node: '"<<openbrace.toStdString()<<"' ... '"<<closebrace.toStdString()<<"'\n";
|
||||||
|
|
||||||
const NodeSize nodesize=getSizeInternalAndBrace(painter, currentEv);
|
const NodeSize nodesize=getSizeInternalAndBrace(painter, currentEv);
|
||||||
doDrawBoxes(painter, x, y, nodesize);
|
doDrawBoxes(painter, x, y, nodesize);
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
|
|
||||||
const double lw=fm.lineWidth();
|
const double lw=JKQTMathTextGetFontLineWidth(f, painter.device());
|
||||||
|
|
||||||
double xnew=x;
|
double xnew=x;
|
||||||
|
|
||||||
@ -360,7 +364,6 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//qDebug()<<" ==> "<<bc<<fm.boundingRect(bc).width();
|
|
||||||
return xnew;
|
return xnew;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,20 +469,20 @@ JKQTMathTextBraceNode::NodeSize::NodeSize(const NodeSize &other):
|
|||||||
|
|
||||||
void JKQTMathTextBraceNode::calcBraceSizes(NodeSize& out, QPainter &painter, const JKQTMathTextEnvironment &ev, const JKQTMathTextNodeSize &childSize) const
|
void JKQTMathTextBraceNode::calcBraceSizes(NodeSize& out, QPainter &painter, const JKQTMathTextEnvironment &ev, const JKQTMathTextNodeSize &childSize) const
|
||||||
{
|
{
|
||||||
const QFontMetricsF fm(ev.getFont(parentMathText), painter.device());
|
const QFont f=ev.getFont(parentMathText);
|
||||||
const QSizeF openBraceS=calcBraceSize(fm, openbrace, childSize);
|
const QSizeF openBraceS=calcBraceSize(f, painter.device(), openbrace, childSize);
|
||||||
const QSizeF closeBraceS=calcBraceSize(fm, closebrace, childSize);
|
const QSizeF closeBraceS=calcBraceSize(f, painter.device(), closebrace, childSize);
|
||||||
out.openBraceWidth=openBraceS.width();
|
out.openBraceWidth=openBraceS.width();
|
||||||
out.openBraceHeight=openBraceS.width();
|
out.openBraceHeight=openBraceS.width();
|
||||||
out.closeBraceWidth=closeBraceS.width();
|
out.closeBraceWidth=closeBraceS.width();
|
||||||
out.closeBraceHeight=closeBraceS.width();
|
out.closeBraceHeight=closeBraceS.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF JKQTMathTextBraceNode::calcBraceSize(const QFontMetricsF &fm, JKQTMathTextBraceType bracetype, const JKQTMathTextNodeSize &childSize) const
|
QSizeF JKQTMathTextBraceNode::calcBraceSize(const QFont &f, QPaintDevice *pd, JKQTMathTextBraceType bracetype, const JKQTMathTextNodeSize &childSize) const
|
||||||
{
|
{
|
||||||
double braceWidth=0.0;
|
double braceWidth=0.0;
|
||||||
double braceHeight=0.0;
|
double braceHeight=0.0;
|
||||||
const double lw=fm.lineWidth();
|
const double lw=JKQTMathTextGetFontLineWidth(f, pd);
|
||||||
const double dblline_distance=2.0*lw;
|
const double dblline_distance=2.0*lw;
|
||||||
braceHeight=childSize.overallHeight*parentMathText->getBraceFactor();
|
braceHeight=childSize.overallHeight*parentMathText->getBraceFactor();
|
||||||
braceWidth=lw*5.0;
|
braceWidth=lw*5.0;
|
||||||
@ -489,7 +492,7 @@ QSizeF JKQTMathTextBraceNode::calcBraceSize(const QFontMetricsF &fm, JKQTMathTex
|
|||||||
if (bracetype==MTBTSingleLine) braceWidth=3.0*lw;
|
if (bracetype==MTBTSingleLine) braceWidth=3.0*lw;
|
||||||
if (bracetype==MTBTSquareBracket || bracetype==MTBTCeilBracket || bracetype==MTBTFloorBracket) braceWidth=7.0*lw;
|
if (bracetype==MTBTSquareBracket || bracetype==MTBTCeilBracket || bracetype==MTBTFloorBracket) braceWidth=7.0*lw;
|
||||||
|
|
||||||
const double overSizeFactor=braceHeight/fm.height();
|
const double overSizeFactor=braceHeight/JKQTMathTextGetFontHeight(f, pd);
|
||||||
if (overSizeFactor>1.2) braceWidth=braceWidth*sqrt(overSizeFactor);
|
if (overSizeFactor>1.2) braceWidth=braceWidth*sqrt(overSizeFactor);
|
||||||
|
|
||||||
return QSizeF(braceWidth, braceHeight);
|
return QSizeF(braceWidth, braceHeight);
|
||||||
|
@ -101,7 +101,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextSingleCh
|
|||||||
*
|
*
|
||||||
* \return width and hieght of the brace
|
* \return width and hieght of the brace
|
||||||
*/
|
*/
|
||||||
QSizeF calcBraceSize(const QFontMetricsF& fm, JKQTMathTextBraceType bracetype, const JKQTMathTextNodeSize &childSize) const;
|
QSizeF calcBraceSize(const QFont& fm, QPaintDevice* pd, JKQTMathTextBraceType bracetype, const JKQTMathTextNodeSize &childSize) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // JKQTMATHTEXTBRACENODE_H
|
#endif // JKQTMATHTEXTBRACENODE_H
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -133,15 +134,15 @@ JKQTMathTextNodeSize JKQTMathTextDecoratedNode::getSizeInternal(QPainter& painte
|
|||||||
JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
const double cDescent=cs.getDescent();
|
const double cDescent=cs.getDescent();
|
||||||
const QFont font=ev.getFont(parentMathText);
|
const QFont font=ev.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(font, painter.device());
|
const double fascent=JKQTMathTextGetFontAscent(font, painter.device());
|
||||||
const double decoSeparation=parentMathText->getDecorationSeparationFactor()*fm.ascent();
|
const double decoSeparation=parentMathText->getDecorationSeparationFactor()*fascent;
|
||||||
const double deco_height=parentMathText->getDecorationHeightFactor()*fm.ascent();
|
const double deco_height=parentMathText->getDecorationHeightFactor()*fascent;
|
||||||
const double deco_ypos=cs.baselineHeight+decoSeparation;
|
const double deco_ypos=cs.baselineHeight+decoSeparation;
|
||||||
const double decoAboveAscent_ypos=fm.ascent()+decoSeparation;
|
const double decoAboveAscent_ypos=fascent+decoSeparation;
|
||||||
const double decobelow_ypos=cDescent+decoSeparation;
|
const double decobelow_ypos=cDescent+decoSeparation;
|
||||||
const double italic_xcorrection=getNonItalicXCorretion(painter, cs.width, ev, getChild());
|
const double italic_xcorrection=getNonItalicXCorretion(painter, cs.width, ev, getChild());
|
||||||
const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("~").width():fm.boundingRect("^").width())-italic_xcorrection;
|
const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?JKQTMathTextGetBoundingRect(font,"~",painter.device()).width():JKQTMathTextGetBoundingRect(font,"^",painter.device()).width())-italic_xcorrection;
|
||||||
const double linewidth=qMax(parentMathText->ABS_MIN_LINEWIDTH, fm.lineWidth());
|
const double linewidth=qMax(parentMathText->ABS_MIN_LINEWIDTH, JKQTMathTextGetFontLineWidth(font, painter.device()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -227,20 +228,24 @@ const QHash<QString, JKQTMathTextDecoratedNode::DecorationType>& JKQTMathTextDec
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextDecoratedNode[]::draw()"));
|
||||||
|
#endif
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
auto cs=getChild()->getSize(painter, ev);
|
auto cs=getChild()->getSize(painter, ev);
|
||||||
const double cDescent=cs.overallHeight-cs.baselineHeight;
|
const double cDescent=cs.overallHeight-cs.baselineHeight;
|
||||||
const QFont font=ev.getFont(parentMathText);
|
const QFont font=ev.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(font, painter.device());
|
const QFontMetricsF fm(font, painter.device());
|
||||||
const double width_X=fm.boundingRect("X").width();
|
const double width_X=JKQTMathTextGetBoundingRect(font,"X",painter.device()).width();
|
||||||
const double width_x=fm.boundingRect("x").width();
|
const double width_x=JKQTMathTextGetBoundingRect(font,"x",painter.device()).width();
|
||||||
const double width_dot=fm.boundingRect(".").width()/2.0;
|
const double width_dot=JKQTMathTextGetBoundingRect(font,".",painter.device()).width()/2.0;
|
||||||
const double decoSeparation=parentMathText->getDecorationSeparationFactor()*fm.ascent();
|
const double ascent=JKQTMathTextGetFontLineWidth(font, painter.device());
|
||||||
const double linewidth=qMax(parentMathText->ABS_MIN_LINEWIDTH, fm.lineWidth());
|
const double decoSeparation=parentMathText->getDecorationSeparationFactor()*ascent;
|
||||||
|
const double linewidth=qMax(parentMathText->ABS_MIN_LINEWIDTH, JKQTMathTextGetFontLineWidth(font, painter.device()));
|
||||||
const double linewidthArrow=linewidth*0.65;
|
const double linewidthArrow=linewidth*0.65;
|
||||||
const double deco_height=parentMathText->getDecorationHeightFactor()*fm.ascent();
|
const double deco_height=parentMathText->getDecorationHeightFactor()*ascent;
|
||||||
const double decoAboveAscent_ypos=y-fm.ascent()-decoSeparation;
|
const double decoAboveAscent_ypos=y-ascent-decoSeparation;
|
||||||
const double strike_ypos=y-cs.baselineHeight/2.0;
|
const double strike_ypos=y-cs.baselineHeight/2.0;
|
||||||
const double decobelow_ypos=y+cDescent+decoSeparation;
|
const double decobelow_ypos=y+cDescent+decoSeparation;
|
||||||
const double italic_xcorrection=getNonItalicXCorretion(painter, cs.width, ev, getChild());
|
const double italic_xcorrection=getNonItalicXCorretion(painter, cs.width, ev, getChild());
|
||||||
@ -249,7 +254,7 @@ double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JK
|
|||||||
const double deco_vecwidth=width_x*0.25;
|
const double deco_vecwidth=width_x*0.25;
|
||||||
const double deco_vecheight=deco_height*0.5;
|
const double deco_vecheight=deco_height*0.5;
|
||||||
const double deco_accentwidth=deco_height/4.0;
|
const double deco_accentwidth=deco_height/4.0;
|
||||||
const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?fm.boundingRect("j").width():fm.boundingRect("^").width())-italic_xcorrection;
|
const double deco_miniwidth=((decoration==MTDtilde||decoration==MTDbreve)?JKQTMathTextGetBoundingRect(font,"~",painter.device()).width():JKQTMathTextGetBoundingRect(font,"^",painter.device()).width())-italic_xcorrection;
|
||||||
const double decotop_xcenter=x+italic_xcorrection+(cs.width-italic_xcorrection)/2.0;
|
const double decotop_xcenter=x+italic_xcorrection+(cs.width-italic_xcorrection)/2.0;
|
||||||
const double decotop_xstart=decotop_xcenter-deco_width/2.0+linewidth/2.0;
|
const double decotop_xstart=decotop_xcenter-deco_width/2.0+linewidth/2.0;
|
||||||
const double decotop_xend=decotop_xcenter+deco_width/2.0-linewidth/2.0;
|
const double decotop_xend=decotop_xcenter+deco_width/2.0-linewidth/2.0;
|
||||||
@ -280,7 +285,7 @@ double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JK
|
|||||||
auto fDrawFontAccent=[&](QChar aDirect=QChar(), QChar aFallback=QChar()) -> bool {
|
auto fDrawFontAccent=[&](QChar aDirect=QChar(), QChar aFallback=QChar()) -> bool {
|
||||||
if (!aDirect.isNull() && fm.inFont(aDirect)) {
|
if (!aDirect.isNull() && fm.inFont(aDirect)) {
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
const QRectF tbra=fm.tightBoundingRect(aDirect);
|
const QRectF tbra=JKQTMathTextGetBoundingRect(font, aDirect, painter.device());
|
||||||
painter.translate(decotop_xcenter-tbra.width()/2.0, (deco_ytopcenter+deco_ytoptop)/2.0);
|
painter.translate(decotop_xcenter-tbra.width()/2.0, (deco_ytopcenter+deco_ytoptop)/2.0);
|
||||||
//painter.setPen("red");
|
//painter.setPen("red");
|
||||||
//painter.drawEllipse(0-2,0-2,4,4);
|
//painter.drawEllipse(0-2,0-2,4,4);
|
||||||
@ -298,7 +303,7 @@ double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JK
|
|||||||
}
|
}
|
||||||
if (!aFallback.isNull() && fm.inFont(aFallback)) {
|
if (!aFallback.isNull() && fm.inFont(aFallback)) {
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
const QRectF tbra=fm.tightBoundingRect(aFallback);
|
const QRectF tbra=JKQTMathTextGetBoundingRect(font, aFallback, painter.device());
|
||||||
painter.translate(decotop_xcenter-tbra.width()/2.0, (deco_ytopcenter+deco_ytoptop)/2.0);
|
painter.translate(decotop_xcenter-tbra.width()/2.0, (deco_ytopcenter+deco_ytoptop)/2.0);
|
||||||
//painter.setPen("yellow");
|
//painter.setPen("yellow");
|
||||||
//painter.drawEllipse(0-2,0-2,4,4);
|
//painter.drawEllipse(0-2,0-2,4,4);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -128,15 +129,14 @@ JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JK
|
|||||||
if (fracmode==MTFMsfrac) fracmode=MTFMstfrac;
|
if (fracmode==MTFMsfrac) fracmode=MTFMstfrac;
|
||||||
}
|
}
|
||||||
const QFont f=currentEv.getFont(parentMathText);
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
JKQTMathTextEnvironment ev1=currentEv;
|
JKQTMathTextEnvironment ev1=currentEv;
|
||||||
JKQTMathTextEnvironment ev2=currentEv;
|
JKQTMathTextEnvironment ev2=currentEv;
|
||||||
|
|
||||||
const double xheight=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height();
|
const double xheight=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height();
|
||||||
const double line_ascent=xheight/2.0;
|
const double line_ascent=xheight/2.0;
|
||||||
//const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
//const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();
|
||||||
const double xwidth=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width();
|
const double xwidth=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width();
|
||||||
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();
|
||||||
const double braceheight=xheight*parentMathText->getUnderbraceBraceSizeXFactor();
|
const double braceheight=xheight*parentMathText->getUnderbraceBraceSizeXFactor();
|
||||||
const double braceseparation=xheight*parentMathText->getUnderbraceSeparationXFactor();
|
const double braceseparation=xheight*parentMathText->getUnderbraceSeparationXFactor();
|
||||||
|
|
||||||
@ -152,11 +152,11 @@ JKQTMathTextNodeSize JKQTMathTextFracNode::getSizeInternal(QPainter& painter, JK
|
|||||||
ev2.fontSize=ev2.fontSize*getFracScalingFactor()*0.7;
|
ev2.fontSize=ev2.fontSize*getFracScalingFactor()*0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QFontMetricsF fmev1(ev1.getFont(parentMathText), painter.device());
|
const QFont fev1=ev1.getFont(parentMathText);
|
||||||
const QRectF AeTBR1=fmev1.tightBoundingRect("A");
|
const QRectF AeTBR1=JKQTMathTextGetBoundingRect(fev1, "A", painter.device());
|
||||||
const double asc1=AeTBR1.height();
|
const double asc1=AeTBR1.height();
|
||||||
const QFontMetricsF fmev2(ev2.getFont(parentMathText), painter.device());
|
const QFont fev2=ev2.getFont(parentMathText);
|
||||||
const QRectF AeTBR2=fmev2.tightBoundingRect("A");
|
const QRectF AeTBR2=JKQTMathTextGetBoundingRect(fev2, "A", painter.device());
|
||||||
const double asc2=AeTBR2.height();
|
const double asc2=AeTBR2.height();
|
||||||
|
|
||||||
JKQTMathTextNodeSize size1=child1->getSize(painter, ev1);
|
JKQTMathTextNodeSize size1=child1->getSize(painter, ev1);
|
||||||
@ -243,6 +243,9 @@ double JKQTMathTextFracNode::getFracScalingFactor() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextFracNode[]::draw()"));
|
||||||
|
#endif
|
||||||
FracType fracmode=this->mode;
|
FracType fracmode=this->mode;
|
||||||
if (currentEv.isMathTextStyle()) {
|
if (currentEv.isMathTextStyle()) {
|
||||||
if (fracmode==MTFMfrac) fracmode=MTFMtfrac;
|
if (fracmode==MTFMfrac) fracmode=MTFMtfrac;
|
||||||
@ -251,14 +254,13 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
|
|||||||
|
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
const QFont f=currentEv.getFont(parentMathText);
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
JKQTMathTextEnvironment ev1=currentEv;
|
JKQTMathTextEnvironment ev1=currentEv;
|
||||||
JKQTMathTextEnvironment ev2=currentEv;
|
JKQTMathTextEnvironment ev2=currentEv;
|
||||||
|
|
||||||
|
const QRectF tbr_x=JKQTMathTextGetTightBoundingRect(f, "x", painter.device());
|
||||||
const double xheight=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height();
|
const double xheight=tbr_x.height();
|
||||||
const double xwidth=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).width();
|
const double xwidth=tbr_x.width();
|
||||||
const double linewideth=fm.lineWidth();
|
const double linewideth=JKQTMathTextGetFontLineWidth(f, painter.device());
|
||||||
const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
const double Mheight=JKQTMathTextGetTightBoundingRect(f, "M", painter.device()).height();//fm.ascent();
|
||||||
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
const double qheight=JKQTMathTextGetTightBoundingRect(f, "q", painter.device()).height();//fm.ascent();
|
||||||
const double braceheight=xheight*parentMathText->getUnderbraceBraceSizeXFactor();
|
const double braceheight=xheight*parentMathText->getUnderbraceBraceSizeXFactor();
|
||||||
@ -277,13 +279,14 @@ double JKQTMathTextFracNode::draw(QPainter& painter, double x, double y, JKQTMat
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const QFontMetricsF fmev1(ev1.getFont(parentMathText), painter.device());
|
const QFont fev1=ev1.getFont(parentMathText);
|
||||||
const QRectF AeTBR1=fmev1.tightBoundingRect("A");
|
const QRectF AeTBR1=JKQTMathTextGetBoundingRect(fev1, "A", painter.device());
|
||||||
const double asc1=AeTBR1.height();
|
const double asc1=AeTBR1.height();
|
||||||
const QFontMetricsF fmev2(ev2.getFont(parentMathText), painter.device());
|
const QFont fev2=ev2.getFont(parentMathText);
|
||||||
const QRectF AeTBR2=fmev2.tightBoundingRect("A");
|
const QRectF AeTBR2=JKQTMathTextGetBoundingRect(fev2, "A", painter.device());
|
||||||
const double asc2=AeTBR2.height();
|
const double asc2=AeTBR2.height();
|
||||||
|
|
||||||
|
|
||||||
JKQTMathTextNodeSize size1=child1->getSize(painter, ev1);
|
JKQTMathTextNodeSize size1=child1->getSize(painter, ev1);
|
||||||
JKQTMathTextNodeSize size2=child2->getSize(painter, ev2);
|
JKQTMathTextNodeSize size2=child2->getSize(painter, ev2);
|
||||||
if (asc1>size1.baselineHeight) {
|
if (asc1>size1.baselineHeight) {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -63,12 +64,12 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
|
|||||||
//bool wasBrace=false;
|
//bool wasBrace=false;
|
||||||
for (int i=0; i<nodes.size(); i++) {
|
for (int i=0; i<nodes.size(); i++) {
|
||||||
const QFont f=currentEv.getFont(parentMathText);
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
const auto tbr_x=JKQTMathTextGetTightBoundingRect(f, "x", painter.device());
|
||||||
const double subsupershift=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()*parentMathText->getOperatorsubsuperDistanceFactor();
|
const double subsupershift=tbr_x.height()*parentMathText->getOperatorsubsuperDistanceFactor();
|
||||||
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
|
const double subsuperextrawidth=tbr_x.width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
|
||||||
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
const double subsuperSpecialModeAscent=JKQTMathTextGetFontAscent(f, painter.device())*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
||||||
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
const double subsuperSpecialModeDecent=JKQTMathTextGetFontDescent(f, painter.device())*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
||||||
const double spaceWidth=fm.boundingRect(' ').width();
|
const double spaceWidth=JKQTMathTextGetBoundingRect(f, " ", painter.device()).width();
|
||||||
|
|
||||||
JKQTMathTextSymbolNode::NodeSize prevNodeSize;
|
JKQTMathTextSymbolNode::NodeSize prevNodeSize;
|
||||||
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
|
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
|
||||||
@ -85,7 +86,7 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
|
|||||||
if (shouldUseSpecialSubscriptMode) prevNodeSizePtrForSubscript=&prevNodeSize;
|
if (shouldUseSpecialSubscriptMode) prevNodeSizePtrForSubscript=&prevNodeSize;
|
||||||
if (shouldUseSpecialSuperscriptMode) prevNodeSizePtrForSuperscript=&prevNodeSize;
|
if (shouldUseSpecialSuperscriptMode) prevNodeSizePtrForSuperscript=&prevNodeSize;
|
||||||
}
|
}
|
||||||
const double subscript_xcorrection=prevNodeSize.baselineXCorrection+fm.lineWidth()*0.5;
|
const double subscript_xcorrection=prevNodeSize.baselineXCorrection+JKQTMathTextGetFontLineWidth(f, painter.device())*0.5;
|
||||||
|
|
||||||
JKQTMathTextSuperscriptNode* nodeI_SuperScript=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i]);
|
JKQTMathTextSuperscriptNode* nodeI_SuperScript=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i]);
|
||||||
JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i]);
|
JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i]);
|
||||||
@ -327,6 +328,9 @@ JKQTMathTextNodeSize JKQTMathTextHorizontalListNode::getSizeInternal(QPainter& p
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment ev) const {
|
double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment ev) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextHorizontalListNode[]::draw()"));
|
||||||
|
#endif
|
||||||
JKQTMathTextEnvironment currentEv=ev;
|
JKQTMathTextEnvironment currentEv=ev;
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
double ynew=y;
|
double ynew=y;
|
||||||
@ -335,11 +339,11 @@ double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double
|
|||||||
for (int i=0; i<nodes.size(); i++) {
|
for (int i=0; i<nodes.size(); i++) {
|
||||||
bool doDraw=true;
|
bool doDraw=true;
|
||||||
const QFont f=currentEv.getFont(parentMathText);
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
const auto tbr_x=JKQTMathTextGetTightBoundingRect(f, "x", painter.device());
|
||||||
const double subsupershift=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height()*parentMathText->getOperatorsubsuperDistanceFactor();
|
const double subsupershift=tbr_x.height()*parentMathText->getOperatorsubsuperDistanceFactor();
|
||||||
const double subsuperextrawidth=fm.boundingRect('x').width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
|
const double subsuperextrawidth=tbr_x.width()*parentMathText->getOperatorsubsuperExtraSpaceFactor();
|
||||||
const double subsuperSpecialModeAscent=fm.ascent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
const double subsuperSpecialModeAscent=JKQTMathTextGetFontAscent(f, painter.device())*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
||||||
const double subsuperSpecialModeDecent=fm.descent()*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
const double subsuperSpecialModeDecent=JKQTMathTextGetFontDescent(f, painter.device())*parentMathText->getSubsuperModeSelectionBySizeFactor();
|
||||||
|
|
||||||
JKQTMathTextSymbolNode::NodeSize prevNodeSize;
|
JKQTMathTextSymbolNode::NodeSize prevNodeSize;
|
||||||
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
|
JKQTMathTextNodeSize* prevNodeSizePtrForSubscript=nullptr;
|
||||||
@ -359,7 +363,7 @@ double JKQTMathTextHorizontalListNode::draw(QPainter& painter, double x, double
|
|||||||
if (shouldUseSpecialSubscriptMode) prevNodeSizePtrForSubscript=&prevNodeSize;
|
if (shouldUseSpecialSubscriptMode) prevNodeSizePtrForSubscript=&prevNodeSize;
|
||||||
if (shouldUseSpecialSuperscriptMode) prevNodeSizePtrForSuperscript=&prevNodeSize;
|
if (shouldUseSpecialSuperscriptMode) prevNodeSizePtrForSuperscript=&prevNodeSize;
|
||||||
}
|
}
|
||||||
const double subscript_xcorrection=prevNodeSize.baselineXCorrection+fm.lineWidth()*0.5;
|
const double subscript_xcorrection=prevNodeSize.baselineXCorrection+JKQTMathTextGetFontLineWidth(f, painter.device())*0.5;
|
||||||
|
|
||||||
JKQTMathTextSuperscriptNode* nodeI_SuperScript=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i]);
|
JKQTMathTextSuperscriptNode* nodeI_SuperScript=dynamic_cast<JKQTMathTextSuperscriptNode*>(nodes[i]);
|
||||||
JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i]);
|
JKQTMathTextSubscriptNode* nodeI_SubScript=dynamic_cast<JKQTMathTextSubscriptNode*>(nodes[i]);
|
||||||
|
@ -82,9 +82,8 @@ double JKQTMathTextSimpleInstructionNode::draw(QPainter &painter, double x, doub
|
|||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
QFont f=currentEv.getFont(parentMathText);
|
QFont f=currentEv.getFont(parentMathText);
|
||||||
f.setStyleStrategy(QFont::PreferDefault);
|
f.setStyleStrategy(QFont::PreferDefault);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
const QString txt=executeInstruction();
|
const QString txt=executeInstruction();
|
||||||
const QRectF bb=fm.boundingRect(txt);
|
const QRectF bb=JKQTMathTextGetBoundingRect(f, txt, painter.device());
|
||||||
painter.setPen(currentEv.color);
|
painter.setPen(currentEv.color);
|
||||||
painter.setFont(f);
|
painter.setFont(f);
|
||||||
painter.drawText(x,y,txt);
|
painter.drawText(x,y,txt);
|
||||||
@ -123,14 +122,13 @@ JKQTMathTextNodeSize JKQTMathTextSimpleInstructionNode::getSizeInternal(QPainter
|
|||||||
{
|
{
|
||||||
QFont f=currentEv.getFont(parentMathText);
|
QFont f=currentEv.getFont(parentMathText);
|
||||||
f.setStyleStrategy(QFont::PreferDefault);
|
f.setStyleStrategy(QFont::PreferDefault);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
const QString txt=executeInstruction();
|
const QString txt=executeInstruction();
|
||||||
const QRectF bb=fm.boundingRect(txt);
|
const QRectF bb=JKQTMathTextGetBoundingRect(f, txt, painter.device());
|
||||||
JKQTMathTextNodeSize s;
|
JKQTMathTextNodeSize s;
|
||||||
s.width=bb.width();
|
s.width=bb.width();
|
||||||
s.baselineHeight=-bb.y();
|
s.baselineHeight=-bb.y();
|
||||||
s.overallHeight=bb.height();
|
s.overallHeight=bb.height();
|
||||||
s.strikeoutPos=fm.strikeOutPos();
|
s.strikeoutPos=JKQTMathTextGetFontStrikoutPos(f, painter.device());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -318,10 +319,10 @@ JKQTMathTextMatrixNode::LayoutInfo JKQTMathTextMatrixNode::calcLayout(QPainter &
|
|||||||
|
|
||||||
JKQTMathTextEnvironment ev1=currentEv;
|
JKQTMathTextEnvironment ev1=currentEv;
|
||||||
|
|
||||||
const QFontMetricsF fm(ev1.getFont(parentMathText), painter.device());
|
const QFont font=ev1.getFont(parentMathText);
|
||||||
const double strikepos=fm.strikeOutPos();
|
const double strikepos=JKQTMathTextGetFontStrikoutPos(font, painter.device());
|
||||||
const double xwidth=fm.boundingRect("x").width();
|
const double xwidth=JKQTMathTextGetBoundingRect(font,"f",painter.device()).width();
|
||||||
const double lw=fm.lineWidth()*1.5;
|
const double lw=JKQTMathTextGetFontLineWidth(font, painter.device())*1.5;
|
||||||
const double XPadding=parentMathText->getMatrixXPaddingFactor()*xwidth;
|
const double XPadding=parentMathText->getMatrixXPaddingFactor()*xwidth;
|
||||||
const double YPadding=parentMathText->getMatrixYPaddingFactor()*xwidth;
|
const double YPadding=parentMathText->getMatrixYPaddingFactor()*xwidth;
|
||||||
const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
|
const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
|
||||||
@ -372,21 +373,25 @@ JKQTMathTextNodeSize JKQTMathTextMatrixNode::getSizeInternal(QPainter& painter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextMatrixNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextMatrixNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextMatrixNode[]::draw()"));
|
||||||
|
#endif
|
||||||
|
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
const QFont font=currentEv.getFont(parentMathText);
|
||||||
JKQTMathTextEnvironment ev1=currentEv;
|
JKQTMathTextEnvironment ev1=currentEv;
|
||||||
|
|
||||||
const LayoutInfo l=calcLayout(painter, currentEv);
|
const LayoutInfo l=calcLayout(painter, currentEv);
|
||||||
doDrawBoxes(painter, x, y, l);
|
doDrawBoxes(painter, x, y, l);
|
||||||
|
|
||||||
const double xwidth=fm.boundingRect("x").width();
|
const double xwidth=JKQTMathTextGetBoundingRect(font,"f",painter.device()).width();
|
||||||
|
const double fontlw=JKQTMathTextGetFontLineWidth(font, painter.device());
|
||||||
const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
|
const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
|
||||||
const double YSeparation=parentMathText->getMatrixYSeparationFactor()*xwidth;
|
const double YSeparation=parentMathText->getMatrixYSeparationFactor()*xwidth;
|
||||||
const double yTop=y-l.baselineHeight+l.topPadding;
|
const double yTop=y-l.baselineHeight+l.topPadding;
|
||||||
const double xLeft=x+l.leftPadding;
|
const double xLeft=x+l.leftPadding;
|
||||||
const double linewidth=parentMathText->getMatrixLinewidthThinFactor()*fm.lineWidth();
|
const double linewidth=parentMathText->getMatrixLinewidthThinFactor()*fontlw;
|
||||||
const double linewidthThick=parentMathText->getMatrixLinewidthHeavyFactor()*fm.lineWidth();
|
const double linewidthThick=parentMathText->getMatrixLinewidthHeavyFactor()*fontlw;
|
||||||
const double lineSeparation=parentMathText->getMatrixLineSeparationFactor()*fm.lineWidth();
|
const double lineSeparation=parentMathText->getMatrixLineSeparationFactor()*fontlw;
|
||||||
double leftlineX=xLeft-l.leftPadding/2.0;
|
double leftlineX=xLeft-l.leftPadding/2.0;
|
||||||
double rightlineX=x+l.width-l.rightPadding/2.0;
|
double rightlineX=x+l.width-l.rightPadding/2.0;
|
||||||
double toplineY=yTop-l.topPadding/2.0;
|
double toplineY=yTop-l.topPadding/2.0;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtexttools.h"
|
#include "jkqtmathtext/jkqtmathtexttools.h"
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -58,6 +59,9 @@ JKQTMathTextNodeSize JKQTMathTextModifiedTextPropsInstructionNode::getSizeIntern
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextModifiedTextPropsInstructionNode[]::draw()"));
|
||||||
|
#endif
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "jkqtmathtext/nodes/jkqtmathtextnoopnode.h"
|
#include "jkqtmathtext/nodes/jkqtmathtextnoopnode.h"
|
||||||
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
|
#include "jkqtmathtext/nodes/jkqtmathtextnode.h"
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +68,9 @@ QString JKQTMathTextBlockNode::getTypeName() const
|
|||||||
|
|
||||||
double JKQTMathTextBlockNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
double JKQTMathTextBlockNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextBlockNode[]::draw()"));
|
||||||
|
#endif
|
||||||
return child->draw(painter, x, y, currentEv);
|
return child->draw(painter, x, y, currentEv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -52,16 +53,16 @@ JKQTMathTextSqrtNode::~JKQTMathTextSqrtNode() {
|
|||||||
|
|
||||||
JKQTMathTextNodeSize JKQTMathTextSqrtNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
|
JKQTMathTextNodeSize JKQTMathTextSqrtNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
|
||||||
JKQTMathTextNodeSize s;
|
JKQTMathTextNodeSize s;
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
JKQTMathTextEnvironment evSmall=currentEv;
|
JKQTMathTextEnvironment evSmall=currentEv;
|
||||||
evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
|
evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
|
||||||
evSmall.italic=false;
|
evSmall.italic=false;
|
||||||
|
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, currentEv);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, currentEv);
|
||||||
const double descent=cs.getDescent();
|
const double descent=cs.getDescent();
|
||||||
const double sqrtwidth=fm.boundingRect("X").width()*parentMathText->getSqrtWidthXFactor();
|
const double sqrtwidth=JKQTMathTextGetBoundingRect(f, "X", painter.device()).width()*parentMathText->getSqrtWidthXFactor();
|
||||||
const double newAscent=qMax(cs.baselineHeight*parentMathText->getSqrtHeightFactor(), fm.ascent());
|
const double newAscent=qMax(cs.baselineHeight*parentMathText->getSqrtHeightFactor(), JKQTMathTextGetFontAscent(f, painter.device()));
|
||||||
const double newDescent=qMax(descent*parentMathText->getSqrtHeightFactor(), fm.descent());
|
const double newDescent=qMax(descent*parentMathText->getSqrtHeightFactor(), JKQTMathTextGetFontDescent(f, painter.device()));
|
||||||
|
|
||||||
s.overallHeight=newAscent+newDescent;
|
s.overallHeight=newAscent+newDescent;
|
||||||
s.baselineHeight=newAscent;
|
s.baselineHeight=newAscent;
|
||||||
@ -76,20 +77,22 @@ JKQTMathTextNodeSize JKQTMathTextSqrtNode::getSizeInternal(QPainter& painter, JK
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextSqrtNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSqrtNode[]::draw()"));
|
||||||
|
#endif
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
|
|
||||||
const QFont f=currentEv.getFont(parentMathText);
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
JKQTMathTextEnvironment evSmall=currentEv;
|
JKQTMathTextEnvironment evSmall=currentEv;
|
||||||
evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
|
evSmall.fontSize=currentEv.fontSize*parentMathText->getSqrtSmallFontFactor();
|
||||||
evSmall.italic=false;
|
evSmall.italic=false;
|
||||||
|
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, currentEv);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, currentEv);
|
||||||
const double descent=cs.overallHeight-cs.baselineHeight;
|
const double descent=cs.overallHeight-cs.baselineHeight;
|
||||||
const double sqrtwidth=fm.boundingRect("X").width()*parentMathText->getSqrtWidthXFactor();
|
const double sqrtwidth=JKQTMathTextGetBoundingRect(f, "X", painter.device()).width()*parentMathText->getSqrtWidthXFactor();
|
||||||
const double newAscent=qMax(cs.baselineHeight*parentMathText->getSqrtHeightFactor(), fm.ascent());
|
const double newAscent=qMax(cs.baselineHeight*parentMathText->getSqrtHeightFactor(), JKQTMathTextGetFontAscent(f, painter.device()));
|
||||||
const double newDescent=qMax(descent*parentMathText->getSqrtHeightFactor(), fm.descent());
|
const double newDescent=qMax(descent*parentMathText->getSqrtHeightFactor(), JKQTMathTextGetFontDescent(f, painter.device()));
|
||||||
const double linewidth=fm.lineWidth();
|
const double linewidth=JKQTMathTextGetFontLineWidth(f, painter.device());
|
||||||
const double tinyhookSize=sqrtwidth*0.1;
|
const double tinyhookSize=sqrtwidth*0.1;
|
||||||
const double smalltextIndent=0.6*sqrtwidth;
|
const double smalltextIndent=0.6*sqrtwidth;
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -50,7 +54,6 @@ JKQTMathTextNodeSize JKQTMathTextSuperscriptNode::getSizeWithSpecialPlacement(QP
|
|||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
||||||
const QFont fnt=currentEv.getFont(parentMathText);
|
const QFont fnt=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(fnt, painter.device());
|
|
||||||
//const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
|
//const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
const double childDescent=cs.getDescent();
|
const double childDescent=cs.getDescent();
|
||||||
@ -67,7 +70,7 @@ JKQTMathTextNodeSize JKQTMathTextSuperscriptNode::getSizeWithSpecialPlacement(QP
|
|||||||
s.baselineHeight=s.overallHeight=cs.overallHeight+shiftToChildBottom;
|
s.baselineHeight=s.overallHeight=cs.overallHeight+shiftToChildBottom;
|
||||||
s.width=cs.width;
|
s.width=cs.width;
|
||||||
if (prevNodeSizeForSpecialPlacement!=nullptr) s.strikeoutPos=prevNodeSizeForSpecialPlacement->strikeoutPos;
|
if (prevNodeSizeForSpecialPlacement!=nullptr) s.strikeoutPos=prevNodeSizeForSpecialPlacement->strikeoutPos;
|
||||||
else s.strikeoutPos=fm.strikeOutPos();
|
else s.strikeoutPos=JKQTMathTextGetFontStrikoutPos(fnt, painter.device());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,13 +80,15 @@ JKQTMathTextNodeSize JKQTMathTextSuperscriptNode::getSizeInternal(QPainter &pain
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextSuperscriptNode::drawWithSpecialPlacement(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSizeForSpecialPlacement) const {
|
double JKQTMathTextSuperscriptNode::drawWithSpecialPlacement(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSizeForSpecialPlacement) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSuperscriptNode[]::draw()"));
|
||||||
|
#endif
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
||||||
|
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
const QFont fnt=currentEv.getFont(parentMathText);
|
const QFont fnt=currentEv.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(fnt, painter.device());
|
|
||||||
const QRectF tbr=JKQTMathTextGetTightBoundingRect(fnt, "x", painter.device());
|
const QRectF tbr=JKQTMathTextGetTightBoundingRect(fnt, "x", painter.device());
|
||||||
const double xh=tbr.height();
|
const double xh=tbr.height();
|
||||||
//qDebug()<<"x="<<x<<" prevNodeSizeForSpecialPlacement="<<prevNodeSizeForSpecialPlacement<<" font="<<currentEv.getFont(parentMathText);
|
//qDebug()<<"x="<<x<<" prevNodeSizeForSpecialPlacement="<<prevNodeSizeForSpecialPlacement<<" font="<<currentEv.getFont(parentMathText);
|
||||||
@ -98,11 +103,14 @@ double JKQTMathTextSuperscriptNode::drawWithSpecialPlacement(QPainter& painter,
|
|||||||
|
|
||||||
double xx=x;
|
double xx=x;
|
||||||
|
|
||||||
return getChild()->draw(painter, xx, y-(shiftToChildBottom+childDescent), ev);//+0.5*fm.boundingRect("A").width();
|
return getChild()->draw(painter, xx, y-(shiftToChildBottom+childDescent), ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextSuperscriptNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
double JKQTMathTextSuperscriptNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSuperscriptNode[]::draw()"));
|
||||||
|
#endif
|
||||||
return drawWithSpecialPlacement(painter, x, y, currentEv, nullptr);
|
return drawWithSpecialPlacement(painter, x, y, currentEv, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +149,6 @@ JKQTMathTextNodeSize JKQTMathTextSubscriptNode::getSizeWithSpecialPlacement(QPai
|
|||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
||||||
const QFont f(ev.getFont(parentMathText));
|
const QFont f(ev.getFont(parentMathText));
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
//const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
|
//const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
|
||||||
|
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
@ -159,7 +166,7 @@ JKQTMathTextNodeSize JKQTMathTextSubscriptNode::getSizeWithSpecialPlacement(QPai
|
|||||||
s.baselineHeight=cs.baselineHeight-shift_to_childBaseline;
|
s.baselineHeight=cs.baselineHeight-shift_to_childBaseline;
|
||||||
s.overallHeight=cs.overallHeight;
|
s.overallHeight=cs.overallHeight;
|
||||||
if (prevNodeSizeForSpecialPlacement!=nullptr) s.strikeoutPos=prevNodeSizeForSpecialPlacement->strikeoutPos;
|
if (prevNodeSizeForSpecialPlacement!=nullptr) s.strikeoutPos=prevNodeSizeForSpecialPlacement->strikeoutPos;
|
||||||
else s.strikeoutPos=fm.strikeOutPos();
|
else s.strikeoutPos=JKQTMathTextGetFontStrikoutPos(f, painter.device());
|
||||||
s.width=cs.width;
|
s.width=cs.width;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -170,11 +177,13 @@ JKQTMathTextNodeSize JKQTMathTextSubscriptNode::getSizeInternal(QPainter &painte
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextSubscriptNode::drawWithSpecialPlacement(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSizeForSpecialPlacement) const {
|
double JKQTMathTextSubscriptNode::drawWithSpecialPlacement(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSizeForSpecialPlacement) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSubscriptNode[]::draw()"));
|
||||||
|
#endif
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
JKQTMathTextEnvironment ev=currentEv;
|
JKQTMathTextEnvironment ev=currentEv;
|
||||||
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
ev.fontSize=ev.fontSize*parentMathText->getSubsuperSizeFactor();
|
||||||
QFont f=ev.getFont(parentMathText);
|
QFont f=ev.getFont(parentMathText);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
//const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
|
//const QRectF tbr_of_letterM=JKQTMathTextGetTightBoundingRect(currentEv.getFont(parentMathText), "M", painter.device());
|
||||||
|
|
||||||
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
const JKQTMathTextNodeSize cs=getChild()->getSize(painter, ev);
|
||||||
@ -191,11 +200,14 @@ double JKQTMathTextSubscriptNode::drawWithSpecialPlacement(QPainter& painter, do
|
|||||||
//qDebug()<<"baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight<<", strikeoutPos="<<strikeoutPos;
|
//qDebug()<<"baselineHeight="<<baselineHeight<<", overallHeight="<<overallHeight<<", strikeoutPos="<<strikeoutPos;
|
||||||
//qDebug()<<"shift="<<shift<<", yshift="<<yshift;
|
//qDebug()<<"shift="<<shift<<", yshift="<<yshift;
|
||||||
double xx=x;
|
double xx=x;
|
||||||
return getChild()->draw(painter, xx, y+shift_to_childBaseline, ev);//+0.5*fm.boundingRect("A").width();
|
return getChild()->draw(painter, xx, y+shift_to_childBaseline, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextSubscriptNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
double JKQTMathTextSubscriptNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSubscriptNode[]::draw()"));
|
||||||
|
#endif
|
||||||
return drawWithSpecialPlacement(painter, x, y, currentEv, nullptr);
|
return drawWithSpecialPlacement(painter, x, y, currentEv, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -54,14 +55,17 @@ JKQTMathTextNodeSize JKQTMathTextSymbolNode::getSizeInternal(QPainter& painter,
|
|||||||
return getSymbolSize(painter, currentEv);
|
return getSymbolSize(painter, currentEv);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF JKQTMathTextSymbolNode::getBoundingRect(const QFontMetricsF &fm, const QString &text, GlobalSymbolFlags globalFlags)
|
QRectF JKQTMathTextSymbolNode::getBoundingRect(const QFont &f, const QString &text, GlobalSymbolFlags globalFlags, QPaintDevice *pd)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSymbolNode[]::getBoundingRect()"));
|
||||||
|
#endif
|
||||||
if (has(globalFlags, MakeWhitespaceHalf) && text.contains(' ')) {
|
if (has(globalFlags, MakeWhitespaceHalf) && text.contains(' ')) {
|
||||||
const QStringList str=text.simplified().trimmed().split(' ');
|
const QStringList str=text.simplified().trimmed().split(' ');
|
||||||
const QRectF brSp=fm.boundingRect("i");
|
const QRectF brSp=JKQTMathTextGetBoundingRect(f,"i",pd);
|
||||||
QRectF br;
|
QRectF br;
|
||||||
for (int i=0; i<str.size(); i++) {
|
for (int i=0; i<str.size(); i++) {
|
||||||
const QRectF lbr=fm.boundingRect(str[i]);
|
const QRectF lbr=JKQTMathTextGetBoundingRect(f,str[i],pd);
|
||||||
if (i==0) br=lbr;
|
if (i==0) br=lbr;
|
||||||
else {
|
else {
|
||||||
br.setWidth(br.width()+brSp.width()/2.0+lbr.width());
|
br.setWidth(br.width()+brSp.width()/2.0+lbr.width());
|
||||||
@ -75,18 +79,21 @@ QRectF JKQTMathTextSymbolNode::getBoundingRect(const QFontMetricsF &fm, const QS
|
|||||||
}
|
}
|
||||||
return br;
|
return br;
|
||||||
} else {
|
} else {
|
||||||
return fm.boundingRect(text);
|
return JKQTMathTextGetBoundingRect(f,text,pd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF JKQTMathTextSymbolNode::getTightBoundingRect(const QFontMetricsF &fm, const QString &text, GlobalSymbolFlags globalFlags)
|
QRectF JKQTMathTextSymbolNode::getTightBoundingRect(const QFont &f, const QString &text, GlobalSymbolFlags globalFlags, QPaintDevice* pd)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSymbolNode[]::getTightBoundingRect()"));
|
||||||
|
#endif
|
||||||
if (has(globalFlags, MakeWhitespaceHalf) && text.contains(' ')) {
|
if (has(globalFlags, MakeWhitespaceHalf) && text.contains(' ')) {
|
||||||
const QStringList str=text.simplified().trimmed().split(' ');
|
const QStringList str=text.simplified().trimmed().split(' ');
|
||||||
const QRectF brSp=fm.boundingRect("i");
|
const QRectF brSp=JKQTMathTextGetBoundingRect(f,"i",pd);
|
||||||
QRectF br;
|
QRectF br;
|
||||||
for (int i=0; i<str.size(); i++) {
|
for (int i=0; i<str.size(); i++) {
|
||||||
const QRectF lbr=fm.tightBoundingRect(str[i]);
|
const QRectF lbr=JKQTMathTextGetTightBoundingRect(f,str[i],pd);
|
||||||
if (i==0) br=lbr;
|
if (i==0) br=lbr;
|
||||||
else {
|
else {
|
||||||
br.setWidth(br.width()+brSp.width()/2.0+lbr.width());
|
br.setWidth(br.width()+brSp.width()/2.0+lbr.width());
|
||||||
@ -100,23 +107,25 @@ QRectF JKQTMathTextSymbolNode::getTightBoundingRect(const QFontMetricsF &fm, con
|
|||||||
}
|
}
|
||||||
return br;
|
return br;
|
||||||
} else {
|
} else {
|
||||||
return fm.tightBoundingRect(text);
|
return JKQTMathTextGetTightBoundingRect(f,text,pd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTMathTextSymbolNode::drawText(QPainter &p, const QString &text, GlobalSymbolFlags globalFlags, SymbolFlags symflags)
|
void JKQTMathTextSymbolNode::drawText(QPainter &p, const QString &text, GlobalSymbolFlags globalFlags, SymbolFlags symflags)
|
||||||
{
|
{
|
||||||
const QFontMetricsF fm(p.font(), p.device());
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSymbolNode[]::drawText()"));
|
||||||
|
#endif
|
||||||
if (has(globalFlags, MakeWhitespaceHalf) && text.contains(' ')) {
|
if (has(globalFlags, MakeWhitespaceHalf) && text.contains(' ')) {
|
||||||
const QStringList str=text.simplified().trimmed().split(' ');
|
const QStringList str=text.simplified().trimmed().split(' ');
|
||||||
const QRectF brSp=fm.boundingRect("i");
|
const QRectF brSp=JKQTMathTextGetBoundingRect(p.font(), "i", p.device());
|
||||||
double x=0;
|
double x=0;
|
||||||
for (int i=0; i<str.size(); i++) {
|
for (int i=0; i<str.size(); i++) {
|
||||||
p.drawText(QPointF(x,0), str[i]);
|
p.drawText(QPointF(x,0), str[i]);
|
||||||
x=x+fm.boundingRect(str[i]).width()+brSp.width()/2.0;
|
x=x+JKQTMathTextGetBoundingRect(p.font(), str[i], p.device()).width()+brSp.width()/2.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const QRectF tbr=fm.tightBoundingRect(text);
|
const QRectF tbr=JKQTMathTextGetBoundingRect(p.font(), text, p.device());
|
||||||
p.save(); auto __finalpaint=JKQTPFinally([&p]() {p.restore();});
|
p.save(); auto __finalpaint=JKQTPFinally([&p]() {p.restore();});
|
||||||
p.translate(tbr.center());
|
p.translate(tbr.center());
|
||||||
if (has(symflags, RotateSymbol90)) {
|
if (has(symflags, RotateSymbol90)) {
|
||||||
@ -138,6 +147,9 @@ void JKQTMathTextSymbolNode::drawText(QPainter &p, const QString &text, GlobalSy
|
|||||||
|
|
||||||
|
|
||||||
double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSymbolNode[]::draw()"));
|
||||||
|
#endif
|
||||||
const NodeSize s=getSymbolSize(painter, currentEv);
|
const NodeSize s=getSymbolSize(painter, currentEv);
|
||||||
doDrawBoxes(painter, x, y, s);
|
doDrawBoxes(painter, x, y, s);
|
||||||
|
|
||||||
@ -146,20 +158,18 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM
|
|||||||
const auto drawProps=fullProps.getDrawingData(currentEv, parentMathText, painter);
|
const auto drawProps=fullProps.getDrawingData(currentEv, parentMathText, painter);
|
||||||
const QFont f=drawProps.first;
|
const QFont f=drawProps.first;
|
||||||
const QFont fnonItalic=JKQTMathTextGetNonItalic(drawProps.first);
|
const QFont fnonItalic=JKQTMathTextGetNonItalic(drawProps.first);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
const QFontMetricsF fmNonItalic(fnonItalic, painter.device());
|
|
||||||
const JKQTMathTextSymbolNode::SymbolProps symprops=drawProps.second;
|
const JKQTMathTextSymbolNode::SymbolProps symprops=drawProps.second;
|
||||||
const SymbolFlags symflags=symprops.flags;
|
const SymbolFlags symflags=symprops.flags;
|
||||||
const QString sym=symprops.symbol;
|
const QString sym=symprops.symbol;
|
||||||
const QRectF tbr=getTightBoundingRect(fm, sym, globalFlags);
|
const QRectF tbr=getTightBoundingRect(f, sym, globalFlags, painter.device());
|
||||||
const QRectF tbrNonItalic=getTightBoundingRect(fmNonItalic, sym, globalFlags);
|
const QRectF tbrNonItalic=getTightBoundingRect(fnonItalic, sym, globalFlags, painter.device());
|
||||||
//const QRectF br=getBoundingRect(fm, sym, globalFlags);
|
//const QRectF br=getBoundingRect(fm, sym, globalFlags);
|
||||||
const QRectF tbrNoSymbol=JKQTMathTextGetTightBoundingRect(f, "X", painter.device());
|
const QRectF tbrNoSymbol=JKQTMathTextGetTightBoundingRect(f, "X", painter.device());
|
||||||
const double yShift=symprops.yShiftFactor*tbr.height();
|
const double yShift=symprops.yShiftFactor*tbr.height();
|
||||||
const double xShift=(s.width-tbr.width())/2.0;
|
const double xShift=(s.width-tbr.width())/2.0;
|
||||||
const QPointF x0(x+xShift-tbr.x(), y+yShift);
|
const QPointF x0(x+xShift-tbr.x(), y+yShift);
|
||||||
double italic_xcorrection=fabs(tbr.width()-tbrNonItalic.width());
|
double italic_xcorrection=fabs(tbr.width()-tbrNonItalic.width());
|
||||||
if (fabs(italic_xcorrection)<1e-6) italic_xcorrection=double(fm.boundingRect(' ').width())*0.4;
|
if (fabs(italic_xcorrection)<1e-6) italic_xcorrection=double(JKQTMathTextGetBoundingRect(f, " ", painter.device()).width())*0.4;
|
||||||
|
|
||||||
//std::cout<<"SYMB::draw(): symbolName="<<symbolName.toStdString()<<" font="<<f.family().toStdString()<<" sym="<<sym.toStdString()<<"(0x"<<std::hex<<((sym.size()==0)?uint64_t(0):uint64_t(sym[0].unicode()))<<") yShiftFactor="<<symprops.yShiftFactor<<"\n";
|
//std::cout<<"SYMB::draw(): symbolName="<<symbolName.toStdString()<<" font="<<f.family().toStdString()<<" sym="<<sym.toStdString()<<"(0x"<<std::hex<<((sym.size()==0)?uint64_t(0):uint64_t(sym[0].unicode()))<<") yShiftFactor="<<symprops.yShiftFactor<<"\n";
|
||||||
|
|
||||||
@ -173,7 +183,7 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM
|
|||||||
if (has(symflags, DrawLeftHBar) || has (symflags, DrawRightHBar)) {
|
if (has(symflags, DrawLeftHBar) || has (symflags, DrawRightHBar)) {
|
||||||
//qDebug()<<" -> DrawLeftHBar or DrawRightHBar";
|
//qDebug()<<" -> DrawLeftHBar or DrawRightHBar";
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
painter.setPen(QPen(currentEv.color, fm.lineWidth()));
|
painter.setPen(QPen(currentEv.color, JKQTMathTextGetFontLineWidth(f, painter.device())));
|
||||||
const double xh=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height();
|
const double xh=JKQTMathTextGetTightBoundingRect(f, "x", painter.device()).height();
|
||||||
const double ybar=-xh*1.1;
|
const double ybar=-xh*1.1;
|
||||||
const double deltaybar=xh*0.2;
|
const double deltaybar=xh*0.2;
|
||||||
@ -184,7 +194,7 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM
|
|||||||
if (has(symflags, DrawVertLine)) {
|
if (has(symflags, DrawVertLine)) {
|
||||||
//qDebug()<<" -> DrawVertLine";
|
//qDebug()<<" -> DrawVertLine";
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
painter.setPen(QPen(currentEv.color, fm.lineWidth()));
|
painter.setPen(QPen(currentEv.color, JKQTMathTextGetFontLineWidth(f, painter.device())));
|
||||||
const double ybar=tbr.top();
|
const double ybar=tbr.top();
|
||||||
const double xbarstart=italic_xcorrection+tbrNonItalic.width()/2.0;
|
const double xbarstart=italic_xcorrection+tbrNonItalic.width()/2.0;
|
||||||
const double xbarend=tbrNonItalic.width()/2.0;
|
const double xbarend=tbrNonItalic.width()/2.0;
|
||||||
@ -192,22 +202,16 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM
|
|||||||
}
|
}
|
||||||
if (has(symflags, DrawSlash)) {
|
if (has(symflags, DrawSlash)) {
|
||||||
//qDebug()<<" -> DrawSlash";
|
//qDebug()<<" -> DrawSlash";
|
||||||
painter.drawText(QPointF((s.width-fm.boundingRect('/').width())/2.0,0),"/");
|
painter.drawText(QPointF((s.width-JKQTMathTextGetBoundingRect(f, "/", painter.device()).width())/2.0,0),"/");
|
||||||
}
|
}
|
||||||
if (has(symflags, DrawBackSlash)) {
|
if (has(symflags, DrawBackSlash)) {
|
||||||
//qDebug()<<" -> DrawBackSlash";
|
//qDebug()<<" -> DrawBackSlash";
|
||||||
painter.drawText(QPointF((s.width-fm.boundingRect('\\').width())/2.0,0),"\\");
|
painter.drawText(QPointF((s.width-JKQTMathTextGetBoundingRect(f, "\\", painter.device()).width())/2.0,0),"\\");
|
||||||
}
|
}
|
||||||
/*painter.save();
|
|
||||||
painter.setPen(QPen(QColor("red"), 0.5, Qt::DotLine));
|
|
||||||
painter.drawEllipse(0,0,5,5);
|
|
||||||
painter.drawRect(tbr);
|
|
||||||
painter.setPen(QPen(QColor("blue"), 0.5, Qt::DashLine));
|
|
||||||
painter.drawRect(br);
|
|
||||||
painter.restore();*/
|
|
||||||
} else { // draw a box to indicate an unavailable symbol
|
} else { // draw a box to indicate an unavailable symbol
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
painter.setPen(QPen(currentEv.color, fm.lineWidth()));
|
painter.setPen(QPen(currentEv.color, JKQTMathTextGetFontLineWidth(f, painter.device())));
|
||||||
painter.drawRect(QRectF(x0.x(), x0.y()-tbrNoSymbol.height(), tbrNoSymbol.width(), tbrNoSymbol.height()));
|
painter.drawRect(QRectF(x0.x(), x0.y()-tbrNoSymbol.height(), tbrNoSymbol.width(), tbrNoSymbol.height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,18 +236,20 @@ QString JKQTMathTextSymbolNode::getSymbolName() const {
|
|||||||
|
|
||||||
JKQTMathTextSymbolNode::NodeSize JKQTMathTextSymbolNode::getSymbolSize(QPainter &painter, JKQTMathTextEnvironment currentEv) const
|
JKQTMathTextSymbolNode::NodeSize JKQTMathTextSymbolNode::getSymbolSize(QPainter &painter, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextSymbolNode[]::getSymbolSize()"));
|
||||||
|
#endif
|
||||||
NodeSize s;
|
NodeSize s;
|
||||||
|
|
||||||
const auto fullProps=symbols().value(symbolName, SymbolFullProps());
|
const auto fullProps=symbols().value(symbolName, SymbolFullProps());
|
||||||
const GlobalSymbolFlags globalFlags=fullProps.globalFlags;
|
const GlobalSymbolFlags globalFlags=fullProps.globalFlags;
|
||||||
const auto drawProps=fullProps.getDrawingData(currentEv, parentMathText, painter);
|
const auto drawProps=fullProps.getDrawingData(currentEv, parentMathText, painter);
|
||||||
const QFont f=drawProps.first;
|
const QFont f=drawProps.first;
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
const JKQTMathTextSymbolNode::SymbolProps symprops=drawProps.second;
|
const JKQTMathTextSymbolNode::SymbolProps symprops=drawProps.second;
|
||||||
const SymbolFlags symflags=symprops.flags;
|
const SymbolFlags symflags=symprops.flags;
|
||||||
const QString sym=symprops.symbol;
|
const QString sym=symprops.symbol;
|
||||||
const QRectF tbr=getTightBoundingRect(fm, sym, globalFlags);
|
const QRectF tbr=getTightBoundingRect(f, sym, globalFlags, painter.device());
|
||||||
const QRectF br=getBoundingRect(fm, sym, globalFlags);
|
const QRectF br=getBoundingRect(f, sym, globalFlags, painter.device());
|
||||||
const QRectF tbrNoSymbol=JKQTMathTextGetTightBoundingRect(f, "X", painter.device());
|
const QRectF tbrNoSymbol=JKQTMathTextGetTightBoundingRect(f, "X", painter.device());
|
||||||
const QRectF mintbr=JKQTMathTextGetTightBoundingRect(f, "(", painter.device());
|
const QRectF mintbr=JKQTMathTextGetTightBoundingRect(f, "(", painter.device());
|
||||||
const QRectF dottbr=JKQTMathTextGetTightBoundingRect(f, ".", painter.device());
|
const QRectF dottbr=JKQTMathTextGetTightBoundingRect(f, ".", painter.device());
|
||||||
@ -272,13 +278,13 @@ JKQTMathTextSymbolNode::NodeSize JKQTMathTextSymbolNode::getSymbolSize(QPainter
|
|||||||
const double oldDescent=s.overallHeight-s.baselineHeight;
|
const double oldDescent=s.overallHeight-s.baselineHeight;
|
||||||
|
|
||||||
if (has(symflags, HeightIsAscent)) {
|
if (has(symflags, HeightIsAscent)) {
|
||||||
s.baselineHeight=fm.ascent();
|
s.baselineHeight=JKQTMathTextGetFontAscent(f, painter.device());
|
||||||
s.overallHeight=s.baselineHeight+oldDescent;
|
s.overallHeight=s.baselineHeight+oldDescent;
|
||||||
}
|
}
|
||||||
if (has(symflags, RotateSymbol90)) {
|
if (has(symflags, RotateSymbol90)) {
|
||||||
s.width=qMax(s.overallHeight, s.width);
|
s.width=qMax(s.overallHeight, s.width);
|
||||||
}
|
}
|
||||||
s.strikeoutPos=fm.strikeOutPos();
|
s.strikeoutPos=JKQTMathTextGetFontStrikoutPos(f, painter.device());
|
||||||
|
|
||||||
if (has(globalFlags, IntLikeSymbolCorrection)) {
|
if (has(globalFlags, IntLikeSymbolCorrection)) {
|
||||||
if (has(globalFlags, SubSuperscriptBelowAboveSymbol)) {
|
if (has(globalFlags, SubSuperscriptBelowAboveSymbol)) {
|
||||||
@ -288,7 +294,7 @@ JKQTMathTextSymbolNode::NodeSize JKQTMathTextSymbolNode::getSymbolSize(QPainter
|
|||||||
s.topXCorrection=dottbr.width();
|
s.topXCorrection=dottbr.width();
|
||||||
}
|
}
|
||||||
if (has(globalFlags, SubscriptCorrection) && sym.size()>0) {
|
if (has(globalFlags, SubscriptCorrection) && sym.size()>0) {
|
||||||
s.baselineXCorrection=fm.rightBearing(sym[sym.size()-1]);
|
s.baselineXCorrection=JKQTMathTextGetRightBearing(f,sym[sym.size()-1],painter.device());
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@ -384,7 +390,7 @@ const QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps> &JKQTMathTextSymbo
|
|||||||
* STANDARD Symbols available in all standard fonts
|
* STANDARD Symbols available in all standard fonts
|
||||||
**************************************************************************************/
|
**************************************************************************************/
|
||||||
symbols["#"]=SimpleTextSymbol("#", "#");
|
symbols["#"]=SimpleTextSymbol("#", "#");
|
||||||
symbols["%"]=SimpleTextSymbol("%", "≫");
|
symbols["%"]=SimpleTextSymbol("%", "&percent;");
|
||||||
symbols["&"]=SimpleTextSymbol("&", "&");
|
symbols["&"]=SimpleTextSymbol("&", "&");
|
||||||
symbols["("]=SimpleUprightTextSymbol("(");
|
symbols["("]=SimpleUprightTextSymbol("(");
|
||||||
symbols[")"]=SimpleUprightTextSymbol(")");
|
symbols[")"]=SimpleUprightTextSymbol(")");
|
||||||
|
@ -156,9 +156,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
|
|||||||
friend inline bool has(GlobalSymbolFlags a, GlobalSymbolFlags b) { return (a&b)==b; }
|
friend inline bool has(GlobalSymbolFlags a, GlobalSymbolFlags b) { return (a&b)==b; }
|
||||||
|
|
||||||
/** \brief calculates the bounding rect of \a text using \a fm and taking the flags from \a globalFlags into account */
|
/** \brief calculates the bounding rect of \a text using \a fm and taking the flags from \a globalFlags into account */
|
||||||
static QRectF getBoundingRect(const QFontMetricsF& fm, const QString& text, GlobalSymbolFlags globalFlags);
|
static QRectF getBoundingRect(const QFont &fm, const QString& text, GlobalSymbolFlags globalFlags, QPaintDevice *pd);
|
||||||
/** \brief calculates the tight bounding rect of \a text using \a fm and taking the flags from \a globalFlags into account */
|
/** \brief calculates the tight bounding rect of \a text using \a fm and taking the flags from \a globalFlags into account */
|
||||||
static QRectF getTightBoundingRect(const QFontMetricsF& fm, const QString& text, GlobalSymbolFlags globalFlags);
|
static QRectF getTightBoundingRect(const QFont& fm, const QString& text, GlobalSymbolFlags globalFlags, QPaintDevice *pd);
|
||||||
/** \brief draw \a text at (0,0) using QPainter \a p and taking the flags from \a globalFlags into account */
|
/** \brief draw \a text at (0,0) using QPainter \a p and taking the flags from \a globalFlags into account */
|
||||||
static void drawText(QPainter &p, const QString &text, GlobalSymbolFlags globalFlags, SymbolFlags symflags);
|
static void drawText(QPainter &p, const QString &text, GlobalSymbolFlags globalFlags, SymbolFlags symflags);
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -141,15 +142,7 @@ JKQTMathTextTextNode::LayoutInfo JKQTMathTextTextNode::calcLayout(QPainter &pain
|
|||||||
const QFont fUpright=JKQTMathTextGetNonItalic(f);
|
const QFont fUpright=JKQTMathTextGetNonItalic(f);
|
||||||
const QFont fFallbackSym=currentEv.exchangedFontFor(MTEFallbackSymbols).getFont(parentMathText);
|
const QFont fFallbackSym=currentEv.exchangedFontFor(MTEFallbackSymbols).getFont(parentMathText);
|
||||||
const QFont fRoman=currentEv.exchangedFontForRoman().getFont(parentMathText);
|
const QFont fRoman=currentEv.exchangedFontForRoman().getFont(parentMathText);
|
||||||
const QFontMetricsF fmUpright(fUpright, painter.device());
|
const double sp=JKQTMathTextGetHorAdvance(f, " ", painter.device());
|
||||||
const QFontMetricsF fm(f, painter.device());
|
|
||||||
const QFontMetricsF fmFallbackSym(fFallbackSym, painter.device());
|
|
||||||
const QFontMetricsF fmRoman(fRoman, painter.device());
|
|
||||||
#if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0))
|
|
||||||
const double sp=fm.horizontalAdvance(' ');
|
|
||||||
#else
|
|
||||||
const double sp=fm.width(' ');
|
|
||||||
#endif
|
|
||||||
l.width=0;
|
l.width=0;
|
||||||
double ascent=0;
|
double ascent=0;
|
||||||
double descent=0;
|
double descent=0;
|
||||||
@ -160,23 +153,23 @@ JKQTMathTextTextNode::LayoutInfo JKQTMathTextTextNode::calcLayout(QPainter &pain
|
|||||||
switch(l.fontMode[i]) {
|
switch(l.fontMode[i]) {
|
||||||
case FMasDefined:
|
case FMasDefined:
|
||||||
case FMasDefinedOutline:
|
case FMasDefinedOutline:
|
||||||
br=fm.boundingRect(l.textpart[i]);
|
br=JKQTMathTextGetBoundingRect(f, l.textpart[i], painter.device());
|
||||||
tbr=JKQTMathTextGetTightBoundingRect(f, l.textpart[i], painter.device());
|
tbr=JKQTMathTextGetTightBoundingRect(f, l.textpart[i], painter.device());
|
||||||
if (f.italic() && l.textpart[i].size()>0) l.baselineXCorrection=fm.rightBearing(l.textpart[i].operator[](l.textpart[i].size()-1));
|
if (f.italic() && l.textpart[i].size()>0) l.baselineXCorrection=JKQTMathTextGetRightBearing(f,l.textpart[i].operator[](l.textpart[i].size()-1),painter.device());
|
||||||
break;
|
break;
|
||||||
case FMasDefinedForceUpright:
|
case FMasDefinedForceUpright:
|
||||||
br=fmUpright.boundingRect(l.textpart[i]);
|
br=JKQTMathTextGetBoundingRect(fUpright, l.textpart[i], painter.device());
|
||||||
tbr=JKQTMathTextGetTightBoundingRect(fUpright, l.textpart[i], painter.device());
|
tbr=JKQTMathTextGetTightBoundingRect(fUpright, l.textpart[i], painter.device());
|
||||||
break;
|
break;
|
||||||
case FMroman:
|
case FMroman:
|
||||||
br=fmRoman.boundingRect(l.textpart[i]);
|
br=JKQTMathTextGetBoundingRect(fRoman, l.textpart[i], painter.device());
|
||||||
tbr=JKQTMathTextGetTightBoundingRect(fRoman, l.textpart[i], painter.device());
|
tbr=JKQTMathTextGetTightBoundingRect(fRoman, l.textpart[i], painter.device());
|
||||||
if (fRoman.italic() && l.textpart[i].size()>0) l.baselineXCorrection=fmRoman.rightBearing(l.textpart[i].operator[](l.textpart[i].size()-1));
|
if (fRoman.italic() && l.textpart[i].size()>0) l.baselineXCorrection=JKQTMathTextGetRightBearing(fRoman,l.textpart[i].operator[](l.textpart[i].size()-1),painter.device());
|
||||||
break;
|
break;
|
||||||
case FMfallbackSymbol:
|
case FMfallbackSymbol:
|
||||||
br=fmFallbackSym.boundingRect(l.textpart[i]);
|
br=JKQTMathTextGetBoundingRect(fFallbackSym, l.textpart[i], painter.device());
|
||||||
tbr=JKQTMathTextGetTightBoundingRect(fFallbackSym, l.textpart[i], painter.device());
|
tbr=JKQTMathTextGetTightBoundingRect(fFallbackSym, l.textpart[i], painter.device());
|
||||||
if (fFallbackSym.italic() && l.textpart[i].size()>0) l.baselineXCorrection=fmFallbackSym.rightBearing(l.textpart[i].operator[](l.textpart[i].size()-1));
|
if (fFallbackSym.italic() && l.textpart[i].size()>0) l.baselineXCorrection=JKQTMathTextGetRightBearing(fFallbackSym,l.textpart[i].operator[](l.textpart[i].size()-1),painter.device());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
l.textpartXPos.append(l.width);
|
l.textpartXPos.append(l.width);
|
||||||
@ -193,7 +186,7 @@ JKQTMathTextTextNode::LayoutInfo JKQTMathTextTextNode::calcLayout(QPainter &pain
|
|||||||
}
|
}
|
||||||
l.overallHeight=(ascent+descent); //fm.height();
|
l.overallHeight=(ascent+descent); //fm.height();
|
||||||
l.baselineHeight=ascent;
|
l.baselineHeight=ascent;
|
||||||
l.strikeoutPos=fm.strikeOutPos();
|
l.strikeoutPos=JKQTMathTextGetFontStrikoutPos(f, painter.device());
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +278,9 @@ void JKQTMathTextTextNode::splitTextForLayout(QPainter &painter, JKQTMathTextEnv
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextTextNode[]::draw()"));
|
||||||
|
#endif
|
||||||
const LayoutInfo l=calcLayout(painter, currentEv);
|
const LayoutInfo l=calcLayout(painter, currentEv);
|
||||||
doDrawBoxes(painter, x, y, l);
|
doDrawBoxes(painter, x, y, l);
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -81,6 +82,9 @@ size_t JKQTMathTextVerbatimNode::getTabSize() const
|
|||||||
|
|
||||||
double JKQTMathTextVerbatimNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
double JKQTMathTextVerbatimNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextVerbatimNode[]::draw()"));
|
||||||
|
#endif
|
||||||
transformEnvironment(currentEv);
|
transformEnvironment(currentEv);
|
||||||
const LayoutInfo l=calcLayout(painter, currentEv);
|
const LayoutInfo l=calcLayout(painter, currentEv);
|
||||||
doDrawBoxes(painter, x, y, l);
|
doDrawBoxes(painter, x, y, l);
|
||||||
@ -134,10 +138,10 @@ JKQTMathTextVerbatimNode::LayoutInfo JKQTMathTextVerbatimNode::calcLayout(QPaint
|
|||||||
QFont f=currentEv.getFont(parentMathText);
|
QFont f=currentEv.getFont(parentMathText);
|
||||||
f.setStyleStrategy(QFont::PreferDefault);
|
f.setStyleStrategy(QFont::PreferDefault);
|
||||||
f.setFixedPitch(true);
|
f.setFixedPitch(true);
|
||||||
const QFontMetricsF fm(f, painter.device());
|
const qreal fascent=JKQTMathTextGetFontAscent(f, painter.device());
|
||||||
const double linespacing=fm.lineSpacing()*lineSpacingFactor;
|
const double linespacing=JKQTMathTextGetFontLineSpacing(f, painter.device())*lineSpacingFactor;
|
||||||
const double fleading=fm.leading();
|
const double fleading=JKQTMathTextGetFontLeading(f, painter.device());
|
||||||
const double synLeading=fm.lineWidth();
|
const double synLeading=JKQTMathTextGetFontLineWidth(f, painter.device());
|
||||||
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
|
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
|
||||||
|
|
||||||
if (text.size()<=0) {
|
if (text.size()<=0) {
|
||||||
@ -154,18 +158,18 @@ JKQTMathTextVerbatimNode::LayoutInfo JKQTMathTextVerbatimNode::calcLayout(QPaint
|
|||||||
for (int i=0; i<l.lines.size(); i++) {
|
for (int i=0; i<l.lines.size(); i++) {
|
||||||
|
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
heightSum=fm.ascent();
|
heightSum=fascent;
|
||||||
} else if (i>0) {
|
} else if (i>0) {
|
||||||
const double deltaLine=qMax(linespacing, descents.last()+lineLeading+fm.ascent());
|
const double deltaLine=qMax(linespacing, descents.last()+lineLeading+fascent);
|
||||||
heightSum=heightSum+deltaLine;
|
heightSum=heightSum+deltaLine;
|
||||||
y=y+deltaLine;
|
y=y+deltaLine;
|
||||||
}
|
}
|
||||||
widths<<fm.boundingRect(l.lines[i]).width();
|
widths<<JKQTMathTextGetBoundingRect(f,l.lines[i],painter.device()).width();
|
||||||
l.width=qMax(l.width, widths.last());
|
l.width=qMax(l.width, widths.last());
|
||||||
heights<<fm.height();
|
heights<<JKQTMathTextGetFontHeight(f, painter.device());
|
||||||
ascents<<fm.ascent();
|
ascents<<fascent;
|
||||||
descents<<fm.descent();
|
descents<<JKQTMathTextGetFontDescent(f, painter.device());
|
||||||
strikeouts<<fm.strikeOutPos();
|
strikeouts<<JKQTMathTextGetFontStrikoutPos(f, painter.device());
|
||||||
ysFromFirstLine<<y;
|
ysFromFirstLine<<y;
|
||||||
}
|
}
|
||||||
heightSum+=descents.last();
|
heightSum+=descents.last();
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -76,10 +77,10 @@ JKQTMathTextVerticalListNode::LayoutInfo JKQTMathTextVerticalListNode::calcLayou
|
|||||||
QList<double> ysFromFirstLine; // y-position of each line, where the first line is always at y=0 (i.e. ysFromFirstLine[0]==0)
|
QList<double> ysFromFirstLine; // y-position of each line, where the first line is always at y=0 (i.e. ysFromFirstLine[0]==0)
|
||||||
double y=0;
|
double y=0;
|
||||||
for (int i=0; i<nodes.size(); i++) {
|
for (int i=0; i<nodes.size(); i++) {
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
const double linespacing=fm.lineSpacing()*lineSpacingFactor;
|
const double linespacing=JKQTMathTextGetFontLineSpacing(f, painter.device())*lineSpacingFactor;
|
||||||
const double fleading=fm.leading();
|
const double fleading=JKQTMathTextGetFontLeading(f, painter.device());
|
||||||
const double synLeading=fm.lineWidth();
|
const double synLeading=JKQTMathTextGetFontLineWidth(f, painter.device());
|
||||||
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
|
const double lineLeading=((fabs(fleading)>1e-6)?fleading:synLeading)*lineSpacingFactor;
|
||||||
|
|
||||||
const JKQTMathTextNodeSize loc=nodes[i]->getSize(painter, currentEv);
|
const JKQTMathTextNodeSize loc=nodes[i]->getSize(painter, currentEv);
|
||||||
@ -145,6 +146,9 @@ JKQTMathTextVerticalListNode::LayoutInfo JKQTMathTextVerticalListNode::calcLayou
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextVerticalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment ev) const {
|
double JKQTMathTextVerticalListNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment ev) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextVerticalListNode[]::draw()"));
|
||||||
|
#endif
|
||||||
JKQTMathTextEnvironment currentEv=ev;
|
JKQTMathTextEnvironment currentEv=ev;
|
||||||
doDrawBoxes(painter, x, y, currentEv);
|
doDrawBoxes(painter, x, y, currentEv);
|
||||||
const LayoutInfo l=calcLayout(painter, currentEv);
|
const LayoutInfo l=calcLayout(painter, currentEv);
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include "jkqtcommon/jkqtpstringtools.h"
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpdebuggingtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -114,6 +117,9 @@ size_t JKQTMathTextWhitespaceNode::getWhitespaceCount() const
|
|||||||
|
|
||||||
double JKQTMathTextWhitespaceNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
double JKQTMathTextWhitespaceNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextWhitespaceNode[]::draw()"));
|
||||||
|
#endif
|
||||||
const JKQTMathTextNodeSize s=getSize(painter, currentEv);
|
const JKQTMathTextNodeSize s=getSize(painter, currentEv);
|
||||||
doDrawBoxes(painter, x,y,s);
|
doDrawBoxes(painter, x,y,s);
|
||||||
return x+s.width;
|
return x+s.width;
|
||||||
@ -123,11 +129,10 @@ JKQTMathTextNodeSize JKQTMathTextWhitespaceNode::getSizeInternal(QPainter &paint
|
|||||||
{
|
{
|
||||||
JKQTMathTextNodeSize s;
|
JKQTMathTextNodeSize s;
|
||||||
const double singelWidthPIX=Type2PixelWidth(whitespace.type, currentEv, painter.device());
|
const double singelWidthPIX=Type2PixelWidth(whitespace.type, currentEv, painter.device());
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
|
||||||
s.width=singelWidthPIX*static_cast<double>(whitespace.count);
|
s.width=singelWidthPIX*static_cast<double>(whitespace.count);
|
||||||
s.baselineHeight=0;
|
s.baselineHeight=0;
|
||||||
s.overallHeight=0;
|
s.overallHeight=0;
|
||||||
s.strikeoutPos=fm.strikeOutPos();
|
s.strikeoutPos=JKQTMathTextGetFontStrikoutPos(currentEv.getFont(parentMathText), painter.device());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,14 +184,9 @@ QString JKQTMathTextWhitespaceNode::Type2String(Types type)
|
|||||||
|
|
||||||
double JKQTMathTextWhitespaceNode::Type2PixelWidth(Types type, JKQTMathTextEnvironment currentEv, QPaintDevice* pd) const
|
double JKQTMathTextWhitespaceNode::Type2PixelWidth(Types type, JKQTMathTextEnvironment currentEv, QPaintDevice* pd) const
|
||||||
{
|
{
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), pd);
|
const QFont f=currentEv.getFont(parentMathText);
|
||||||
#if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0))
|
const double sp=JKQTMathTextGetHorAdvance(f, " ", pd);
|
||||||
const double em=fm.horizontalAdvance(QChar(0x2003));//currentEv.fontSize;
|
const double em=JKQTMathTextGetHorAdvance(f, QChar(0x2003), pd);
|
||||||
const double sp=fm.horizontalAdvance(' ');//currentEv.fontSize;
|
|
||||||
#else
|
|
||||||
const double em=fm.width(QChar(0x2003));//currentEv.fontSize;
|
|
||||||
const double sp=fm.width(' ');//currentEv.fontSize;
|
|
||||||
#endif
|
|
||||||
const double en=em/2.0;
|
const double en=em/2.0;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case WSTNormal: return sp;
|
case WSTNormal: return sp;
|
||||||
@ -255,13 +255,8 @@ double JKQTMathTextEmptyBoxNode::Units2PixelWidth(double value, Units unit, JKQT
|
|||||||
{
|
{
|
||||||
QFont f=currentEv.getFont(parentMathText);
|
QFont f=currentEv.getFont(parentMathText);
|
||||||
f.setStyleStrategy(QFont::PreferDefault);
|
f.setStyleStrategy(QFont::PreferDefault);
|
||||||
const QFontMetricsF fm(f, pd);
|
|
||||||
if (unit==EBUem) {
|
if (unit==EBUem) {
|
||||||
#if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0))
|
const double em=JKQTMathTextGetHorAdvance(f, QChar(0x2003), pd);
|
||||||
const double em=fm.horizontalAdvance(QChar(0x2003));//currentEv.fontSize;
|
|
||||||
#else
|
|
||||||
const double em=fm.width(QChar(0x2003));//currentEv.fontSize;
|
|
||||||
#endif
|
|
||||||
//qDebug()<<"em="<<em<<"pix";
|
//qDebug()<<"em="<<em<<"pix";
|
||||||
return value*em;
|
return value*em;
|
||||||
} else if (unit==EBUex) {
|
} else if (unit==EBUex) {
|
||||||
@ -319,6 +314,9 @@ double JKQTMathTextEmptyBoxNode::getHeight() const
|
|||||||
|
|
||||||
double JKQTMathTextEmptyBoxNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
double JKQTMathTextEmptyBoxNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextEmptyBoxNode[]::draw()"));
|
||||||
|
#endif
|
||||||
const auto s=getSize(painter, currentEv);
|
const auto s=getSize(painter, currentEv);
|
||||||
doDrawBoxes(painter, x,y,s);
|
doDrawBoxes(painter, x,y,s);
|
||||||
return x+s.width;
|
return x+s.width;
|
||||||
@ -327,7 +325,6 @@ double JKQTMathTextEmptyBoxNode::draw(QPainter &painter, double x, double y, JKQ
|
|||||||
JKQTMathTextNodeSize JKQTMathTextEmptyBoxNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
|
JKQTMathTextNodeSize JKQTMathTextEmptyBoxNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
|
||||||
{
|
{
|
||||||
JKQTMathTextNodeSize s;
|
JKQTMathTextNodeSize s;
|
||||||
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
|
|
||||||
s.width=Units2PixelWidth(width, widthUnit, currentEv, painter.device());
|
s.width=Units2PixelWidth(width, widthUnit, currentEv, painter.device());
|
||||||
s.overallHeight=Units2PixelWidth(height, heightUnit, currentEv, painter.device());
|
s.overallHeight=Units2PixelWidth(height, heightUnit, currentEv, painter.device());
|
||||||
if (height>0) {
|
if (height>0) {
|
||||||
@ -335,7 +332,7 @@ JKQTMathTextNodeSize JKQTMathTextEmptyBoxNode::getSizeInternal(QPainter &painter
|
|||||||
} else {
|
} else {
|
||||||
s.baselineHeight=0;
|
s.baselineHeight=0;
|
||||||
}
|
}
|
||||||
s.strikeoutPos=fm.strikeOutPos();
|
s.strikeoutPos=JKQTMathTextGetFontStrikoutPos(currentEv.getFont(parentMathText), painter.device());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +397,9 @@ JKQTMathTextNodeSize JKQTMathTextPhantomNode::getSizeInternal(QPainter& painter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
double JKQTMathTextPhantomNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
double JKQTMathTextPhantomNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTMathTextPhantomNode[]::draw()"));
|
||||||
|
#endif
|
||||||
const JKQTMathTextNodeSize s=getSize(painter, currentEv);
|
const JKQTMathTextNodeSize s=getSize(painter, currentEv);
|
||||||
doDrawBoxes(painter, x, y, s);
|
doDrawBoxes(painter, x, y, s);
|
||||||
return x+s.width;
|
return x+s.width;
|
||||||
|
@ -63,13 +63,15 @@ void JKQTPBaseKey::saveSettings(QSettings& settings, const QString& group) const
|
|||||||
|
|
||||||
void JKQTPBaseKey::drawKey(JKQTPEnhancedPainter &painter, const QRectF &rect, const KeySizeDescription& layout)
|
void JKQTPBaseKey::drawKey(JKQTPEnhancedPainter &painter, const QRectF &rect, const KeySizeDescription& layout)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPBaseKey[%1]::drawKey()").arg(objectName()));
|
||||||
|
#endif
|
||||||
if (!keyStyle().visible) return;
|
if (!keyStyle().visible) return;
|
||||||
|
|
||||||
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
||||||
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
||||||
const QFontMetricsF kfm(kf, painter.device());
|
const qreal Xwid=JKQTMathTextGetBoundingRect(kf,"X",painter.device()).width();
|
||||||
const qreal Xwid=kfm.boundingRect('X').width();
|
const qreal FHeight=JKQTMathTextGetFontHeight(kf, painter.device());
|
||||||
const qreal FHeight=kfm.height();
|
|
||||||
|
|
||||||
// determine layouting info and size
|
// determine layouting info and size
|
||||||
QPointF internalOffset(0,0);
|
QPointF internalOffset(0,0);
|
||||||
@ -130,6 +132,7 @@ void JKQTPBaseKey::drawKey(JKQTPEnhancedPainter &painter, const QRectF &rect, co
|
|||||||
// draw key table/contents
|
// draw key table/contents
|
||||||
x0=x0+internalOffset;
|
x0=x0+internalOffset;
|
||||||
QPointF xi=x0;
|
QPointF xi=x0;
|
||||||
|
int ic=0;
|
||||||
for (const auto& c: layout.d->columns) {
|
for (const auto& c: layout.d->columns) {
|
||||||
xi.setY(x0.y());
|
xi.setY(x0.y());
|
||||||
int ir=0;
|
int ir=0;
|
||||||
@ -137,12 +140,22 @@ void JKQTPBaseKey::drawKey(JKQTPEnhancedPainter &painter, const QRectF &rect, co
|
|||||||
const QRectF sampleRect(xi, QSizeF(keyStyle().sampleLineLength*Xwid, keyStyle().sampleHeight*FHeight));
|
const QRectF sampleRect(xi, QSizeF(keyStyle().sampleLineLength*Xwid, keyStyle().sampleHeight*FHeight));
|
||||||
const double rowHeight=layout.d->calcRowHeight(ir, sampleRect.height());
|
const double rowHeight=layout.d->calcRowHeight(ir, sampleRect.height());
|
||||||
const QRectF textRect(xi+QPointF((keyStyle().sampleLineLength+keyStyle().xSeparation)*Xwid, 0), QSize(r.size.width(), rowHeight));
|
const QRectF textRect(xi+QPointF((keyStyle().sampleLineLength+keyStyle().xSeparation)*Xwid, 0), QSize(r.size.width(), rowHeight));
|
||||||
drawEntrySample(r.id, painter, sampleRect),
|
drawEntrySample(r.id, painter, sampleRect);
|
||||||
getParentMathText()->setFontColor(keyStyle().textColor);
|
{
|
||||||
getParentMathText()->setFontPointSize(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
getParentMathText()->setFontSpecial(keyStyle().fontName);
|
JKQTPAutoOutputTimer jkaatmt(QString("JKQTPBaseKey[%1]::drawKey()::drawEntryText(r=%2,c=%3)::parse").arg(objectName()).arg(ir).arg(ic));
|
||||||
getParentMathText()->parse(r.text);
|
#endif
|
||||||
getParentMathText()->draw(painter, Qt::AlignLeft|Qt::AlignVCenter, textRect, getParent()->isDebugShowTextBoxesEnabled());
|
getParentMathText()->setFontColor(keyStyle().textColor);
|
||||||
|
getParentMathText()->setFontPointSize(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
||||||
|
getParentMathText()->setFontSpecial(keyStyle().fontName);
|
||||||
|
getParentMathText()->parse(r.text);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaatmt(QString("JKQTPBaseKey[%1]::drawKey()::drawEntryText(r=%2,c=%3)::parse").arg(objectName()).arg(ir).arg(ic));
|
||||||
|
#endif
|
||||||
|
getParentMathText()->draw(painter, Qt::AlignLeft|Qt::AlignVCenter, textRect, getParent()->isDebugShowTextBoxesEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
if (drawDebugRects) {
|
if (drawDebugRects) {
|
||||||
painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();});
|
painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
@ -160,6 +173,7 @@ void JKQTPBaseKey::drawKey(JKQTPEnhancedPainter &painter, const QRectF &rect, co
|
|||||||
ir++;
|
ir++;
|
||||||
}
|
}
|
||||||
xi.setX(xi.x()+c.calcColumnWidth(keyStyle().sampleLineLength*Xwid, keyStyle().xSeparation*Xwid)+keyStyle().columnSeparation*Xwid);
|
xi.setX(xi.x()+c.calcColumnWidth(keyStyle().sampleLineLength*Xwid, keyStyle().xSeparation*Xwid)+keyStyle().columnSeparation*Xwid);
|
||||||
|
ic++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -167,13 +181,15 @@ void JKQTPBaseKey::drawKey(JKQTPEnhancedPainter &painter, const QRectF &rect, co
|
|||||||
|
|
||||||
JKQTPBaseKey::KeySizeDescription JKQTPBaseKey::getSize(JKQTPEnhancedPainter &painter)
|
JKQTPBaseKey::KeySizeDescription JKQTPBaseKey::getSize(JKQTPEnhancedPainter &painter)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPBaseKey[%1]::getSize()").arg(objectName()));
|
||||||
|
#endif
|
||||||
KeySizeDescription size;
|
KeySizeDescription size;
|
||||||
if (!keyStyle().visible) return size;
|
if (!keyStyle().visible) return size;
|
||||||
|
|
||||||
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
||||||
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
||||||
const QFontMetricsF kfm(kf, painter.device());
|
const qreal Xwid=JKQTMathTextGetBoundingRect(kf,"X",painter.device()).width();
|
||||||
const qreal Xwid=kfm.boundingRect('X').width();
|
|
||||||
|
|
||||||
// calculate layout of the "table" of samples and labels
|
// calculate layout of the "table" of samples and labels
|
||||||
const KeyLayoutDescription layout=getKeyLayout(painter);
|
const KeyLayoutDescription layout=getKeyLayout(painter);
|
||||||
@ -190,9 +206,8 @@ void JKQTPBaseKey::calcLayoutSize(JKQTPEnhancedPainter &painter, KeySizeDescript
|
|||||||
{
|
{
|
||||||
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
||||||
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
||||||
const QFontMetricsF kfm(kf, painter.device());
|
const qreal Xwid=JKQTMathTextGetBoundingRect(kf,"X",painter.device()).width();
|
||||||
const qreal Xwid=kfm.boundingRect('X').width();
|
const qreal FHeight=JKQTMathTextGetFontHeight(kf, painter.device());
|
||||||
const qreal FHeight=kfm.height();
|
|
||||||
|
|
||||||
layout.requiredSize=extendLayoutSize(QSizeF(layout.d->calcOverallWidth(keyStyle().sampleLineLength*Xwid, keyStyle().xSeparation*Xwid, keyStyle().columnSeparation*Xwid),
|
layout.requiredSize=extendLayoutSize(QSizeF(layout.d->calcOverallWidth(keyStyle().sampleLineLength*Xwid, keyStyle().xSeparation*Xwid, keyStyle().columnSeparation*Xwid),
|
||||||
layout.d->calcOverallHeight(keyStyle().ySeparation*FHeight, keyStyle().sampleHeight*FHeight)), painter);
|
layout.d->calcOverallHeight(keyStyle().ySeparation*FHeight, keyStyle().sampleHeight*FHeight)), painter);
|
||||||
@ -207,6 +222,9 @@ void JKQTPBaseKey::calcLayoutSize(JKQTPEnhancedPainter &painter, KeySizeDescript
|
|||||||
|
|
||||||
void JKQTPBaseKey::modifySize(JKQTPEnhancedPainter &painter, KeySizeDescription ¤tKeyLayout, QSizeF preliminaryPlotSize)
|
void JKQTPBaseKey::modifySize(JKQTPEnhancedPainter &painter, KeySizeDescription ¤tKeyLayout, QSizeF preliminaryPlotSize)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPBaseKey[%1]::modifySize()").arg(objectName()));
|
||||||
|
#endif
|
||||||
const auto lay=getLayout();
|
const auto lay=getLayout();
|
||||||
if (lay==JKQTPKeyLayoutMultiColumn || lay==JKQTPKeyLayoutMultiRow) {
|
if (lay==JKQTPKeyLayoutMultiColumn || lay==JKQTPKeyLayoutMultiRow) {
|
||||||
std::function<bool(QSizeF, QSizeF)> fCompare=[](const QSizeF& requiredSize, const QSizeF& preliminaryPlotSize) {
|
std::function<bool(QSizeF, QSizeF)> fCompare=[](const QSizeF& requiredSize, const QSizeF& preliminaryPlotSize) {
|
||||||
@ -264,11 +282,13 @@ void JKQTPBaseKey::setCurrentKeyStyle(const JKQTPKeyStyle &style)
|
|||||||
|
|
||||||
JKQTPBaseKey::KeyLayoutDescription JKQTPBaseKey::getKeyLayout(JKQTPEnhancedPainter &painter)
|
JKQTPBaseKey::KeyLayoutDescription JKQTPBaseKey::getKeyLayout(JKQTPEnhancedPainter &painter)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPBaseKey[%1]::getKeyLayout()").arg(objectName()));
|
||||||
|
#endif
|
||||||
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
||||||
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
||||||
QFontMetricsF kfm(kf, painter.device());
|
//const qreal Xwid=JKQTMathTextGetBoundingRect(kf,"X",painter.device()).width();
|
||||||
//const qreal Xwid=kfm.boundingRect('X').width();
|
const qreal Fheight=JKQTMathTextGetFontHeight(kf, painter.device());
|
||||||
const qreal Fheight=kfm.height();
|
|
||||||
//const double frameWidth=qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, getParent()->pt2px(painter, keyStyle().frameWidth*getParent()->getLineWidthMultiplier()));
|
//const double frameWidth=qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, getParent()->pt2px(painter, keyStyle().frameWidth*getParent()->getLineWidthMultiplier()));
|
||||||
|
|
||||||
|
|
||||||
@ -303,10 +323,12 @@ JKQTPBaseKey::KeyLayoutDescription JKQTPBaseKey::getKeyLayout(JKQTPEnhancedPaint
|
|||||||
|
|
||||||
QSizeF JKQTPBaseKey::extendLayoutSize(QSizeF rawLayoutSize, JKQTPEnhancedPainter& painter, QPointF *offset) const
|
QSizeF JKQTPBaseKey::extendLayoutSize(QSizeF rawLayoutSize, JKQTPEnhancedPainter& painter, QPointF *offset) const
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPBaseKey[%1]::extendLayoutSize()").arg(objectName()));
|
||||||
|
#endif
|
||||||
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
QFont kf(JKQTMathTextFontSpecifier::fromFontSpec(keyStyle().fontName).fontName(), keyStyle().fontSize);
|
||||||
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
kf.setPointSizeF(keyStyle().fontSize*getParent()->getFontSizeMultiplier());
|
||||||
QFontMetricsF kfm(kf, painter.device());
|
const qreal Xwid=JKQTMathTextGetBoundingRect(kf,"X",painter.device()).width();
|
||||||
const qreal Xwid=kfm.boundingRect('X').width();
|
|
||||||
const double frameWidth=qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, getParent()->pt2px(painter, keyStyle().frameWidth*getParent()->getLineWidthMultiplier()));
|
const double frameWidth=qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, getParent()->pt2px(painter, keyStyle().frameWidth*getParent()->getLineWidthMultiplier()));
|
||||||
|
|
||||||
if (rawLayoutSize.width()>0) rawLayoutSize.setWidth(rawLayoutSize.width()+2.0*keyStyle().xMargin*Xwid+2.0*frameWidth);
|
if (rawLayoutSize.width()>0) rawLayoutSize.setWidth(rawLayoutSize.width()+2.0*keyStyle().xMargin*Xwid+2.0*frameWidth);
|
||||||
@ -531,6 +553,9 @@ QColor JKQTPMainKey::getEntryColor(int item) const
|
|||||||
|
|
||||||
void JKQTPMainKey::drawEntrySample(int item, JKQTPEnhancedPainter &painter, const QRectF &rect)
|
void JKQTPMainKey::drawEntrySample(int item, JKQTPEnhancedPainter &painter, const QRectF &rect)
|
||||||
{
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPBaseKey[%1]::drawEntrySammple(%2)").arg(objectName()).arg(item));
|
||||||
|
#endif
|
||||||
auto g=getPlotElement(item);
|
auto g=getPlotElement(item);
|
||||||
if (g) g->drawKeyMarker(painter, rect);
|
if (g) g->drawKeyMarker(painter, rect);
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 202 KiB |
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 34 KiB |
Loading…
Reference in New Issue
Block a user