cutter/src/common/CachedFontMetrics.h
2021-01-24 18:34:16 +02:00

101 lines
2.2 KiB
C++

#ifndef CACHEDFONTMETRICS_H
#define CACHEDFONTMETRICS_H
#include "common/Metrics.h"
#include <QObject>
#include <QFont>
#include <QFontMetrics>
template<typename T>
class CachedFontMetrics
{
public:
explicit CachedFontMetrics(const QFont &font) : mFontMetrics(font)
{
memset(mWidths, 0, sizeof(mWidths));
mHeight = mFontMetrics.height();
}
T width(const QChar &ch)
{
// return mFontMetrics.width(ch);
auto unicode = ch.unicode();
if (unicode >= 0xD800) {
if (unicode >= 0xE000)
unicode -= 0xE000 - 0xD800;
else
// is lonely surrogate
return fetchWidth(ch);
}
if (!mWidths[unicode])
return mWidths[unicode] = fetchWidth(ch);
return mWidths[unicode];
}
T width(const QString &text)
{
T result = 0;
QChar temp;
for (const QChar &ch : text) {
if (ch.isHighSurrogate())
temp = ch;
else if (ch.isLowSurrogate())
result += fetchWidth(QString(temp) + ch);
else
result += width(ch);
}
return result;
}
T height() { return mHeight; }
T position(const QString &text, T offset)
{
T curWidth = 0;
QChar temp;
for (int i = 0; i < text.length(); i++) {
QChar ch = text[i];
if (ch.isHighSurrogate())
temp = ch;
else if (ch.isLowSurrogate())
curWidth += fetchWidth(QString(temp) + ch);
else
curWidth += width(ch);
if (curWidth >= offset) {
return i;
}
}
return -1;
}
private:
typename Metrics<T>::FontMetrics mFontMetrics;
T mWidths[0x10000 - 0xE000 + 0xD800];
T mHeight;
T fetchWidth(QChar c)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
return mFontMetrics.width(c);
#else
return mFontMetrics.horizontalAdvance(c);
#endif
}
T fetchWidth(const QString &s)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
return mFontMetrics.width(s);
#else
return mFontMetrics.horizontalAdvance(s);
#endif
}
};
#endif // CACHEDFONTMETRICS_H