Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
distancefieldmodel.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
6
7#include <QThread>
8#include <QMetaEnum>
9
11
14 , m_glyphCount(0)
15{
16 int index = metaObject()->indexOfEnumerator("UnicodeRange");
17 Q_ASSERT(index >= 0);
18
19 m_rangeEnum = metaObject()->enumerator(index);
20
21 m_workerThread.reset(new QThread);
22
23 m_worker = new DistanceFieldModelWorker;
24 m_worker->moveToThread(m_workerThread.data());
25 connect(m_workerThread.data(), &QThread::finished,
26 m_worker, &QObject::deleteLater);
27
28 connect(m_worker, &DistanceFieldModelWorker::fontLoaded,
29 this, &DistanceFieldModel::startGeneration);
30 connect(m_worker, &DistanceFieldModelWorker::fontLoaded,
31 this, &DistanceFieldModel::reserveSpace);
32 connect(m_worker, &DistanceFieldModelWorker::distanceFieldGenerated,
33 this, &DistanceFieldModel::addDistanceField);
34 connect(m_worker, &DistanceFieldModelWorker::fontGenerated,
35 this, &DistanceFieldModel::stopGeneration);
36 connect(m_worker, &DistanceFieldModelWorker::distanceFieldGenerated,
37 this, &DistanceFieldModel::distanceFieldGenerated);
38 connect(m_worker, &DistanceFieldModelWorker::error,
39 this, &DistanceFieldModel::error);
40
41 m_workerThread->start();
42}
43
45{
46 m_workerThread->quit();
47 m_workerThread->wait();
48}
49
50QVariant DistanceFieldModel::headerData(int section, Qt::Orientation orientation, int role) const
51{
52 Q_UNUSED(section);
53 Q_UNUSED(orientation);
54 Q_UNUSED(role);
55 return QVariant();
56}
57
58int DistanceFieldModel::rowCount(const QModelIndex &parent) const
59{
60 if (parent.isValid())
61 return 0;
62 else
63 return m_glyphCount;
64}
65
66QVariant DistanceFieldModel::data(const QModelIndex &index, int role) const
67{
68 static QPixmap defaultImage;
69 if (defaultImage.isNull()) {
70 defaultImage = QPixmap(64, 64);
71 defaultImage.fill(Qt::white);
72 }
73
74 if (!index.isValid())
75 return QVariant();
76
77 if (role == Qt::DecorationRole) {
78 if (index.row() < m_distanceFields.size()) {
79 return QPixmap::fromImage(m_distanceFields.at(index.row()).scaled(64, 64));
80 } else {
81 return defaultImage;
82 }
83
84 }
85
86 return QVariant();
87}
88
89void DistanceFieldModel::setFont(const QString &fileName)
90{
91 QMetaObject::invokeMethod(m_worker,
92 [this, fileName] { m_worker->loadFont(fileName); },
93 Qt::QueuedConnection);
94}
95
96void DistanceFieldModel::reserveSpace(quint16 glyphCount,
97 bool doubleResolution,
98 qreal pixelSize)
99{
100 beginResetModel();
101 m_glyphsPerUnicodeRange.clear();
102 m_distanceFields.clear();
103 m_glyphCount = glyphCount;
104 if (glyphCount > 0)
105 m_distanceFields.reserve(glyphCount);
106 endResetModel();
107
108 m_doubleGlyphResolution = doubleResolution;
109 m_pixelSize = pixelSize;
110
111 QMetaObject::invokeMethod(m_worker,
112 [this] { m_worker->generateOneDistanceField(); },
113 Qt::QueuedConnection);
114}
115
116DistanceFieldModel::UnicodeRange DistanceFieldModel::unicodeRangeForUcs4(quint32 ucs4) const
117{
118 int index = metaObject()->indexOfEnumerator("UnicodeRange");
119 Q_ASSERT(index >= 0);
120
121 QMetaEnum range = metaObject()->enumerator(index);
122 for (int i = 0; i < range.keyCount() - 1; ++i) {
123 int rangeStart = range.value(i);
124 int rangeEnd = range.value(i + 1);
125 if (quint32(rangeStart) <= ucs4 && quint32(rangeEnd) >= ucs4)
126 return UnicodeRange(rangeStart);
127 }
128
129 return Other;
130}
131
133{
134 return m_glyphsPerUnicodeRange.uniqueKeys();
135}
136
138{
139 return m_glyphsPerUnicodeRange.values(range);
140}
141
143{
144 return QString::fromLatin1(m_rangeEnum.valueToKey(int(range)));
145}
146
147void DistanceFieldModel::addDistanceField(const QImage &distanceField,
148 const QPainterPath &path,
149 glyph_t glyphId,
150 quint32 ucs4)
151{
152 if (glyphId >= quint16(m_distanceFields.size()))
153 m_distanceFields.resize(glyphId + 1);
154 m_distanceFields[glyphId] = distanceField;
155 if (glyphId >= quint16(m_paths.size()))
156 m_paths.resize(glyphId + 1);
157 m_paths[glyphId] = path;
158
159 if (ucs4 != 0) {
160 UnicodeRange range = unicodeRangeForUcs4(ucs4);
161 m_glyphsPerUnicodeRange.insert(range, glyphId);
162 m_glyphsPerUcs4.insert(ucs4, glyphId);
163 }
164
165 emit dataChanged(createIndex(glyphId, 0), createIndex(glyphId, 0));
166
167 QMetaObject::invokeMethod(m_worker,
168 [this] { m_worker->generateOneDistanceField(); },
169 Qt::QueuedConnection);
170}
171
173{
174 return m_glyphsPerUcs4.value(ucs4);
175}
176
177QT_END_NAMESPACE
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of rows under the given parent.
void setFont(const QString &fileName)
QString nameForUnicodeRange(UnicodeRange range) const
QList< glyph_t > glyphIndexesForUnicodeRange(UnicodeRange range) const
glyph_t glyphIndexForUcs4(quint32 ucs4) const
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Returns the data for the given role and section in the header with the specified orientation.
QList< UnicodeRange > unicodeRanges() const
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Returns the data stored under the given role for the item referred to by the index.
QObject * parent
Definition qobject.h:73
\inmodule QtCore
Definition qobject.h:103
Combined button and popup list for selecting options.