cutter/src/common/CachedFontMetrics.h

85 lines
2.0 KiB
C
Raw Normal View History

#ifndef CACHEDFONTMETRICS_H
#define CACHEDFONTMETRICS_H
#include <QObject>
#include <QFont>
#include <QFontMetrics>
class CachedFontMetrics : public QObject
{
Q_OBJECT
public:
2018-03-21 20:32:32 +00:00
explicit CachedFontMetrics(QObject *parent, const QFont &font)
: QObject(parent),
mFontMetrics(font)
{
memset(mWidths, 0, sizeof(mWidths));
mHeight = mFontMetrics.height();
}
2018-03-21 20:32:32 +00:00
int width(const QChar &ch)
{
auto unicode = ch.unicode();
2018-03-21 20:32:32 +00:00
if (unicode >= 0xD800) {
if (unicode >= 0xE000)
unicode -= 0xE000 - 0xD800;
else
// is lonely surrogate
return mFontMetrics.width(ch);
}
2018-03-21 20:32:32 +00:00
if (!mWidths[unicode])
return mWidths[unicode] = mFontMetrics.width(ch);
return mWidths[unicode];
}
2018-03-21 20:32:32 +00:00
int width(const QString &text)
{
int result = 0;
QChar temp;
2018-03-21 20:32:32 +00:00
for (const QChar &ch : text) {
if (ch.isHighSurrogate())
temp = ch;
2018-03-21 20:32:32 +00:00
else if (ch.isLowSurrogate())
result += mFontMetrics.width(QString(temp) + ch);
else
result += width(ch);
}
return result;
}
int height()
{
return mHeight;
}
int position(const QString &text, int offset)
{
int 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 += mFontMetrics.width(QString(temp) + ch);
else
curWidth += width(ch);
if (curWidth >= offset) {
return i;
}
}
return -1;
}
private:
QFontMetrics mFontMetrics;
uchar mWidths[0x10000 - 0xE000 + 0xD800];
int mHeight;
};
#endif // CACHEDFONTMETRICS_H