MODIFIED: Synchronization of JKQTMathText and JKQTBasePlotter over threads: using read/write lockers now and removed some unnecessary mutexes by using a kind of singleton pattern

This commit is contained in:
jkriege2 2024-01-05 23:26:47 +01:00
parent 11b9ac6c8b
commit 9662ed2d69
29 changed files with 1636 additions and 1638 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

View File

@ -94,10 +94,13 @@ This test results in the following numbers (on my AMD Ryzen5 8/16-core laptop):
[comment]:RESULTS
<u><b>SERIAL RESULTS:</b></u><br/>runtime, overall = 1822.3ms<br/>single runtimes = (227.7 +/- 306.8) ms<br/>speedup = 1.00x<br/>threads / available = 1 / 16<br/><br/>
<b>VERSION:</b> 5.0.0
<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>PARALLEL RESULTS:</b></u><br/>
runtime, overall = 811.1ms<br/>single runtimes = (760.8 +/- 63.8) ms<br/>speedup = 7.50x<br/>threads / available = 8 / 16<br/><br/><b>speedup vs. serial = 2.2x</b>
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>
[comment]:RESULTS_END

View File

@ -15,6 +15,7 @@
#include "multithreaded_thread.h"
#include "jkqtmath/jkqtpstatbasics.h"
#include "jkqtpexampleapplication.h"
#include "jkqtplotter_version.h"
#define NUM_SHOWN_PLOTS 3
#define NUM_PLOTS 8
@ -129,7 +130,9 @@ int main(int argc, char* argv[])
const auto iend=md.indexOf("[comment]:RESULTS_END");
qDebug()<<" istart="<<istart<<", iend="<<iend;
if (istart>=0 && iend>istart) {
const QByteArray newResults="[comment]:RESULTS\n\n<u><b>SERIAL RESULTS:</b></u><br/>"+ser_result.toUtf8()
const QByteArray newResults="[comment]:RESULTS\n\n<b>VERSION:</b> "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_VERSION)
+"\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>PARALLEL RESULTS:</b></u><br/>\n"+par_result.toUtf8()+"\n\n";
md.replace(istart,iend-istart,newResults);
if (f.open(QFile::WriteOnly)) {

View File

@ -40,7 +40,9 @@ const int JKQTPImageTools::NDEFAULTSTEPS = 5;
QMap<int, JKQTPImageTools::LUTData > JKQTPImageTools::global_jkqtpimagetools_lutstore = JKQTPImageTools::getDefaultLUTs();
int JKQTPImageTools::global_next_userpalette = JKQTPMathImageFIRST_REGISTERED_USER_PALETTE;
std::mutex JKQTPImageTools::lutMutex;
QReadWriteLock JKQTPImageTools::lutMutex;
QStringList JKQTPImageTools::getPredefinedPalettesGlobalList = QStringList();
QStringList JKQTPImageTools::getPredefinedPalettesMachineReadableGlobalList = QStringList();
@ -2040,38 +2042,44 @@ bool JKQTPImagePlot_QPairCompareFirst(const QPair<T1, T2> &s1, const QPair<T1, T
}
QStringList JKQTPImageTools::getPredefinedPalettes() {
std::lock_guard<std::mutex> lock(JKQTPImageTools::lutMutex);
static QStringList sl;
QReadLocker lock(&JKQTPImageTools::lutMutex);
if (sl.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) {
sl.clear();
if (getPredefinedPalettesGlobalList.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) {
lock.unlock();
QWriteLocker lock(&JKQTPImageTools::lutMutex);
if (getPredefinedPalettesGlobalList.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) {
getPredefinedPalettesGlobalList.clear();
for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) {
if (it.key()>=0 && it.key()<=JKQTPMathImageLAST_POSSIBLE_REGISTERED_USER_PALETTE) {
if (it.value().nameT.size()!=0) sl<<it.value().nameT;
else if (it.value().name.size()!=0) sl<<it.value().name;
else sl<<QString(QObject::tr("Palette")+" #"+QString::number(it.key()));
if (it.value().nameT.size()!=0) getPredefinedPalettesGlobalList<<it.value().nameT;
else if (it.value().name.size()!=0) getPredefinedPalettesGlobalList<<it.value().name;
else getPredefinedPalettesGlobalList<<QString(QObject::tr("Palette")+" #"+QString::number(it.key()));
}
}
}
return sl;
}
return getPredefinedPalettesGlobalList;
}
QStringList JKQTPImageTools::getPredefinedPalettesMachineReadable() {
std::lock_guard<std::mutex> lock(JKQTPImageTools::lutMutex);
static QStringList sl;
QReadLocker lock(&JKQTPImageTools::lutMutex);
if (sl.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) {
sl.clear();
if (getPredefinedPalettesMachineReadableGlobalList.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) {
lock.unlock();
QWriteLocker lock(&JKQTPImageTools::lutMutex);
if (getPredefinedPalettesMachineReadableGlobalList.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) {
getPredefinedPalettesMachineReadableGlobalList.clear();
for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) {
if (it.key()>=0) {
if (it.value().name.size()!=0) sl<<it.value().name;
else if (it.value().nameT.size()!=0) sl<<it.value().nameT;
else sl<<QString("palette #"+QString::number(it.key()));
if (it.value().name.size()!=0) getPredefinedPalettesMachineReadableGlobalList<<it.value().name;
else if (it.value().nameT.size()!=0) getPredefinedPalettesMachineReadableGlobalList<<it.value().nameT;
else getPredefinedPalettesMachineReadableGlobalList<<QString("palette #"+QString::number(it.key()));
}
}
}
return sl;
}
return getPredefinedPalettesMachineReadableGlobalList;
}
@ -2080,7 +2088,7 @@ QStringList JKQTPImageTools::getPredefinedPalettesMachineReadable() {
QString JKQTPImageTools::JKQTPMathImageColorPalette2String(JKQTPMathImageColorPalette p)
{
std::lock_guard<std::mutex> lock(JKQTPImageTools::lutMutex);
QReadLocker lock(&JKQTPImageTools::lutMutex);
auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.find(p);
if (it==JKQTPImageTools::global_jkqtpimagetools_lutstore.end()) return QString::number(static_cast<int>(p));
else {
@ -2091,7 +2099,7 @@ QString JKQTPImageTools::JKQTPMathImageColorPalette2String(JKQTPMathImageColorPa
QString JKQTPImageTools::JKQTPMathImageColorPalette2StringHumanReadable(JKQTPMathImageColorPalette p)
{
std::lock_guard<std::mutex> lock(JKQTPImageTools::lutMutex);
QReadLocker lock(&JKQTPImageTools::lutMutex);
auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.find(p);
if (it==JKQTPImageTools::global_jkqtpimagetools_lutstore.end()) return QString::number(static_cast<int>(p));
else {
@ -2103,7 +2111,7 @@ QString JKQTPImageTools::JKQTPMathImageColorPalette2StringHumanReadable(JKQTPMat
JKQTPMathImageColorPalette JKQTPImageTools::String2JKQTPMathImageColorPalette(const QString &p)
{
std::lock_guard<std::mutex> lock(JKQTPImageTools::lutMutex);
QReadLocker lock(&JKQTPImageTools::lutMutex);
for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) {
if (QString::compare(p, it.value().name, Qt::CaseInsensitive)==0) {
return static_cast<JKQTPMathImageColorPalette>(it.key());
@ -2234,7 +2242,7 @@ QVector<QColor> JKQTPImageTools::getColorsforPalette(JKQTPMathImageColorPalette
int JKQTPImageTools::registerPalette(const QString &name, const JKQTPImageTools::LUTType &paletteLut, const QString &nameT)
{
std::lock_guard<std::mutex> lock(JKQTPImageTools::lutMutex);
QWriteLocker lock(&JKQTPImageTools::lutMutex);
int id=JKQTPImageTools::global_next_userpalette++;
JKQTPImageTools::global_jkqtpimagetools_lutstore[id].name=name;
JKQTPImageTools::global_jkqtpimagetools_lutstore[id].nameT=((nameT.size()>0)?nameT:name);

View File

@ -28,7 +28,7 @@
#include <cfloat>
#include <stdint.h>
#include <QColor>
#include <mutex>
#include <QReadWriteLock>
#include <vector>
#include "jkqtcommon/jkqtcommon_imexport.h"
#include "jkqtcommon/jkqtpmathtools.h"
@ -341,16 +341,16 @@ enum JKQTPMathImageColorPalette {
JKQTPMathImagePastel2_STEP, /*!< \image{inline} html palettes/palette_pastel2_step.png */
JKQTPMathImageSet1_STEP, /*!< \image{inline} html palettes/palette_set1_step.png */
JKQTPMathImageSet2_STEP, /*!< \image{inline} html palettes/palette_set2_step.png */
JKQTPMathImageALPHA, /*!< \brief special palette with increasing alpha values */
JKQTPMathImageINVERTED_ALPHA, /*!< \brief special palette with decreasing alpha values */
JKQTPMathImagePREDEFINED_PALETTES_COUNT, /*!< \brief the number of predefined palettes */
JKQTPMathImageUSER_PALETTE=65000, /*!< \brief special value for JKQTPImageTools::array2image(), which signals the usage of a provided user-defined palette */
JKQTPMathImageALPHA=JKQTPMathImageUSER_PALETTE-2, /*!< \brief special palette with increasing alpha values */
JKQTPMathImageINVERTED_ALPHA=JKQTPMathImageUSER_PALETTE-1, /*!< \brief special palette with decreasing alpha values */
JKQTPMathImageFIRST_REGISTERED_USER_PALETTE=JKQTPMathImagePREDEFINED_PALETTES_COUNT, /*!< \brief the ID of the first user-defined paletted, registered with JKQTPImageTools::registerPalette() or JKQTPImageTools::registerPalettesFromFile() */
JKQTPMathImageLAST_POSSIBLE_REGISTERED_USER_PALETTE=JKQTPMathImageUSER_PALETTE-10, /*!< \brief the ID of the first user-defined paletted, registered with JKQTPImageTools::registerPalette() or JKQTPImageTools::registerPalettesFromFile() */
JKQTPMathImageLAST_POSSIBLE_REGISTERED_USER_PALETTE=JKQTPMathImageUSER_PALETTE-10, /*!< \brief the ID of the last user-defined paletted, registered with JKQTPImageTools::registerPalette() or JKQTPImageTools::registerPalettesFromFile() */
};
@ -664,8 +664,12 @@ struct JKQTPImageTools {
\see registerPalette() registerPalettesFromFile()
*/
static JKQTCOMMON_LIB_EXPORT int global_next_userpalette;
/** \brief Mutex to protect global_jkqtpimagetools_lutstore and global_next_userpalette */
static JKQTCOMMON_LIB_EXPORT std::mutex lutMutex;
/** \brief storage for the palette names in getPredefinedPalettes() \internal */
static JKQTCOMMON_LIB_EXPORT QStringList getPredefinedPalettesGlobalList;
/** \brief storage for the palette names in etPredefinedPalettesMachineReadable() \internal */
static JKQTCOMMON_LIB_EXPORT QStringList getPredefinedPalettesMachineReadableGlobalList;
/** \brief Mutex to protect global_jkqtpimagetools_lutstore, getPredefinedPalettesGlobalList, getPredefinedPalettesMachineReadableGlobalList and global_next_userpalette */
static JKQTCOMMON_LIB_EXPORT QReadWriteLock lutMutex;
/*! \brief returns data of the default LUTs, used to initialize global_jkqtpimagetools_lutstore

View File

@ -25,6 +25,9 @@
#define JKQTPCONCURRENCYTOOLS_H
#include "jkqtcommon/jkqtcommon_imexport.h"
#include <QReadWriteLock>
#include <QReadLocker>
#include <QWriteLocker>
#include <mutex>
/** \brief template class that wraps any datatype and combines it with a mutex, exposes the lock()/unlock()
@ -37,9 +40,39 @@ template <class T>
class JKQTPSynchronized {
public:
/** \brief Mutex used by this temmplate */
typedef std::mutex MutexType;
/** \brief type of a lock_guard for a JKQTPSynchronized<T> */
typedef std::lock_guard<JKQTPSynchronized<T> > Locker;
typedef QReadWriteLock MutexType;
/** \brief type of AdoptLock tag, which is used in ReadLocker and WriteLocker to adopt a pre-locked JKQTPSynchronized<T> */
struct AdoptLockType { explicit AdoptLockType() = default; };
/** \brief tag, which is used in ReadLocker and WriteLocker to adopt a pre-locked JKQTPSynchronized<T> */
static constexpr AdoptLockType AdoptLock { };
/** \brief type of a lock_guard for a JKQTPSynchronized<T> for reading */
class ReadLocker
{
public:
inline ReadLocker(const JKQTPSynchronized<T> &sync) noexcept: m_sync(sync) { m_sync.lockForRead(); };
inline ReadLocker(const JKQTPSynchronized<T> &sync, AdoptLockType) noexcept : m_sync(sync) { };
inline ~ReadLocker() { m_sync.unlock(); }
private:
Q_DISABLE_COPY(ReadLocker)
const JKQTPSynchronized<T> &m_sync;
};
/** \brief type of a lock_guard for a JKQTPSynchronized<T> for writing */
class WriteLocker
{
public:
inline WriteLocker(JKQTPSynchronized<T> &sync) noexcept: m_sync(sync) { m_sync.lockForWrite(); };
inline WriteLocker(JKQTPSynchronized<T> &sync, AdoptLockType) noexcept : m_sync(sync) { };
inline ~WriteLocker() { m_sync.unlock(); }
private:
Q_DISABLE_COPY(WriteLocker)
JKQTPSynchronized<T> &m_sync;
};
/** \brief type of a lock_guard for a JKQTPSynchronized<T> for writing */
typedef JKQTPSynchronized<T>::WriteLocker Locker;
/** \brief contained data type T */
typedef T data_type;
/** \brief default constructor, the internal data is default-initialized */
@ -59,18 +92,32 @@ public:
m_data=std::move(other.m_data);
}
/** \brief locks the internal mutex until unlock() is called,
/** \brief locks the internal mutex for writing, until unlock() is called
*
* \note Use Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand!
* \note Use WriteLocker or Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand!
*/
inline void lock() {
m_mutex.lock();
inline void lock() const {
lockForWrite();
}
/** \brief unlocks the internal mutex from a previous lock() call
/** \brief locks the internal mutex for writing, until unlock() is called
*
* \note Use WriteLocker or Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand!
*/
inline void lockForWrite() const {
m_mutex.lockForWrite();
}
/** \brief locks the internal mutex for writing, until unlock() is called
*
* \note Use WriteLocker or Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand!
*/
inline void lockForRead() const {
m_mutex.lockForRead();
}
/** \brief unlocks the internal mutex from a previous lock(), lockForWrite() or lockForRead() call
*
* \note Use Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand!
*/
inline void unlock() {
inline void unlock() const {
m_mutex.unlock();
}
/** \brief assign a value to the internal data storage, <b>not thread-safe.</b>
@ -130,7 +177,7 @@ public:
/** \brief returns the value in the internal data storage, <b>thread-safe</b>.
*/
inline T get_safe() const {
Locker lck(m_mutex);
ReadLocker lck(this);
return m_data;
}

View File

@ -556,14 +556,14 @@ JKQTPSynchronized<QVector<JKQTPCustomGraphSymbolFunctor> > JKQTPlotterDrawingToo
JKQTPGraphSymbols JKQTPRegisterCustomGraphSymbol(JKQTPCustomGraphSymbolFunctor&& f)
{
JKQTPlotterDrawingTools::SymbolsLocker lock(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore);
JKQTPlotterDrawingTools::SymbolsWriteLocker lock(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore);
JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore->push_back(std::move(f));
return static_cast<JKQTPGraphSymbols>(static_cast<uint64_t>(JKQTPFirstCustomSymbol)+static_cast<uint64_t>(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore->size()-1));
}
JKQTPGraphSymbols JKQTPRegisterCustomGraphSymbol(const JKQTPCustomGraphSymbolFunctor& f)
{
JKQTPlotterDrawingTools::SymbolsLocker lock(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore);
JKQTPlotterDrawingTools::SymbolsWriteLocker lock(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore);
JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore->push_back(f);
return static_cast<JKQTPGraphSymbols>(static_cast<uint64_t>(JKQTPFirstCustomSymbol)+static_cast<uint64_t>(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore->size()-1));
}

View File

@ -87,7 +87,8 @@ struct JKQTPlotterDrawingTools {
* \internal
*/
static JKQTCOMMON_LIB_EXPORT JKQTPSynchronized<QVector<JKQTPCustomGraphSymbolFunctor> > JKQTPCustomGraphSymbolStore;
typedef JKQTPSynchronized<QVector<JKQTPCustomGraphSymbolFunctor> >::Locker SymbolsLocker;
typedef JKQTPSynchronized<QVector<JKQTPCustomGraphSymbolFunctor> >::ReadLocker SymbolsReadLocker;
typedef JKQTPSynchronized<QVector<JKQTPCustomGraphSymbolFunctor> >::WriteLocker SymbolsWriteLocker;
};
@ -982,7 +983,7 @@ inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSym
painter.drawPath(path);
}
if (symbol>=JKQTPFirstCustomSymbol) {
JKQTPlotterDrawingTools::SymbolsLocker lock(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore);
JKQTPlotterDrawingTools::SymbolsReadLocker lock(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore);
const int idx(static_cast<int>(symbol-JKQTPFirstCustomSymbol));
if (idx>=0 && idx<JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore->size()) {
painter.setPen(p);

View File

@ -29,22 +29,21 @@
#include <QFontInfo>
#include <QApplication>
#include <QFont>
#include <mutex>
void initJKQTMathTextResources()
{
static bool initialized=false;
static std::mutex mutex_initialized;
std::lock_guard<std::mutex> lock(mutex_initialized);
if (!initialized) {
static std::once_flag flag;
std::call_once(flag, []() {
#ifdef JKQTMATHTEXT_COMPILED_WITH_XITS
Q_INIT_RESOURCE(xits);
#endif
#ifdef JKQTMATHTEXT_COMPILED_WITH_FIRAMATH
Q_INIT_RESOURCE(firamath);
#endif
initialized=true;
}
);
}
JKQTMathTextFontSpecifier::JKQTMathTextFontSpecifier():
@ -234,6 +233,8 @@ bool JKQTMathTextFontSpecifier::hasFallbackSymbolFontName() const
JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getXITSFamilies()
{
initJKQTMathTextResources();
#if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb;
const auto fontFamilies=fdb.families();
@ -250,8 +251,6 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getXITSFamilies()
}
static JKQTMathTextFontSpecifier fontSpec;
static std::mutex fontSpecMutex;
std::lock_guard<std::mutex> lock(fontSpecMutex);
if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) {
fontSpec.m_transformOnOutput=false;
for (int i=0; i<fontFamilies.size(); i++) {
@ -277,6 +276,7 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getXITSFamilies()
JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getASANAFamilies()
{
static JKQTMathTextFontSpecifier fontSpec=[]() -> JKQTMathTextFontSpecifier {
initJKQTMathTextResources();
#if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb;
@ -289,10 +289,7 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getASANAFamilies()
}
static JKQTMathTextFontSpecifier fontSpec;
static std::mutex fontSpecMutex;
std::lock_guard<std::mutex> lock(fontSpecMutex);
if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) {
JKQTMathTextFontSpecifier fontSpec;
fontSpec.m_transformOnOutput=false;
for (int i=0; i<fontFamilies.size(); i++) {
if (fontFamilies.at(i).contains("Asana Math")) {
@ -310,22 +307,19 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getASANAFamilies()
fontSpec.m_fontName=fontSpec.m_mathFontName;
}
fontSpec.m_fallbackSymbolFont=fontSpec.m_mathFontName;
}
return fontSpec;
}();
return fontSpec;
}
JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getSTIXFamilies()
{
static JKQTMathTextFontSpecifier fontSpec=[]() -> JKQTMathTextFontSpecifier {
initJKQTMathTextResources();
static QStringList mathNames{"STIX Two Math", "STIX Math", "STIX Two Math Standard", "STIX Math Standard"};
static QStringList textNames{"STIX", "STIXGeneral", "STIX General"};
static JKQTMathTextFontSpecifier fontSpec;
static std::mutex fontSpecMutex;
std::lock_guard<std::mutex> lock(fontSpecMutex);
if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) {
JKQTMathTextFontSpecifier fontSpec;
fontSpec.m_transformOnOutput=false;
#if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb;
@ -365,12 +359,14 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getSTIXFamilies()
fontSpec.m_fontName=fontSpec.m_mathFontName;
}
fontSpec.m_fallbackSymbolFont=fontSpec.m_mathFontName;
}
return fontSpec;
}();
return fontSpec;
}
JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getFIRAFamilies()
{
static JKQTMathTextFontSpecifier fontSpec=[]() -> JKQTMathTextFontSpecifier {
initJKQTMathTextResources();
#if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb;
@ -382,10 +378,7 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getFIRAFamilies()
if (QFile::exists(":/JKQTMathText/fonts/FiraMath-Regular.otf")) { QFontDatabase::addApplicationFont(":/JKQTMathText/fonts/FiraMath-Regular.otf"); }
}
static JKQTMathTextFontSpecifier fontSpec;
static std::mutex fontSpecMutex;
std::lock_guard<std::mutex> lock(fontSpecMutex);
if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) {
JKQTMathTextFontSpecifier fontSpec;
fontSpec.m_transformOnOutput=false;
for (int i=0; i<fontFamilies.size(); i++) {
if (fontFamilies.at(i).contains("Fira Math")) {
@ -405,17 +398,16 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getFIRAFamilies()
fontSpec.m_fontName=fontSpec.m_mathFontName;
}
fontSpec.m_fallbackSymbolFont=fontSpec.m_mathFontName;
}
return fontSpec;
}();
return fontSpec;
}
JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getAppFontFamilies()
{
static JKQTMathTextFontSpecifier fontSpec;
static std::mutex fontSpecMutex;
std::lock_guard<std::mutex> lock(fontSpecMutex);
if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) {
static JKQTMathTextFontSpecifier fontSpec=[]() -> JKQTMathTextFontSpecifier {
JKQTMathTextFontSpecifier fontSpec;
#if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb;
const auto fontFamilies=fdb.families();
@ -448,16 +440,14 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getAppFontFamilies()
if (xits.hasMathFontName()) fontSpec.m_mathFontName=xits.mathFontName();
}
}
}
return fontSpec;
}();
return fontSpec;
}
JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getAppFontSFFamilies()
{
static JKQTMathTextFontSpecifier fontSpec;
static std::mutex fontSpecMutex;
std::lock_guard<std::mutex> lock(fontSpecMutex);
if (fontSpec.m_fontName.isEmpty() && fontSpec.m_mathFontName.isEmpty()) {
static JKQTMathTextFontSpecifier fontSpec=[]() -> JKQTMathTextFontSpecifier {
const QFont f=QGuiApplication::font().family();
QFont testFnt;
if (f.styleHint()==QFont::SansSerif) {
@ -467,7 +457,8 @@ JKQTMathTextFontSpecifier JKQTMathTextFontSpecifier::getAppFontSFFamilies()
testFnt.setStyleHint(QFont::StyleHint::SansSerif);
fontSpec.m_fontName=fontSpec.m_mathFontName=testFnt.defaultFamily();
}
}
return fontSpec;
}();
return fontSpec;
}

View File

@ -41,7 +41,7 @@
JKQTMathTextBoxInstructionNode::JKQTMathTextBoxInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
{
fillInstructions();
}
JKQTMathTextBoxInstructionNode::~JKQTMathTextBoxInstructionNode() {
@ -56,7 +56,7 @@ QString JKQTMathTextBoxInstructionNode::getTypeName() const
JKQTMathTextNodeSize JKQTMathTextBoxInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
JKQTMathTextEnvironment ev=currentEv;
const auto& inst=instructions.value(getInstructionName());
const auto& inst=instructions().value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
@ -77,7 +77,7 @@ double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;
const auto& inst=instructions.value(getInstructionName());
const auto& inst=instructions().value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
@ -111,8 +111,8 @@ double JKQTMathTextBoxInstructionNode::draw(QPainter& painter, double x, double
bool JKQTMathTextBoxInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
const auto& inst=instructions.value(getInstructionName());
const auto& inst=instructions().value(getInstructionName());
inst.modifier(ev, getParameters());
const QPen p=inst.pen(ev, getParameters(), parentMathText);
const QBrush b=inst.brush(ev, getParameters(), parentMathText);
@ -140,38 +140,32 @@ bool JKQTMathTextBoxInstructionNode::toHtml(QString &html, JKQTMathTextEnvironme
bool JKQTMathTextBoxInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}
size_t JKQTMathTextBoxInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
if (instructions().contains(instructionName)) return instructions()[instructionName].NParams;
return 0;
}
void JKQTMathTextBoxInstructionNode::modifyInMathEnvironment(const QString &instructionName, bool &insideMath, bool& insideMathTextStyle, const QStringList& params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
if (instructions().contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMath=insideMath;
ev.insideMathUseTextStyle=insideMathTextStyle;
instructions[instructionName].modifier(ev, params);
instructions()[instructionName].modifier(ev, params);
insideMath=ev.insideMath;
insideMathTextStyle=ev.insideMathUseTextStyle;
}
}
QHash<QString, JKQTMathTextBoxInstructionNode::InstructionProperties> JKQTMathTextBoxInstructionNode::instructions;
void JKQTMathTextBoxInstructionNode::fillInstructions()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
const QHash<QString, JKQTMathTextBoxInstructionNode::InstructionProperties>& JKQTMathTextBoxInstructionNode::instructions() {
static QHash<QString, JKQTMathTextBoxInstructionNode::InstructionProperties> table=[](){
QHash<QString, JKQTMathTextBoxInstructionNode::InstructionProperties> instructions;
{
InstructionProperties i(InstructionProperties::NoModification,
@ -306,8 +300,12 @@ void JKQTMathTextBoxInstructionNode::fillInstructions()
/*Nparams=*/2);
instructions["fcolorbox"] = i;
}
return instructions;
}();
return table;
}
JKQTMathTextBoxInstructionNode::InstructionProperties::ModifyEnvironmentFunctor JKQTMathTextBoxInstructionNode::InstructionProperties::NoModification=
[](JKQTMathTextEnvironment& /*ev*/, const QStringList& /*parameters*/){};

View File

@ -106,13 +106,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBoxInstructionNode: public JKQTMathTex
double roundingFactor;
};
/** \brief fills instructions
/** \brief defines all implemented instructions in this node
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
static const QHash<QString, InstructionProperties>& instructions();
};

View File

@ -108,14 +108,12 @@ QString JKQTMathTextDecoratedNode::DecorationType2String(JKQTMathTextDecoratedNo
JKQTMathTextDecoratedNode::DecorationType JKQTMathTextDecoratedNode::InstructionName2DecorationType(const QString &mode)
{
fillInstructions();
return instructions[mode];
return instructions()[mode];
}
bool JKQTMathTextDecoratedNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}
@ -168,13 +166,9 @@ JKQTMathTextNodeSize JKQTMathTextDecoratedNode::getSizeInternal(QPainter& painte
return s;
}
QHash<QString, JKQTMathTextDecoratedNode::DecorationType> JKQTMathTextDecoratedNode::instructions;
void JKQTMathTextDecoratedNode::fillInstructions()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
const QHash<QString, JKQTMathTextDecoratedNode::DecorationType>& JKQTMathTextDecoratedNode::instructions() {
static QHash<QString, JKQTMathTextDecoratedNode::DecorationType> table =[](){
QHash<QString, JKQTMathTextDecoratedNode::DecorationType> instructions;
instructions["vec"]=MTDvec;
instructions["overline"]=MTDoverline;
@ -226,6 +220,10 @@ void JKQTMathTextDecoratedNode::fillInstructions()
instructions["underrightarrow"]=MTDunderrightarrow;
instructions["underleftrightarrow"]=MTDunderleftrightarrow;
return instructions;
}();
return table;
}
double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {

View File

@ -104,9 +104,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDecoratedNode: public JKQTMathTextSing
/** \brief type of decoration that is added to the child node */
DecorationType decoration;
/** \brief lists all supported instructions */
static QHash<QString, DecorationType> instructions;
/** \brief fills instructions */
static void fillInstructions();
static const QHash<QString, DecorationType>& instructions();
};
#endif // JKQTMATHTEXTDECORATEDNODE_H

View File

@ -34,14 +34,10 @@
#include <QFont>
QHash<QString, JKQTMathTextFracNode::FracType> JKQTMathTextFracNode::instructions;
void JKQTMathTextFracNode::fillInstructions()
const QHash<QString, JKQTMathTextFracNode::FracType>& JKQTMathTextFracNode::instructions() {
static QHash<QString, JKQTMathTextFracNode::FracType> table=[]()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
QHash<QString, JKQTMathTextFracNode::FracType> instructions;
instructions["frac"]=MTFMfrac;
instructions["dfrac"] = MTFMdfrac;
instructions["cfrac"]=MTFMdfrac;
@ -60,12 +56,14 @@ void JKQTMathTextFracNode::fillInstructions()
instructions["overbrace"]=MTFMoverbrace;
instructions["overbracket"]=MTFMoverbracket;
instructions["overset"]=MTFMoverset;
return instructions;
}();
return table;
}
QString JKQTMathTextFracNode::FracType2String(JKQTMathTextFracNode::FracType mode)
{
switch(mode) {
@ -99,14 +97,12 @@ QString JKQTMathTextFracNode::FracType2String(JKQTMathTextFracNode::FracType mod
JKQTMathTextFracNode::FracType JKQTMathTextFracNode::InstructionName2FracType(const QString &mode)
{
fillInstructions();
return instructions.value(mode, MTFMfrac);
return instructions().value(mode, MTFMfrac);
}
bool JKQTMathTextFracNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}

View File

@ -90,9 +90,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFracNode: public JKQTMathTextDualChild
JKQTMathTextFracNode::FracType getMode() const;
protected:
/** \brief lists all supported instructions */
static QHash<QString, FracType> instructions;
/** \brief fills instructions */
static void fillInstructions();
static const QHash<QString, FracType>& instructions();
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief actual display type of fraction object */

View File

@ -64,7 +64,6 @@ JKQTMathTextSimpleInstructionNode::JKQTMathTextSimpleInstructionNode(JKQTMathTex
instructionName(_name),
parameters(_parameters)
{
fillInstructions();
}
@ -81,7 +80,6 @@ QString JKQTMathTextSimpleInstructionNode::getTypeName() const
double JKQTMathTextSimpleInstructionNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv) const
{
doDrawBoxes(painter, x, y, currentEv);
fillInstructions();
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
const QFontMetricsF fm(f, painter.device());
@ -95,7 +93,6 @@ double JKQTMathTextSimpleInstructionNode::draw(QPainter &painter, double x, doub
bool JKQTMathTextSimpleInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const
{
fillInstructions();
const QString txt=executeInstruction();
html+=txt;
return true;
@ -113,20 +110,17 @@ const QStringList &JKQTMathTextSimpleInstructionNode::getParameters() const
bool JKQTMathTextSimpleInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}
size_t JKQTMathTextSimpleInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
if (instructions().contains(instructionName)) return instructions()[instructionName].NParams;
return 0;
}
JKQTMathTextNodeSize JKQTMathTextSimpleInstructionNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv) const
{
fillInstructions();
QFont f=currentEv.getFont(parentMathText);
f.setStyleStrategy(QFont::PreferDefault);
const QFontMetricsF fm(f, painter.device());
@ -140,13 +134,10 @@ JKQTMathTextNodeSize JKQTMathTextSimpleInstructionNode::getSizeInternal(QPainter
return s;
}
QHash<QString, JKQTMathTextSimpleInstructionNode::InstructionProperties> JKQTMathTextSimpleInstructionNode::instructions;
void JKQTMathTextSimpleInstructionNode::fillInstructions()
const QHash<QString, JKQTMathTextSimpleInstructionNode::InstructionProperties>& JKQTMathTextSimpleInstructionNode::instructions() {
static QHash<QString, JKQTMathTextSimpleInstructionNode::InstructionProperties> table=[]()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
QHash<QString, JKQTMathTextSimpleInstructionNode::InstructionProperties> instructions;
{
InstructionProperties i([](const QStringList& parameters) -> QString {
bool ok=false;
@ -175,12 +166,14 @@ void JKQTMathTextSimpleInstructionNode::fillInstructions()
}, 1);
instructions["utfeight"]= i;
}
return instructions;
}();
return table;
}
QString JKQTMathTextSimpleInstructionNode::executeInstruction() const
{
fillInstructions();
return instructions.value(getInstructionName(), InstructionProperties()).evaluator(getParameters());
return instructions().value(getInstructionName(), InstructionProperties()).evaluator(getParameters());
}
JKQTMathTextSimpleInstructionNode::InstructionProperties::InstructionProperties():

View File

@ -103,14 +103,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSimpleInstructionNode: public JKQTMath
/** \brief output of the instruction */
EvaluateInstructionFunctor evaluator;
};
/** \brief fills instructions
/** \brief defines all implemented instructions in this node
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
static const QHash<QString, InstructionProperties>& instructions();
/** \brief executes the instruction on \a ev */
QString executeInstruction() const;
/** \brief instruction name */

View File

@ -38,7 +38,6 @@
JKQTMathTextModifiedTextPropsInstructionNode::JKQTMathTextModifiedTextPropsInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
{
fillInstructions();
}
JKQTMathTextModifiedTextPropsInstructionNode::~JKQTMathTextModifiedTextPropsInstructionNode() {
@ -51,7 +50,6 @@ QString JKQTMathTextModifiedTextPropsInstructionNode::getTypeName() const
}
JKQTMathTextNodeSize JKQTMathTextModifiedTextPropsInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
JKQTMathTextEnvironment ev=currentEv;
executeInstruction(ev);
@ -60,7 +58,6 @@ JKQTMathTextNodeSize JKQTMathTextModifiedTextPropsInstructionNode::getSizeIntern
}
double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;
@ -71,7 +68,6 @@ double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, dou
bool JKQTMathTextModifiedTextPropsInstructionNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
executeInstruction(ev);
return getChild()->toHtml(html, ev, defaultEv);
@ -79,25 +75,22 @@ bool JKQTMathTextModifiedTextPropsInstructionNode::toHtml(QString &html, JKQTMat
bool JKQTMathTextModifiedTextPropsInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}
size_t JKQTMathTextModifiedTextPropsInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
if (instructions().contains(instructionName)) return instructions()[instructionName].NParams;
return 0;
}
void JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(const QString &instructionName, bool &insideMath, bool& insideMathTextStyle, const QStringList& params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
if (instructions().contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMath=insideMath;
ev.insideMathUseTextStyle=insideMathTextStyle;
instructions[instructionName].modifier(ev, params);
instructions()[instructionName].modifier(ev, params);
insideMath=ev.insideMath;
insideMathTextStyle=ev.insideMathUseTextStyle;
}
@ -106,18 +99,14 @@ void JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(const
void JKQTMathTextModifiedTextPropsInstructionNode::executeInstruction(JKQTMathTextEnvironment &ev) const
{
fillInstructions();
instructions.value(getInstructionName(), InstructionProperties()).modifier(ev, getParameters());
instructions().value(getInstructionName(), InstructionProperties()).modifier(ev, getParameters());
}
QHash<QString, JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties> JKQTMathTextModifiedTextPropsInstructionNode::instructions;
void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
const QHash<QString, JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties>& JKQTMathTextModifiedTextPropsInstructionNode::instructions() {
static QHash<QString, JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties> table=[]()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
QHash<QString, JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties> instructions;
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.bold=false;
@ -456,6 +445,9 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
}, 0);
instructions["Biggsize"]= i;
}
return instructions;
}();
return table;
}
JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties():
@ -479,7 +471,6 @@ JKQTMathTextModifiedEnvironmentInstructionNode::JKQTMathTextModifiedEnvironmentI
instructionName(name_),
parameters(parameters_)
{
fillInstructions();
}
JKQTMathTextModifiedEnvironmentInstructionNode::~JKQTMathTextModifiedEnvironmentInstructionNode()
@ -504,41 +495,33 @@ const QStringList &JKQTMathTextModifiedEnvironmentInstructionNode::getParameters
void JKQTMathTextModifiedEnvironmentInstructionNode::modifyEnvironment(JKQTMathTextEnvironment &currentEv) const
{
fillInstructions();
instructions.value(getInstructionName(), InstructionProperties()).modifier(currentEv, getParameters(), parentMathText);
instructions().value(getInstructionName(), InstructionProperties()).modifier(currentEv, getParameters(), parentMathText);
}
bool JKQTMathTextModifiedEnvironmentInstructionNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}
size_t JKQTMathTextModifiedEnvironmentInstructionNode::countParametersOfInstruction(const QString &instructionName)
{
fillInstructions();
if (instructions.contains(instructionName)) return instructions[instructionName].NParams;
if (instructions().contains(instructionName)) return instructions()[instructionName].NParams;
return 0;
}
void JKQTMathTextModifiedEnvironmentInstructionNode::modifyInMathTextStyleEnvironment(const QString &instructionName, bool &insideMathTextStyle, JKQTMathText* parentMathText, const QStringList &params)
{
fillInstructions();
if (instructions.contains(instructionName)) {
if (instructions().contains(instructionName)) {
JKQTMathTextEnvironment ev;
ev.insideMathUseTextStyle=insideMathTextStyle;
instructions[instructionName].modifier(ev, params, parentMathText);
instructions()[instructionName].modifier(ev, params, parentMathText);
insideMathTextStyle=ev.insideMathUseTextStyle;
}
}
QHash<QString, JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties> JKQTMathTextModifiedEnvironmentInstructionNode::instructions;
void JKQTMathTextModifiedEnvironmentInstructionNode::fillInstructions()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
const QHash<QString, JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties>& JKQTMathTextModifiedEnvironmentInstructionNode::instructions() {
static QHash<QString, JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties> table=[](){
QHash<QString, JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties> instructions;
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/, const JKQTMathText* parentMathText) {
@ -819,8 +802,9 @@ void JKQTMathTextModifiedEnvironmentInstructionNode::fillInstructions()
instructions["userfontsize"]= i;
instructions["fontsize"]= i;
}
return instructions;
}();
return table;
}
JKQTMathTextModifiedEnvironmentInstructionNode::InstructionProperties::InstructionProperties():

View File

@ -53,15 +53,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedTextPropsInstructionNode: publ
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
* \see instructions()
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
* \see instructions()
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMath to \c true if inside the node is to be parsed in math mode and \c false else
* \see instructions
* \see instructions()
*/
static void modifyInMathEnvironment(const QString& instructionName, bool& insideMath, bool &insideMathTextStyle, const QStringList &params=QStringList());
@ -82,13 +82,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedTextPropsInstructionNode: publ
ModifyEnvironmentFunctor modifier;
};
/** \brief fills instructions
/** \brief defines all implemented instructions in this node
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
static const QHash<QString, InstructionProperties>& instructions();
/** \brief executes the instruction on \a ev */
void executeInstruction(JKQTMathTextEnvironment& ev) const;
};
@ -116,15 +114,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedEnvironmentInstructionNode: pu
virtual void modifyEnvironment(JKQTMathTextEnvironment& currentEv) const override;
/** \brief returns true, if the given \a instructionName can be represented by this node
* \see instructions
* \see instructions()
*/
static bool supportsInstructionName(const QString& instructionName);
/** \brief returns the number of additional string parameters, required for the given \a instructionName
* \see instructions
* \see instructions()
*/
static size_t countParametersOfInstruction(const QString& instructionName);
/** \brief sets \a insideMathTextStyle to \c true if textstyle is set inside math
* \see instructions
* \see instructions()
*/
static void modifyInMathTextStyleEnvironment(const QString& instructionName, bool &insideMathTextStyle, JKQTMathText *parentMathText, const QStringList &params=QStringList());
protected:
@ -146,13 +144,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextModifiedEnvironmentInstructionNode: pu
ModifyEnvironmentFunctor modifier;
};
/** \brief fills instructions
/** \brief defines all implemented instructions in this node
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, InstructionProperties> instructions;
static const QHash<QString, InstructionProperties>& instructions();
};

View File

@ -38,7 +38,6 @@
JKQTMathTextSymbolNode::JKQTMathTextSymbolNode(JKQTMathText* _parent, const QString& name):
JKQTMathTextNode(_parent), symbolName(name)
{
fillSymbolTables();
}
JKQTMathTextSymbolNode::~JKQTMathTextSymbolNode() {
@ -142,7 +141,7 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM
const NodeSize s=getSymbolSize(painter, currentEv);
doDrawBoxes(painter, x, y, s);
const auto fullProps=symbols.value(symbolName, SymbolFullProps());
const auto fullProps=symbols().value(symbolName, SymbolFullProps());
const GlobalSymbolFlags globalFlags=fullProps.globalFlags;
const auto drawProps=fullProps.getDrawingData(currentEv, parentMathText, painter);
const QFont f=drawProps.first;
@ -217,7 +216,7 @@ double JKQTMathTextSymbolNode::draw(QPainter& painter, double x, double y, JKQTM
bool JKQTMathTextSymbolNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
bool ok=true;
const auto props=symbols.value(symbolName, SymbolFullProps());
const auto props=symbols().value(symbolName, SymbolFullProps());
QString s=props.html.symbol;
JKQTMathTextEnvironment ev=currentEv;
ev.fontSize=ev.fontSize*props.html.fontScalingFactor;
@ -235,7 +234,7 @@ JKQTMathTextSymbolNode::NodeSize JKQTMathTextSymbolNode::getSymbolSize(QPainter
{
NodeSize s;
const auto fullProps=symbols.value(symbolName, SymbolFullProps());
const auto fullProps=symbols().value(symbolName, SymbolFullProps());
const GlobalSymbolFlags globalFlags=fullProps.globalFlags;
const auto drawProps=fullProps.getDrawingData(currentEv, parentMathText, painter);
const QFont f=drawProps.first;
@ -297,39 +296,34 @@ JKQTMathTextSymbolNode::NodeSize JKQTMathTextSymbolNode::getSymbolSize(QPainter
bool JKQTMathTextSymbolNode::hasSymbol(const QString &symbolName)
{
fillSymbolTables();
return symbols.contains(symbolName);
return symbols().contains(symbolName);
}
QStringList JKQTMathTextSymbolNode::getSymbols()
{
fillSymbolTables();
return symbols.keys();
return symbols().keys();
}
bool JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(const QString &symbolName)
{
fillSymbolTables();
if (symbols.contains(symbolName)) {
return has(symbols[symbolName].globalFlags, SubSuperscriptBelowAboveSymbol);
if (symbols().contains(symbolName)) {
return has(symbols()[symbolName].globalFlags, SubSuperscriptBelowAboveSymbol);
}
return false;
}
bool JKQTMathTextSymbolNode::isExtendedWidthSymbol(const QString &symbolName)
{
fillSymbolTables();
if (symbols.contains(symbolName)) {
return has(symbols[symbolName].globalFlags, ExtendWidthInMathmode) || has(symbols[symbolName].globalFlags, SmallExtendWidthInMathmode);
if (symbols().contains(symbolName)) {
return has(symbols()[symbolName].globalFlags, ExtendWidthInMathmode) || has(symbols()[symbolName].globalFlags, SmallExtendWidthInMathmode);
}
return false;
}
int JKQTMathTextSymbolNode::getSymbolLength(const QString &symbolName)
{
fillSymbolTables();
if (symbols.contains(symbolName)) {
return symbols[symbolName].props.value(MTFEUnicode, symbols[symbolName].props.value(MTFEStandard, SymbolProps())).symbol.size();
if (symbols().contains(symbolName)) {
return symbols()[symbolName].props.value(MTFEUnicode, symbols()[symbolName].props.value(MTFEStandard, SymbolProps())).symbol.size();
}
return 0;
}
@ -381,120 +375,10 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperat
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0)).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf).addHtml(ophtml, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorSymbolUnicode(const QString &unicode)
const QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps> &JKQTMathTextSymbolNode::symbols()
{
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolUnicode(const QString &unicode)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolStd(const QString &symbol)
{
return NarrowMathOperatorSymbolStd(symbol,symbol);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolStd(const QString &symbol, const QString &symbolHTML)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff|BoldOff, 1.0, 0.0)).addHtml(symbol, ItalicOff|BoldOff, 1.0, 0.0).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathGreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(letterUnicode, ItalicOn), MTFEWinSymbol, SymbolProps(letterWinSymbol, ItalicOn), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::AsOutsiudeGreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(letterUnicode, AsOutside), MTFEWinSymbol, SymbolProps(letterWinSymbol, AsOutside), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightGreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(letterUnicode, ItalicOff), MTFEWinSymbol, SymbolProps(letterWinSymbol, ItalicOff), html, ItalicOff);
}
void JKQTMathTextSymbolNode::addGreekLetterVariants_WinSymbol_Unicode_Html(const QString &baseInstructionName, const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
symbols[baseInstructionName]=MathGreekLetter_WinSymbol_Unicode_Html(letterWinSymbol, letterUnicode, html).addGlobalFlags(SubscriptCorrection);
symbols["text"+baseInstructionName]=AsOutsiudeGreekLetter_WinSymbol_Unicode_Html(letterWinSymbol, letterUnicode, html);
symbols["up"+baseInstructionName]=UprightGreekLetter_WinSymbol_Unicode_Html(letterWinSymbol, letterUnicode, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::StdSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UnicodeSymbol(const QString &symbol, SymbolFlags _flags, double _fontScalingFactor, double _yShiftFactor)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor));
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolStd(const QString &symbol)
{
QString html=symbol;
return UprightSymbolStd(symbol, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UnicodeSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::StdSymbol(const QString &symbol, SymbolFlags _flags, double _fontScalingFactor, double _yShiftFactor)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor), symbol);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolStd(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolUnicode(const QString &symbol)
{
QString html=symbol;
return UprightSymbolUnicode(symbol, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolUnicode(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleTextSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleTextSymbol(const QString &symbol, SymbolFlags _flags, double _fontScalingFactor, double _yShiftFactor)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor), symbol);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleUprightTextSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleUprightTextSymbol(const QString &symbol)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), symbol, ItalicOff);
}
QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps> JKQTMathTextSymbolNode::symbols=QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps>();
void JKQTMathTextSymbolNode::fillSymbolTables()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (symbols.size()>0) return; // tables have already been filled! So nothing to do here
static QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps> s_symbols=[](){
QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps> symbols;
/**************************************************************************************
* STANDARD Symbols available in all standard fonts
@ -860,46 +744,46 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
/**************************************************************************************
* GREEK letters
**************************************************************************************/
addGreekLetterVariants_WinSymbol_Unicode_Html("alpha", "a", QChar(0x3B1), "&alpha;");
addGreekLetterVariants_WinSymbol_Unicode_Html("beta", "b", QChar(0x3B2), "&beta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("gamma", "g", QChar(0x3B3), "&gamma;");
addGreekLetterVariants_WinSymbol_Unicode_Html("delta", "d", QChar(0x3B4), "&delta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("epsilon", "e", QChar(0x3F5), "&varepsilon;");
addGreekLetterVariants_WinSymbol_Unicode_Html("varepsilon", "e", QChar(0x3B5), "&epsi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("zeta", "z", QChar(0x3B6),"&zeta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("eta", "h", QChar(0x3B7),"&eta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("theta", "q", QChar(0x3B8),"&theta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("vartheta", "J", QChar(0x3D1),"&thetasym;");
addGreekLetterVariants_WinSymbol_Unicode_Html("iota", "i", QChar(0x3B9),"&iota;");
addGreekLetterVariants_WinSymbol_Unicode_Html("kappa", "k", QChar(0x3BA),"&kappa;");
addGreekLetterVariants_WinSymbol_Unicode_Html("lambda", "l", QChar(0x3BB),"&lambda;");
addGreekLetterVariants_WinSymbol_Unicode_Html("mu", "m", QChar(0x3BC),"&mu;");
addGreekLetterVariants_WinSymbol_Unicode_Html("nu", "n", QChar(0x3BD),"&nu;");
addGreekLetterVariants_WinSymbol_Unicode_Html("xi", "x", QChar(0x3BE),"&xi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("pi", "p", QChar(0x3C0),"&pi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("varpi", "v", QChar(0x3D6),"&piv;");
addGreekLetterVariants_WinSymbol_Unicode_Html("rho", "r", QChar(0x3C1),"&rho;");
addGreekLetterVariants_WinSymbol_Unicode_Html("varrho", "r", QChar(0x3F1),"&varrho;");
addGreekLetterVariants_WinSymbol_Unicode_Html("sigma", "s", QChar(0x3C3),"&sigma;");
addGreekLetterVariants_WinSymbol_Unicode_Html("varsigma", "V", QChar(0x3C2),"&varsigma;");
addGreekLetterVariants_WinSymbol_Unicode_Html("tau", "t", QChar(0x3C4),"&tau;");
addGreekLetterVariants_WinSymbol_Unicode_Html("upsilon", "u", QChar(0x3C5),"&upsilon;");
addGreekLetterVariants_WinSymbol_Unicode_Html("phi", "f", QChar(0x3C5),"&straightphi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("varphi", "j", QChar(0x3D6),"&phi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("chi", "c", QChar(0x3C7),"&chi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("psi", "y", QChar(0x3C8),"&psi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("omega", "w", QChar(0x3C9),"&omega;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Gamma", "G", QChar(0x3A3),"&Gamma;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Delta", "D", QChar(0x394),"&Delta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Theta", "Q", QChar(0x398),"&Theta;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Lambda", "L", QChar(0x39B),"&Lambda;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Omega", "W", QChar(0x3A9),"&Omega;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Xi", "X", QChar(0x39E),"&Xi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Pi", "P", QChar(0x3A0),"&Pi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Sigma", "S", QChar(0x3A3),"&Sigma;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Upsilon", "U", QChar(0x3C6),"&Upsilon;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Phi", "F", QChar(0x3A6),"&Phi;");
addGreekLetterVariants_WinSymbol_Unicode_Html("Psi", "Y", QChar(0x3A8),"&Psi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "alpha", "a", QChar(0x3B1), "&alpha;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "beta", "b", QChar(0x3B2), "&beta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "gamma", "g", QChar(0x3B3), "&gamma;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "delta", "d", QChar(0x3B4), "&delta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "epsilon", "e", QChar(0x3F5), "&varepsilon;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "varepsilon", "e", QChar(0x3B5), "&epsi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "zeta", "z", QChar(0x3B6),"&zeta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "eta", "h", QChar(0x3B7),"&eta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "theta", "q", QChar(0x3B8),"&theta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "vartheta", "J", QChar(0x3D1),"&thetasym;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "iota", "i", QChar(0x3B9),"&iota;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "kappa", "k", QChar(0x3BA),"&kappa;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "lambda", "l", QChar(0x3BB),"&lambda;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "mu", "m", QChar(0x3BC),"&mu;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "nu", "n", QChar(0x3BD),"&nu;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "xi", "x", QChar(0x3BE),"&xi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "pi", "p", QChar(0x3C0),"&pi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "varpi", "v", QChar(0x3D6),"&piv;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "rho", "r", QChar(0x3C1),"&rho;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "varrho", "r", QChar(0x3F1),"&varrho;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "sigma", "s", QChar(0x3C3),"&sigma;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "varsigma", "V", QChar(0x3C2),"&varsigma;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "tau", "t", QChar(0x3C4),"&tau;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "upsilon", "u", QChar(0x3C5),"&upsilon;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "phi", "f", QChar(0x3C5),"&straightphi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "varphi", "j", QChar(0x3D6),"&phi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "chi", "c", QChar(0x3C7),"&chi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "psi", "y", QChar(0x3C8),"&psi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "omega", "w", QChar(0x3C9),"&omega;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Gamma", "G", QChar(0x3A3),"&Gamma;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Delta", "D", QChar(0x394),"&Delta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Theta", "Q", QChar(0x398),"&Theta;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Lambda", "L", QChar(0x39B),"&Lambda;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Omega", "W", QChar(0x3A9),"&Omega;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Xi", "X", QChar(0x39E),"&Xi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Pi", "P", QChar(0x3A0),"&Pi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Sigma", "S", QChar(0x3A3),"&Sigma;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Upsilon", "U", QChar(0x3C6),"&Upsilon;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Phi", "F", QChar(0x3A6),"&Phi;");
addGreekLetterVariants_WinSymbol_Unicode_Html(symbols, "Psi", "Y", QChar(0x3A8),"&Psi;");
/**************************************************************************************
@ -918,8 +802,121 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["righthand"]=s; symbols["HandLeft"]=s;}
}
return symbols;
}();
return s_symbols;
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorSymbolUnicode(const QString &unicode)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolUnicode(const QString &unicode)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolStd(const QString &symbol)
{
return NarrowMathOperatorSymbolStd(symbol,symbol);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolStd(const QString &symbol, const QString &symbolHTML)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff|BoldOff, 1.0, 0.0)).addHtml(symbol, ItalicOff|BoldOff, 1.0, 0.0).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathGreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(letterUnicode, ItalicOn), MTFEWinSymbol, SymbolProps(letterWinSymbol, ItalicOn), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::AsOutsiudeGreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(letterUnicode, AsOutside), MTFEWinSymbol, SymbolProps(letterWinSymbol, AsOutside), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightGreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(letterUnicode, ItalicOff), MTFEWinSymbol, SymbolProps(letterWinSymbol, ItalicOff), html, ItalicOff);
}
void JKQTMathTextSymbolNode::addGreekLetterVariants_WinSymbol_Unicode_Html(QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps>& symbols, const QString &baseInstructionName, const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
{
symbols[baseInstructionName]=MathGreekLetter_WinSymbol_Unicode_Html(letterWinSymbol, letterUnicode, html).addGlobalFlags(SubscriptCorrection);
symbols["text"+baseInstructionName]=AsOutsiudeGreekLetter_WinSymbol_Unicode_Html(letterWinSymbol, letterUnicode, html);
symbols["up"+baseInstructionName]=UprightGreekLetter_WinSymbol_Unicode_Html(letterWinSymbol, letterUnicode, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::StdSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UnicodeSymbol(const QString &symbol, SymbolFlags _flags, double _fontScalingFactor, double _yShiftFactor)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor));
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolStd(const QString &symbol)
{
QString html=symbol;
return UprightSymbolStd(symbol, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UnicodeSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::StdSymbol(const QString &symbol, SymbolFlags _flags, double _fontScalingFactor, double _yShiftFactor)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor), symbol);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolStd(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolUnicode(const QString &symbol)
{
QString html=symbol;
return UprightSymbolUnicode(symbol, html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::UprightSymbolUnicode(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleTextSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol), html);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleTextSymbol(const QString &symbol, SymbolFlags _flags, double _fontScalingFactor, double _yShiftFactor)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, _flags, _fontScalingFactor, _yShiftFactor), symbol);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleUprightTextSymbol(const QString &symbol, const QString &html)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), html, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::SimpleUprightTextSymbol(const QString &symbol)
{
return SymbolFullProps(MTFEStandard, SymbolProps(symbol, ItalicOff), symbol, ItalicOff);
}
JKQTMathTextSymbolNode::SymbolFullProps::SymbolFullProps():
fontType(MTECurrentFont),

View File

@ -274,7 +274,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
/** \brief constructs a SymbolProps for a greek letter with the format from outside with the symbol in unicode-encoding \a letterUnicode and in WinSymbol-encoding letterWinWsymbol */
static SymbolFullProps AsOutsiudeGreekLetter_WinSymbol_Unicode_Html(const QString& letterWinSymbol, const QString& letterUnicode, const QString& html);
/** \brief insert GreekLetter_WinSymbol_Unicode_Html() as \a baseInstructionName and UprightGreekLetter_WinSymbol_Unicode_Html and "up"+\a letterWinSymbol into symbols */
static void addGreekLetterVariants_WinSymbol_Unicode_Html(const QString& baseInstructionName, const QString& letterWinSymbol, const QString& letterUnicode, const QString& html);
static void addGreekLetterVariants_WinSymbol_Unicode_Html(QHash<QString, JKQTMathTextSymbolNode::SymbolFullProps>& symbols,const QString& baseInstructionName, const QString& letterWinSymbol, const QString& letterUnicode, const QString& html);
/** \brief constructs a SymbolProps for a symbol with encoding in Standard-fonts a */
static SymbolFullProps StdSymbol(const QString& symbol, const QString& html);
/** \brief constructs a SymbolProps for a symbol with encoding in UnicodeFull-fonts a */
@ -306,10 +306,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
/** \brief symbols that can be generated in any standard-font */
static QHash<QString, SymbolFullProps> symbols;
/** \brief fill the symbol tables standardTextSymbols, winSymbolSymbol, ... with contents */
static void fillSymbolTables();
static const QHash<QString, SymbolFullProps>& symbols();
/** \brief retrieve the properties to render the given symbol \a symName in the current environment \a currentEv */
SymbolFullProps getSymbolProp(const QString& symName, const JKQTMathTextEnvironment& currentEv) const;

View File

@ -73,21 +73,20 @@ bool JKQTMathTextTextBaseNode::toHtml(QString &html, JKQTMathTextEnvironment cur
QHash<QChar, uint32_t> JKQTMathTextTextNode::blackboardUnicodeTable=QHash<QChar, uint32_t>();
const QHash<QChar, uint32_t>& JKQTMathTextTextNode::blackboardUnicodeTable(){
static QHash<QChar, uint32_t> table=[]() {
QHash<QChar, uint32_t> blackboardUnicodeTable;
void JKQTMathTextTextNode::fillStaticTables() {
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (blackboardUnicodeTable.size()>0) return;
for (const QChar ch: QString("ABDEFGIJKLMOSTUVWXYZ")) {
const QString ALPHA="ABDEFGIJKLMOSTUVWXYZ";
for (const QChar ch: ALPHA) {
blackboardUnicodeTable[ch]=0x1D538+(ch.unicode()-QChar('A').unicode());
}
for (const QChar ch: QString("abcdefghijklmnopqrstuvwxyz")) {
const QString alpha="abcdefghijklmnopqrstuvwxyz";
for (const QChar ch: alpha) {
blackboardUnicodeTable[ch]=0x1D552+(ch.unicode()-QChar('a').unicode());
}
for (const QChar ch: QString("0123456789")) {
const QString nums="0123456789";
for (const QChar ch: nums) {
blackboardUnicodeTable[ch]=0x1D7D8+(ch.unicode()-QChar('0').unicode());
}
@ -98,12 +97,15 @@ void JKQTMathTextTextNode::fillStaticTables() {
blackboardUnicodeTable['Q']=0x211A;
blackboardUnicodeTable['R']=0x211D;
blackboardUnicodeTable['Z']=0x2124;
return blackboardUnicodeTable;
}();
return table;
}
JKQTMathTextTextNode::JKQTMathTextTextNode(JKQTMathText* _parent, const QString& textIn, bool addWhitespace, bool stripInnerWhitepace):
JKQTMathTextTextBaseNode(_parent, "")
{
fillStaticTables();
QString textTransformed=textIn;
if (stripInnerWhitepace) {
@ -240,11 +242,11 @@ void JKQTMathTextTextNode::splitTextForLayout(QPainter &painter, JKQTMathTextEnv
} else if (bbMode==MTBBDMsimulate) {
CFontMode=FMasDefinedOutline;
} else if (bbMode==MTBBDMunicodeCharactersOrSimulate || bbMode==MTBBDMunicodeCharactersOrFontDirectly) {
if (blackboardUnicodeTable.contains(c) && fmRoman.inFontUcs4(blackboardUnicodeTable[c])) {
cs=jkqtp_UnicodeToUTF8Q(blackboardUnicodeTable[c]);
if (blackboardUnicodeTable().contains(c) && fmRoman.inFontUcs4(blackboardUnicodeTable().operator[](c))) {
cs=jkqtp_UnicodeToUTF8Q(blackboardUnicodeTable().operator[](c));
CFontMode=FMroman;
} else if (blackboardUnicodeTable.contains(c) && fmFallbackSym.inFontUcs4(blackboardUnicodeTable[c])) {
cs=jkqtp_UnicodeToUTF8Q(blackboardUnicodeTable[c]);
} else if (blackboardUnicodeTable().contains(c) && fmFallbackSym.inFontUcs4(blackboardUnicodeTable().operator[](c))) {
cs=jkqtp_UnicodeToUTF8Q(blackboardUnicodeTable().operator[](c));
CFontMode=FMfallbackSymbol;
} else {
if (bbMode==MTBBDMunicodeCharactersOrSimulate) {
@ -291,10 +293,10 @@ double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMat
const QFont fUpright=JKQTMathTextGetNonItalic(f);
const QFont fFallbackSym=currentEv.exchangedFontFor(MTEFallbackSymbols).getFont(parentMathText);
const QFont fRoman=currentEv.exchangedFontForRoman().getFont(parentMathText);
const QFontMetricsF fm(f, painter.device());
const QFontMetricsF fmUpright(fUpright, painter.device());
const QFontMetricsF fmFallbackSym(fFallbackSym, painter.device());
const QFontMetricsF fmRoman(fRoman, painter.device());
//const QFontMetricsF fm(f, painter.device());
//const QFontMetricsF fmUpright(fUpright, painter.device());
//const QFontMetricsF fmFallbackSym(fFallbackSym, painter.device());
//const QFontMetricsF fmRoman(fRoman, painter.device());
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setFont(f);

View File

@ -110,9 +110,7 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextTextBaseN
*/
void splitTextForLayout(QPainter &painter, JKQTMathTextEnvironment currentEv, const QString& txt, QStringList& textpart, QList<FontMode>& fontMode) const;
/** \brief translation table for blackboard-font characters from "normal" Latin-1 encoding to unicode-encoding of blackboards */
static QHash<QChar, uint32_t> blackboardUnicodeTable;
/** \brief fill static data */
static void fillStaticTables();
static const QHash<QChar, uint32_t>& blackboardUnicodeTable();
/** \copydoc JKQTMathTextTextBaseNode::textTransform() */
virtual QString textTransform(const QString& text, const JKQTMathTextEnvironment& currentEv) const override;
};

View File

@ -51,15 +51,13 @@ JKQTMathTextWhitespaceNode::JKQTMathTextWhitespaceNode(JKQTMathText *_parent):
JKQTMathTextWhitespaceNode::JKQTMathTextWhitespaceNode(const QString &_type, JKQTMathText *parent):
JKQTMathTextWhitespaceNode(parent)
{
fillSupportedInstructions();
whitespace=supportedInstructions[_type];
whitespace=supportedInstructions()[_type];
}
JKQTMathTextWhitespaceNode::JKQTMathTextWhitespaceNode(const QString &_type, size_t count, JKQTMathText *parent):
JKQTMathTextWhitespaceNode(parent)
{
fillSupportedInstructions();
whitespace=supportedInstructions[_type];
whitespace=supportedInstructions()[_type];
whitespace.count=whitespace.count*count;
}
@ -67,7 +65,6 @@ JKQTMathTextWhitespaceNode::JKQTMathTextWhitespaceNode(Types type, size_t count,
JKQTMathTextNode(parent),
whitespace(type, count)
{
fillSupportedInstructions();
}
JKQTMathTextWhitespaceNode::~JKQTMathTextWhitespaceNode() {
@ -134,13 +131,10 @@ JKQTMathTextNodeSize JKQTMathTextWhitespaceNode::getSizeInternal(QPainter &paint
return s;
}
QHash<QString, JKQTMathTextWhitespaceNode::WhitespaceProps> JKQTMathTextWhitespaceNode::supportedInstructions;
void JKQTMathTextWhitespaceNode::fillSupportedInstructions()
const QHash<QString, JKQTMathTextWhitespaceNode::WhitespaceProps>& JKQTMathTextWhitespaceNode::supportedInstructions() {
static QHash<QString, JKQTMathTextWhitespaceNode::WhitespaceProps> table=[]()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (supportedInstructions.size()==0) {
QHash<QString, JKQTMathTextWhitespaceNode::WhitespaceProps> supportedInstructions;
supportedInstructions[" "]=WhitespaceProps(WSTthicker, 1);
supportedInstructions["nbsp"]=WhitespaceProps(WSTNonbreaking, 1);
supportedInstructions["enspace"]=WhitespaceProps(WST1en, 1);
@ -158,7 +152,9 @@ void JKQTMathTextWhitespaceNode::fillSupportedInstructions()
supportedInstructions["negthinspace"]=WhitespaceProps(WSTnegthin, 1);
supportedInstructions["negmedspace"]=WhitespaceProps(WSTnegmedium, 1);
supportedInstructions["negthickspace"]=WhitespaceProps(WSTnegthick, 1);
}
return supportedInstructions;
}();
return table;
}
@ -212,8 +208,7 @@ double JKQTMathTextWhitespaceNode::Type2PixelWidth(Types type, JKQTMathTextEnvir
bool JKQTMathTextWhitespaceNode::supportsInstructionName(const QString &instruction)
{
fillSupportedInstructions();
return supportedInstructions.contains(instruction);
return supportedInstructions().contains(instruction);
}
@ -370,13 +365,11 @@ QString JKQTMathTextPhantomNode::Mode2Instruction(Mode mode)
JKQTMathTextPhantomNode::JKQTMathTextPhantomNode(JKQTMathText *parent, const QString &mode, JKQTMathTextNode *child):
JKQTMathTextInstruction1Node(parent, mode, child)
{
fillInstructions();
}
JKQTMathTextPhantomNode::JKQTMathTextPhantomNode(JKQTMathText* _parent, Mode mode, JKQTMathTextNode* child):
JKQTMathTextInstruction1Node(_parent, Mode2Instruction(mode), child)
{
fillInstructions();
}
JKQTMathTextPhantomNode::~JKQTMathTextPhantomNode() {
@ -389,10 +382,9 @@ QString JKQTMathTextPhantomNode::getTypeName() const
}
JKQTMathTextNodeSize JKQTMathTextPhantomNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const {
fillInstructions();
JKQTMathTextNodeSize s=getChild()->getSize(painter, currentEv);
switch(instructions[getInstructionName()]) {
switch(instructions()[getInstructionName()]) {
case FMwidth:
s.overallHeight=0;
s.baselineHeight=0;
@ -415,25 +407,23 @@ double JKQTMathTextPhantomNode::draw(QPainter& painter, double x, double y, JKQT
bool JKQTMathTextPhantomNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) const {
JKQTMathTextEnvironment ev=currentEv;
fillInstructions();
return "&nbsp;";
}
bool JKQTMathTextPhantomNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
return instructions().contains(instructionName);
}
QHash<QString, JKQTMathTextPhantomNode::Mode> JKQTMathTextPhantomNode::instructions;
void JKQTMathTextPhantomNode::fillInstructions()
const QHash<QString, JKQTMathTextPhantomNode::Mode>& JKQTMathTextPhantomNode::instructions() {
static QHash<QString, JKQTMathTextPhantomNode::Mode> table=[]()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
if (instructions.size()>0) return;
QHash<QString, JKQTMathTextPhantomNode::Mode> instructions;
instructions["phantom"] = FMwidthAndHeight;
instructions["hphantom"] = FMwidth;
instructions["vphantom"] = FMheight;
return instructions;
}();
return table;
}

View File

@ -100,10 +100,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextWhitespaceNode: public JKQTMathTextNod
WhitespaceProps whitespace;
/** \brief converts Types \a type into its HTML representation */
static QString Type2HTML(Types type);
/** \brief translation table between latex instruction and WhitespaceProps */
static QHash<QString, WhitespaceProps> supportedInstructions;
/** \brief initializes supportedInstructions */
static void fillSupportedInstructions();
/** \brief translation table between latex instruction and WhitespaceProps
*
* \note This is a customization point for additional whitespace instructions!
*/
static const QHash<QString, WhitespaceProps>& supportedInstructions();
};
@ -187,13 +188,11 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextPhantomNode: public JKQTMathTextInstru
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual JKQTMathTextNodeSize getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv) const override;
/** \brief fills instructions
/** \brief defines all implemented instructions in this node
*
* \note this is the customization point for new instructions!
*/
static void fillInstructions();
/** \brief defines all implemented instructions in this node */
static QHash<QString, Mode> instructions;
static const QHash<QString, Mode>& instructions();
};
#endif // JKQTMATHTEXTWHITESPACENODE_H

View File

@ -53,6 +53,7 @@
#include "jkqtmathtext/jkqtmathtext.h"
#include "jkqtplotter/jkqtpkey.h"
#include <algorithm>
#include <mutex>
QString JKQTBasePlotter::globalUserSettigsFilename="";
QString JKQTBasePlotter::globalUserSettigsPrefix="";
@ -64,10 +65,11 @@ JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>> JKQTBasePlotter::jkqtpSaveDataAd
void initJKQTBasePlotterResources()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> lock(sMutex);
static std::once_flag flag;
std::call_once(flag, []() {
Q_INIT_RESOURCE(jkqtpbaseplotter);
initJKQTMathTextResources();
});
}
@ -80,20 +82,20 @@ void JKQTBasePlotter::setDefaultJKQTBasePrinterUserSettings(QString userSettigsF
void JKQTBasePlotter::registerPaintDeviceAdapter(JKQTPPaintDeviceAdapter *adapter)
{
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::WriteLocker lock(jkqtpPaintDeviceAdapters);
jkqtpPaintDeviceAdapters.get().append(adapter);
}
void JKQTBasePlotter::deregisterPaintDeviceAdapter(JKQTPPaintDeviceAdapter *adapter)
{
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::WriteLocker lock(jkqtpPaintDeviceAdapters);
if (jkqtpPaintDeviceAdapters.get().contains(adapter)) jkqtpPaintDeviceAdapters.get().removeAll(adapter);
}
bool JKQTBasePlotter::registerSaveDataAdapter(JKQTPSaveDataAdapter *adapter)
{
if (adapter){
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::Locker lock(jkqtpSaveDataAdapters);
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::WriteLocker lock(jkqtpSaveDataAdapters);
QString format=adapter->getFilter();
for (int i=0; i<jkqtpSaveDataAdapters.get().size(); i++) {
if (jkqtpSaveDataAdapters.get()[i] && jkqtpSaveDataAdapters.get()[i]->getFilter()==format) {
@ -108,7 +110,7 @@ bool JKQTBasePlotter::registerSaveDataAdapter(JKQTPSaveDataAdapter *adapter)
bool JKQTBasePlotter::deregisterSaveDataAdapter(JKQTPSaveDataAdapter *adapter)
{
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::Locker lock(jkqtpSaveDataAdapters);
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::WriteLocker lock(jkqtpSaveDataAdapters);
if (jkqtpSaveDataAdapters.get().contains(adapter)) jkqtpSaveDataAdapters.get().removeAll(adapter);
return true;
}
@ -3285,7 +3287,7 @@ bool JKQTBasePlotter::saveData(const QString& filename, const QString &format) {
QMap<QString, QStringList> saveAdapterFileExtensions;
{
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::Locker lock(jkqtpSaveDataAdapters);
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::ReadLocker lock(jkqtpSaveDataAdapters);
for (int i=0; i<jkqtpSaveDataAdapters.get().size(); i++) {
const QString fid=jkqtpSaveDataAdapters.get()[i]->getFormatID();
fileformats<<jkqtpSaveDataAdapters.get()[i]->getFilter();
@ -3371,7 +3373,7 @@ bool JKQTBasePlotter::saveData(const QString& filename, const QString &format) {
QString fidx=fmt;
fidx=fidx.remove(0,6);
int idx=fidx.toInt();
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::Locker lock(jkqtpSaveDataAdapters);
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::ReadLocker lock(jkqtpSaveDataAdapters);
if (idx>=0 && idx<jkqtpSaveDataAdapters.get().size() && jkqtpSaveDataAdapters.get()[idx]) {
QStringList columnNames;
const QList<QVector<double> > dataset=datastore->getData(&columnNames);
@ -3379,7 +3381,7 @@ bool JKQTBasePlotter::saveData(const QString& filename, const QString &format) {
return true;
}
} else {
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::Locker lock(jkqtpSaveDataAdapters);
JKQTPSynchronized<QList<JKQTPSaveDataAdapter*>>::ReadLocker lock(jkqtpSaveDataAdapters);
for (int i=0; i<jkqtpSaveDataAdapters.get().size(); i++) {
if (fmt == jkqtpSaveDataAdapters.get()[i]->getFormatID()) {
QStringList columnNames;
@ -3583,7 +3585,7 @@ bool JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) {
// add JKQTPPaintDeviceAdapter exporters
const int filtersIndexFirstExporterPLugin=filterstrings.size();
{
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::ReadLocker lock(jkqtpPaintDeviceAdapters);
for (int i=0; i<jkqtpPaintDeviceAdapters.get().size(); i++) {
filterstrings<<jkqtpPaintDeviceAdapters.get()[i]->getFilter();
filterextensions<<QStringList();
@ -3635,7 +3637,7 @@ bool JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) {
if (idx<0) idx=findExporterByExtension(fnExt);
return idx;
}();
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::ReadLocker lock(jkqtpPaintDeviceAdapters);
// now we determine whether we selected a jkqtpPaintDeviceAdapters, if not adapterID will be <0
const int adapterID=[&](){
int idx=filtID-filtersIndexFirstExporterPLugin;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB