#ifndef CACHEDFONTMETRICS_H #define CACHEDFONTMETRICS_H #include "common/Metrics.h" #include #include #include template 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::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