Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfontengine_ft_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QFONTENGINE_FT_P_H
4#define QFONTENGINE_FT_P_H
5//
6// W A R N I N G
7// -------------
8//
9// This file is not part of the Qt API. It exists purely as an
10// implementation detail. This header file may change from version to
11// version without notice, or even be removed.
12//
13// We mean it.
14//
15
16#include "private/qfontengine_p.h"
17
18#ifndef QT_NO_FREETYPE
19
20#include <ft2build.h>
21#include FT_FREETYPE_H
22#include FT_MULTIPLE_MASTERS_H
23
24
25#ifndef Q_OS_WIN
26#include <unistd.h>
27#endif
28
29#include <qmutex.h>
30
31#include <string.h>
32
34
35class QFontEngineFTRawFont;
37
38/*
39 * This class represents one font file on disk (like Arial.ttf) and is shared between all the font engines
40 * that show this font file (at different pixel sizes).
41 */
42class Q_GUI_EXPORT QFreetypeFace
43{
44public:
45 void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor);
47 bool getSfntTable(uint tag, uchar *buffer, uint *length) const;
48
49 static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id,
50 const QByteArray &fontData = QByteArray());
51 void release(const QFontEngine::FaceId &face_id);
52
53 static int getFaceIndexByStyleName(const QString &faceFileName, const QString &styleName);
54
55 // locks the struct for usage. Any read/write operations require locking.
56 void lock()
57 {
58 _lock.lock();
59 }
60 void unlock()
61 {
62 _lock.unlock();
63 }
64
65 FT_Face face;
66 FT_MM_Var *mm_var;
67 int xsize; // 26.6
68 int ysize; // 26.6
69 FT_Matrix matrix;
70 FT_CharMap unicode_map;
71 FT_CharMap symbol_map;
72
73 enum { cmapCacheSize = 0x200 };
74 glyph_t cmapCache[cmapCacheSize];
75
76 int fsType() const;
77
78 int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);
79
80 bool isScalable() const;
81 bool isScalableBitmap() const;
82
83 static void addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale);
84 static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path);
85
86private:
87 friend class QFontEngineFT;
88 friend class QtFreetypeData;
89 QFreetypeFace() = default;
91 void cleanup();
93 QRecursiveMutex _lock;
95
97};
98
99class Q_GUI_EXPORT QFontEngineFT : public QFontEngine
100{
101public:
102 struct GlyphInfo {
104 unsigned short width;
105 unsigned short height;
106 short x;
107 short y;
108 short xOff;
109 short yOff;
110 };
111
113 {
114 GlyphAndSubPixelPosition(glyph_t g, const QFixedPoint spp) : glyph(g), subPixelPosition(spp) {}
115
117 {
118 return glyph == other.glyph && subPixelPosition == other.subPixelPosition;
119 }
120
123 };
124
126 {
127 QGlyphSet();
128 ~QGlyphSet();
131
132 void removeGlyphFromCache(glyph_t index, const QFixedPoint &subPixelPosition);
133 void clear();
134 inline bool useFastGlyphData(glyph_t index, const QFixedPoint &subPixelPosition) const {
135 return (index < 256 && subPixelPosition.x == 0 && subPixelPosition.y == 0);
136 }
137 inline Glyph *getGlyph(glyph_t index,
138 const QFixedPoint &subPixelPositionX = QFixedPoint()) const;
139 void setGlyph(glyph_t index, const QFixedPoint &spp, Glyph *glyph);
140
141 inline bool isGlyphMissing(glyph_t index) const { return missing_glyphs.contains(index); }
142 inline void setGlyphMissing(glyph_t index) const { missing_glyphs.insert(index); }
143private:
144 Q_DISABLE_COPY(QGlyphSet);
145 mutable QHash<GlyphAndSubPixelPosition, Glyph *> glyph_data; // maps from glyph index to glyph data
146 mutable QSet<glyph_t> missing_glyphs;
147 mutable Glyph *fast_glyph_data[256]; // for fast lookup of glyphs < 256
148 mutable int fast_glyph_count;
149 };
150
151 QFontEngine::FaceId faceId() const override;
152 QFontEngine::Properties properties() const override;
153 QFixed emSquareSize() const override;
155 {
156 return default_hint_style == HintLight ||
157 default_hint_style == HintNone;
158 }
159
161 {
162 return supportsHorizontalSubPixelPositions();
163 }
164
165 bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
166 int synthesized() const override;
167
168 void initializeHeightMetrics() const override;
169 QFixed capHeight() const override;
170 QFixed xHeight() const override;
171 QFixed averageCharWidth() const override;
172
173 qreal maxCharWidth() const override;
174 QFixed lineThickness() const override;
175 QFixed underlinePosition() const override;
176
177 glyph_t glyphIndex(uint ucs4) const override;
178 void doKerning(QGlyphLayout *, ShaperFlags) const override;
179
180 void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
181
182 bool supportsTransformation(const QTransform &transform) const override;
183
184 void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
185 QPainterPath *path, QTextItem::RenderFlags flags) override;
186 void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
187 QPainterPath *path, QTextItem::RenderFlags flags) override;
188
189 int stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
190
191 glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
192 glyph_metrics_t boundingBox(glyph_t glyph) override;
193 glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) override;
194
195 void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const override;
197 QImage alphaMapForGlyph(glyph_t, const QFixedPoint &) override;
198 QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &t) override;
199 QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override;
200 QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color) override;
201 glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
202 const QFixedPoint &subPixelPosition,
203 const QTransform &matrix,
205 Glyph *glyphData(glyph_t glyph,
206 const QFixedPoint &subPixelPosition,
207 GlyphFormat neededFormat,
208 const QTransform &t) override;
209 bool hasInternalCaching() const override { return cacheEnabled; }
210 bool expectsGammaCorrectedBlending() const override;
211
212 void removeGlyphFromCache(glyph_t glyph) override;
213 int glyphMargin(QFontEngine::GlyphFormat /* format */) override { return 0; }
214
215 int glyphCount() const override;
216
217 enum Scaling {
219 Unscaled
220 };
221 FT_Face lockFace(Scaling scale = Scaled) const;
222 void unlockFace() const;
223
224 FT_Face non_locked_face() const;
225
226 inline bool drawAntialiased() const { return antialias; }
227 inline bool invalid() const { return xsize == 0 && ysize == 0; }
228 inline bool isBitmapFont() const { return defaultFormat == Format_Mono; }
229 inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); }
230
231 inline Glyph *loadGlyph(uint glyph,
232 const QFixedPoint &subPixelPosition,
233 GlyphFormat format = Format_None,
234 bool fetchMetricsOnly = false,
235 bool disableOutlineDrawing = false) const
236 { return loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); }
237 Glyph *loadGlyph(QGlyphSet *set,
238 uint glyph,
239 const QFixedPoint &subPixelPosition,
240 GlyphFormat = Format_None,
241 bool fetchMetricsOnly = false,
242 bool disableOutlineDrawing = false) const;
243 Glyph *loadGlyphFor(glyph_t g,
244 const QFixedPoint &subPixelPosition,
245 GlyphFormat format,
246 const QTransform &t,
247 bool fetchBoundingBox = false,
248 bool disableOutlineDrawing = false);
249
250 QGlyphSet *loadGlyphSet(const QTransform &matrix);
251
252 QFontEngineFT(const QFontDef &fd);
253 virtual ~QFontEngineFT();
254
255 bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None,
256 const QByteArray &fontData = QByteArray());
257 bool init(FaceId faceId, bool antialias, GlyphFormat format,
258 QFreetypeFace *freetypeFace);
259
260 int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) override;
261
262 void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
263 void setDefaultHintStyle(HintStyle style) override;
264
265 QFontEngine *cloneWithSize(qreal pixelSize) const override;
266 Qt::HANDLE handle() const override;
267 bool initFromFontEngine(const QFontEngineFT *fontEngine);
268
269 HintStyle defaultHintStyle() const { return default_hint_style; }
270
271 static QFontEngineFT *create(const QFontDef &fontDef, FaceId faceId, const QByteArray &fontData = QByteArray());
272 static QFontEngineFT *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference, const QMap<QFont::Tag, float> &variableAxisValue);
273
274protected:
275
289
290private:
291 friend class QFontEngineFTRawFont;
295
296 int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
297 bool shouldUseDesignMetrics(ShaperFlags flags) const;
298 QFixed scaledBitmapMetrics(QFixed m) const;
299 glyph_metrics_t scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &matrix) const;
300
301 GlyphFormat defaultFormat;
302 FT_Matrix matrix;
303
304 struct TransformedGlyphSets {
305 enum { nSets = 10 };
306 QGlyphSet *sets[nSets];
307
308 QGlyphSet *findSet(const QTransform &matrix, const QFontDef &fontDef);
309 TransformedGlyphSets() { std::fill(&sets[0], &sets[nSets], nullptr); }
310 ~TransformedGlyphSets() { qDeleteAll(&sets[0], &sets[nSets]); }
311 private:
312 void moveToFront(int i);
313 Q_DISABLE_COPY(TransformedGlyphSets);
314 };
315 TransformedGlyphSets transformedGlyphSets;
316 mutable QGlyphSet defaultGlyphSet;
317
318 QFontEngine::FaceId face_id;
319
320 int xsize;
321 int ysize;
322
323 QFixed line_thickness;
324 QFixed underline_position;
325
326 FT_Size_Metrics metrics;
327 mutable bool kerning_pairs_loaded;
328 QFixed scalableBitmapScaleFactor;
329};
330
331
332inline size_t qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g, size_t seed = 0)
333{
334 return qHashMulti(seed,
335 g.glyph,
336 g.subPixelPosition.x.value(),
337 g.subPixelPosition.y.value());
338}
339
341 const QFixedPoint &subPixelPosition) const
342{
343 if (useFastGlyphData(index, subPixelPosition))
344 return fast_glyph_data[index];
345 return glyph_data.value(GlyphAndSubPixelPosition(index, subPixelPosition));
346}
347
348Q_GUI_EXPORT FT_Library qt_getFreetype();
349
351
352#endif // QT_NO_FREETYPE
353
354#endif // QFONTENGINE_FT_P_H
\inmodule QtCore
Definition qatomic.h:112
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
int glyphMargin(QFontEngine::GlyphFormat) override
HintStyle defaultHintStyle() const
bool drawAntialiased() const
HintStyle default_hint_style
bool supportsVerticalSubPixelPositions() const override
QFreetypeFace * freetype
QImage alphaMapForGlyph(glyph_t g) override
bool isScalableBitmap() const
bool invalid() const
Glyph * loadGlyph(uint glyph, const QFixedPoint &subPixelPosition, GlyphFormat format=Format_None, bool fetchMetricsOnly=false, bool disableOutlineDrawing=false) const
bool supportsHorizontalSubPixelPositions() const override
bool isBitmapFont() const
bool hasInternalCaching() const override
SubpixelAntialiasingType subpixelType
HintingPreference
Definition qfont.h:55
FT_CharMap symbol_map
FT_CharMap unicode_map
FT_MM_Var * mm_var
\inmodule QtGui
Definition qimage.h:37
\inmodule QtGui
\inmodule QtCore
Definition qmutex.h:309
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QString str
[2]
b clear()
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
void * HANDLE
AudioChannelLayoutTag tag
static const QCssKnownValue positions[NumKnownPositionModes - 1]
static const QCssKnownValue properties[NumProperties - 1]
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
Q_GUI_EXPORT FT_Library qt_getFreetype()
size_t qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g, size_t seed=0)
constexpr QtPrivate::QHashMultiReturnType< T... > qHashMulti(size_t seed, const T &... args) noexcept(std::conjunction_v< QtPrivate::QNothrowHashable< T >... >)
GLuint64 GLenum void * handle
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLuint index
[2]
GLenum GLuint GLenum GLsizei length
GLenum face
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLenum GLuint buffer
GLuint color
[2]
GLbitfield flags
GLboolean GLboolean g
GLuint64 GLenum GLint fd
GLint ref
GLint GLsizei GLsizei GLenum format
GLenum GLsizeiptr const void * fontData
GLint y
GLuint GLenum GLenum transform
GLuint GLenum matrix
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * path
GLenum GLsizei len
GLenum GLenum GLenum GLenum GLenum scale
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
unsigned int glyph_t
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, QPainterPath *path, bool ttf, glyph_metrics_t *metric=nullptr, qreal scale=1.0, qreal stretch=1.0)
QFuture< QSet< QChar > > set
[10]
sem release()
QSharedPointer< T > other(t)
[5]
view create()
QFixed y
Definition qfixed_p.h:163
QFixed x
Definition qfixed_p.h:162
bool operator==(const GlyphAndSubPixelPosition &other) const
GlyphAndSubPixelPosition(glyph_t g, const QFixedPoint spp)
bool isGlyphMissing(glyph_t index) const
bool useFastGlyphData(glyph_t index, const QFixedPoint &subPixelPosition) const
Glyph * getGlyph(glyph_t index, const QFixedPoint &subPixelPositionX=QFixedPoint()) const
void setGlyphMissing(glyph_t index) const