/src/qtbase/src/gui/text/qfontengine_p.h
Line | Count | Source |
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 | | |
4 | | #ifndef QFONTENGINE_P_H |
5 | | #define QFONTENGINE_P_H |
6 | | |
7 | | // |
8 | | // W A R N I N G |
9 | | // ------------- |
10 | | // |
11 | | // This file is not part of the Qt API. It exists purely as an |
12 | | // implementation detail. This header file may change from version to |
13 | | // version without notice, or even be removed. |
14 | | // |
15 | | // We mean it. |
16 | | // |
17 | | |
18 | | #include <QtGui/private/qtguiglobal_p.h> |
19 | | #include <QtGui/qfontvariableaxis.h> |
20 | | #include "QtCore/qatomic.h" |
21 | | #include <QtCore/qvarlengtharray.h> |
22 | | #include <QtCore/qhashfunctions.h> |
23 | | #include "private/qtextengine_p.h" |
24 | | #include "private/qfont_p.h" |
25 | | |
26 | | QT_BEGIN_NAMESPACE |
27 | | |
28 | | class QPainterPath; |
29 | | class QFontEngineGlyphCache; |
30 | | |
31 | | struct QGlyphLayout; |
32 | | |
33 | | // ### this only used in getPointInOutline(), refactor it and then remove these magic numbers |
34 | | enum HB_Compat_Error { |
35 | | Err_Ok = 0x0000, |
36 | | Err_Not_Covered = 0xFFFF, |
37 | | Err_Invalid_Argument = 0x1A66, |
38 | | Err_Invalid_SubTable_Format = 0x157F, |
39 | | Err_Invalid_SubTable = 0x1570 |
40 | | }; |
41 | | |
42 | | typedef void (*qt_destroy_func_t) (void *user_data); |
43 | | typedef bool (*qt_get_font_table_func_t) (void *user_data, uint tag, uchar *buffer, uint *length); |
44 | | |
45 | | Q_DECLARE_LOGGING_CATEGORY(lcColrv1) |
46 | | |
47 | | class Q_GUI_EXPORT QFontEngine |
48 | | { |
49 | | public: |
50 | | enum Type { |
51 | | Box, |
52 | | Multi, |
53 | | |
54 | | // MS Windows types |
55 | | Win, |
56 | | |
57 | | // Apple Mac OS types |
58 | | Mac, |
59 | | |
60 | | // QWS types |
61 | | Freetype, |
62 | | QPF1, |
63 | | QPF2, |
64 | | Proxy, |
65 | | |
66 | | DirectWrite, |
67 | | |
68 | | TestFontEngine = 0x1000 |
69 | | }; |
70 | | |
71 | | enum GlyphFormat { |
72 | | Format_None, |
73 | | Format_Render = Format_None, |
74 | | Format_Mono, |
75 | | Format_A8, |
76 | | Format_A32, |
77 | | Format_ARGB |
78 | | }; |
79 | | |
80 | | enum ShaperFlag { |
81 | | DesignMetrics = 0x0002, |
82 | | GlyphIndicesOnly = 0x0004, |
83 | | FullStringFallback = 0x008 |
84 | | }; |
85 | | Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag) |
86 | | |
87 | | /* Used with the Freetype font engine. */ |
88 | | struct Glyph { |
89 | 0 | Glyph() = default; |
90 | 0 | ~Glyph() { delete [] data; } |
91 | | short linearAdvance = 0; |
92 | | unsigned short width = 0; |
93 | | unsigned short height = 0; |
94 | | short x = 0; |
95 | | short y = 0; |
96 | | short advance = 0; |
97 | | signed char format = 0; |
98 | | uchar *data = nullptr; |
99 | | private: |
100 | | Q_DISABLE_COPY(Glyph) |
101 | | }; |
102 | | |
103 | | virtual ~QFontEngine(); |
104 | | |
105 | 5.21M | inline Type type() const { return m_type; } |
106 | | |
107 | | // all of these are in unscaled metrics if the engine supports uncsaled metrics, |
108 | | // otherwise in design metrics |
109 | | struct Properties { |
110 | | QByteArray postscriptName; |
111 | | QByteArray copyright; |
112 | | QRectF boundingBox; |
113 | | QFixed emSquare; |
114 | | QFixed ascent; |
115 | | QFixed descent; |
116 | | QFixed leading; |
117 | | QFixed italicAngle; |
118 | | QFixed capHeight; |
119 | | QFixed lineWidth; |
120 | | }; |
121 | | virtual Properties properties() const; |
122 | | virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); |
123 | | QByteArray getSfntTable(uint tag) const; |
124 | | virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; |
125 | | |
126 | | struct FaceId { |
127 | 35.4k | FaceId() : index(0), instanceIndex(-1), encoding(0) {} |
128 | | QByteArray filename; |
129 | | QByteArray uuid; |
130 | | int index; |
131 | | int instanceIndex; |
132 | | int encoding; |
133 | | QMap<QFont::Tag, float> variableAxes; |
134 | | }; |
135 | 35.4k | virtual FaceId faceId() const { return FaceId(); } |
136 | | enum SynthesizedFlags { |
137 | | SynthesizedItalic = 0x1, |
138 | | SynthesizedBold = 0x2, |
139 | | SynthesizedStretch = 0x4 |
140 | | }; |
141 | 0 | virtual int synthesized() const { return 0; } |
142 | | inline bool supportsSubPixelPositions() const |
143 | 280k | { |
144 | 280k | return supportsHorizontalSubPixelPositions() || supportsVerticalSubPixelPositions(); |
145 | 280k | } |
146 | 1.51M | virtual bool supportsHorizontalSubPixelPositions() const { return false; } |
147 | 871k | virtual bool supportsVerticalSubPixelPositions() const { return false; } |
148 | | virtual QFixedPoint subPixelPositionFor(const QFixedPoint &position) const; |
149 | | QFixed subPixelPositionForX(QFixed x) const |
150 | 0 | { |
151 | 0 | return subPixelPositionFor(QFixedPoint(x, 0)).x; |
152 | 0 | } |
153 | | |
154 | | bool preferTypoLineMetrics() const; |
155 | 0 | bool isColorFont() const { return glyphFormat == Format_ARGB; } |
156 | | static bool isIgnorableChar(char32_t ucs4) |
157 | 0 | { |
158 | 0 | return ucs4 == QChar::LineSeparator |
159 | 0 | || ucs4 == QChar::LineFeed |
160 | 0 | || ucs4 == QChar::CarriageReturn |
161 | 0 | || ucs4 == QChar::ParagraphSeparator |
162 | 0 | || (!disableEmojiSegmenter() && (ucs4 & 0xFFF0) == 0xFE00) |
163 | 0 | || QChar::category(ucs4) == QChar::Other_Control; |
164 | 0 | } |
165 | | |
166 | | static int maxCachedGlyphSize(); |
167 | | |
168 | | virtual QFixed emSquareSize() const; |
169 | | |
170 | | /* returns 0 as glyph index for non existent glyphs */ |
171 | | virtual glyph_t glyphIndex(uint ucs4) const = 0; |
172 | | virtual int stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const = 0; |
173 | 0 | virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const {} |
174 | | virtual void doKerning(QGlyphLayout *, ShaperFlags) const; |
175 | | |
176 | | virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, |
177 | | QPainterPath *path, QTextItem::RenderFlags flags); |
178 | | |
179 | | void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, |
180 | | QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions); |
181 | | |
182 | | virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags); |
183 | | void addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags); |
184 | | /** |
185 | | * Create a qimage with the alpha values for the glyph. |
186 | | * Returns an image indexed_8 with index values ranging from 0=fully transparent to 255=opaque |
187 | | */ |
188 | | // ### Refactor this into a smaller and more flexible API. |
189 | | virtual QImage alphaMapForGlyph(glyph_t); |
190 | | virtual QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition); |
191 | | virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t); |
192 | | virtual QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t); |
193 | | virtual QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t); |
194 | | virtual QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color = QColor()); |
195 | | QImage renderedPathForGlyph(glyph_t glyph, const QColor &color); |
196 | | virtual Glyph *glyphData(glyph_t glyph, const QFixedPoint &subPixelPosition, GlyphFormat neededFormat, const QTransform &t); |
197 | 560k | virtual bool hasInternalCaching() const { return false; } |
198 | | |
199 | | virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QFixedPoint &/*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/) |
200 | 30.5k | { |
201 | 30.5k | return boundingBox(glyph, matrix); |
202 | 30.5k | } |
203 | | |
204 | | virtual void removeGlyphFromCache(glyph_t); |
205 | | |
206 | | virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); |
207 | | virtual glyph_metrics_t boundingBox(glyph_t glyph) = 0; |
208 | | virtual glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix); |
209 | | glyph_metrics_t tightBoundingBox(const QGlyphLayout &glyphs, QTextItem::RenderFlags flags); |
210 | | |
211 | | virtual QFixed ascent() const; |
212 | | virtual QFixed capHeight() const = 0; |
213 | | virtual QFixed descent() const; |
214 | | virtual QFixed leading() const; |
215 | | virtual QFixed xHeight() const; |
216 | | virtual QFixed averageCharWidth() const; |
217 | | |
218 | | virtual QFixed lineThickness() const; |
219 | | virtual QFixed underlinePosition() const; |
220 | | |
221 | | virtual qreal maxCharWidth() const = 0; |
222 | | virtual qreal minLeftBearing() const; |
223 | | virtual qreal minRightBearing() const; |
224 | | |
225 | | virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr); |
226 | | |
227 | 0 | inline bool canRender(uint ucs4) const { return glyphIndex(ucs4) != 0; } |
228 | | virtual bool canRender(const QChar *str, int len) const; |
229 | | |
230 | | virtual bool supportsTransformation(const QTransform &transform) const; |
231 | | |
232 | | virtual int glyphCount() const; |
233 | 280k | virtual int glyphMargin(GlyphFormat format) { return format == Format_A32 ? 2 : 0; } |
234 | | bool hasHinting() const; |
235 | | |
236 | 0 | virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return nullptr; } |
237 | | |
238 | | virtual Qt::HANDLE handle() const; |
239 | | |
240 | | virtual QList<QFontVariableAxis> variableAxes() const; |
241 | | |
242 | | virtual QString glyphName(glyph_t index) const; |
243 | | virtual glyph_t findGlyph(QLatin1StringView name) const; |
244 | | |
245 | | void *harfbuzzFont() const; |
246 | | void *harfbuzzFace() const; |
247 | | bool supportsScript(QChar::Script script) const; |
248 | | |
249 | | inline static bool scriptRequiresOpenType(QChar::Script script) |
250 | 1.19M | { |
251 | 1.19M | return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala) |
252 | 1.03M | || script == QChar::Script_Khmer || script == QChar::Script_Nko); |
253 | 1.19M | } |
254 | | |
255 | | virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints); |
256 | | |
257 | | void clearGlyphCache(const void *key); |
258 | | void setGlyphCache(const void *key, QFontEngineGlyphCache *data); |
259 | | QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform, const QColor &color = QColor()) const; |
260 | | |
261 | | static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); |
262 | | static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode); |
263 | | |
264 | | static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily); |
265 | | |
266 | | virtual bool hasUnreliableGlyphOutline() const; |
267 | | virtual bool expectsGammaCorrectedBlending(QFontEngine::GlyphFormat format) const; |
268 | | |
269 | | static bool disableEmojiSegmenter(); |
270 | | |
271 | | enum HintStyle { |
272 | | HintUnset = -1, |
273 | | HintNone, |
274 | | HintLight, |
275 | | HintMedium, |
276 | | HintFull |
277 | | }; |
278 | 0 | virtual void setDefaultHintStyle(HintStyle) { } |
279 | | |
280 | | enum SubpixelAntialiasingType { |
281 | | Subpixel_Unset = -1, |
282 | | Subpixel_None, |
283 | | Subpixel_RGB, |
284 | | Subpixel_BGR, |
285 | | Subpixel_VRGB, |
286 | | Subpixel_VBGR |
287 | | }; |
288 | | |
289 | | private: |
290 | | const Type m_type; |
291 | | |
292 | | public: |
293 | | QAtomicInt ref; |
294 | | QFontDef fontDef; |
295 | | |
296 | | class Holder { // replace by std::unique_ptr once available |
297 | | void *ptr; |
298 | | qt_destroy_func_t destroy_func; |
299 | | public: |
300 | 196k | Holder() : ptr(nullptr), destroy_func(nullptr) {} |
301 | 70.8k | explicit Holder(void *p, qt_destroy_func_t d) : ptr(p), destroy_func(d) {} |
302 | 267k | ~Holder() { if (ptr && destroy_func) destroy_func(ptr); } |
303 | | Holder(Holder &&other) noexcept |
304 | | : ptr(std::exchange(other.ptr, nullptr)), |
305 | | destroy_func(std::exchange(other.destroy_func, nullptr)) |
306 | 0 | { |
307 | 0 | } |
308 | | QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Holder) |
309 | | |
310 | | void swap(Holder &other) noexcept |
311 | 70.8k | { |
312 | 70.8k | qSwap(ptr, other.ptr); |
313 | 70.8k | qSwap(destroy_func, other.destroy_func); |
314 | 70.8k | } |
315 | | |
316 | 1.23M | void *get() const noexcept { return ptr; } |
317 | 0 | void *release() noexcept { |
318 | 0 | void *result = ptr; |
319 | 0 | ptr = nullptr; |
320 | 0 | destroy_func = nullptr; |
321 | 0 | return result; |
322 | 0 | } |
323 | 0 | void reset() noexcept { Holder().swap(*this); } |
324 | 0 | qt_destroy_func_t get_deleter() const noexcept { return destroy_func; } |
325 | | |
326 | 1.23M | bool operator!() const noexcept { return !ptr; } |
327 | | }; |
328 | | |
329 | | mutable Holder font_; // \ NOTE: Declared before m_glyphCaches, so font_, face_ |
330 | | mutable Holder face_; // / are destroyed _after_ m_glyphCaches is destroyed. |
331 | | |
332 | | struct FaceData { |
333 | | void *user_data; |
334 | | qt_get_font_table_func_t get_font_table; |
335 | | } faceData; |
336 | | |
337 | | uint cache_cost; // amount of mem used in bytes by the font |
338 | | uint fsType : 16; |
339 | | bool symbol; |
340 | | bool isSmoothlyScalable; |
341 | | struct KernPair { |
342 | | uint left_right; |
343 | | QFixed adjust; |
344 | | |
345 | | inline bool operator<(const KernPair &other) const |
346 | 0 | { |
347 | 0 | return left_right < other.left_right; |
348 | 0 | } |
349 | | }; |
350 | | QList<KernPair> kerning_pairs; |
351 | | void loadKerningPairs(QFixed scalingFactor); |
352 | | |
353 | | GlyphFormat glyphFormat; |
354 | | int m_subPixelPositionCount; // Number of positions within a single pixel for this cache |
355 | | |
356 | | protected: |
357 | | explicit QFontEngine(Type type); |
358 | | |
359 | | QFixed firstLeftBearing(const QGlyphLayout &glyphs); |
360 | | QFixed lastRightBearing(const QGlyphLayout &glyphs); |
361 | | |
362 | | QFixed calculatedCapHeight() const; |
363 | | |
364 | | mutable QFixed m_ascent; |
365 | | mutable QFixed m_descent; |
366 | | mutable QFixed m_leading; |
367 | | mutable bool m_heightMetricsQueried; |
368 | | |
369 | | virtual void initializeHeightMetrics() const; |
370 | | bool processHheaTable() const; |
371 | | bool processOS2Table() const; |
372 | | |
373 | | private: |
374 | | struct GlyphCacheEntry { |
375 | | GlyphCacheEntry(); |
376 | | GlyphCacheEntry(const GlyphCacheEntry &); |
377 | | ~GlyphCacheEntry(); |
378 | | |
379 | | GlyphCacheEntry &operator=(const GlyphCacheEntry &); |
380 | | |
381 | | QExplicitlySharedDataPointer<QFontEngineGlyphCache> cache; |
382 | 0 | bool operator==(const GlyphCacheEntry &other) const { return cache == other.cache; } |
383 | | }; |
384 | | typedef std::list<GlyphCacheEntry> GlyphCaches; |
385 | | mutable QHash<const void *, GlyphCaches> m_glyphCaches; |
386 | | |
387 | | private: |
388 | | mutable qreal m_minLeftBearing; |
389 | | mutable qreal m_minRightBearing; |
390 | | mutable int m_hasHinting = -1; |
391 | | }; |
392 | | Q_DECLARE_TYPEINFO(QFontEngine::KernPair, Q_PRIMITIVE_TYPE); |
393 | | |
394 | 0 | Q_DECLARE_OPERATORS_FOR_FLAGS(QFontEngine::ShaperFlags) Unexecuted instantiation: operator|(QFontEngine::ShaperFlag, QFontEngine::ShaperFlag) Unexecuted instantiation: operator|(QFontEngine::ShaperFlag, QFlags<QFontEngine::ShaperFlag>) Unexecuted instantiation: operator&(QFontEngine::ShaperFlag, QFontEngine::ShaperFlag) Unexecuted instantiation: operator&(QFontEngine::ShaperFlag, QFlags<QFontEngine::ShaperFlag>) Unexecuted instantiation: operator^(QFontEngine::ShaperFlag, QFontEngine::ShaperFlag) Unexecuted instantiation: operator^(QFontEngine::ShaperFlag, QFlags<QFontEngine::ShaperFlag>) Unexecuted instantiation: operator|(QFontEngine::ShaperFlag, int) |
395 | 0 |
|
396 | 0 | inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2) |
397 | 0 | { |
398 | 0 | return f1.index == f2.index |
399 | 0 | && f1.encoding == f2.encoding |
400 | 0 | && f1.filename == f2.filename |
401 | 0 | && f1.uuid == f2.uuid |
402 | 0 | && f1.instanceIndex == f2.instanceIndex |
403 | 0 | && f1.variableAxes == f2.variableAxes; |
404 | 0 | } |
405 | | |
406 | | inline size_t qHash(const QFontEngine::FaceId &f, size_t seed = 0) |
407 | | noexcept(noexcept(qHash(f.filename))) |
408 | 0 | { |
409 | 0 | return qHashMulti(seed, f.filename, f.uuid, f.index, f.instanceIndex, f.encoding, f.variableAxes.keys(), f.variableAxes.values()); |
410 | 0 | } |
411 | | |
412 | | |
413 | | class QGlyph; |
414 | | |
415 | | |
416 | | |
417 | | class QFontEngineBox : public QFontEngine |
418 | | { |
419 | | public: |
420 | | QFontEngineBox(int size); |
421 | | ~QFontEngineBox(); |
422 | | |
423 | | virtual glyph_t glyphIndex(uint ucs4) const override; |
424 | | virtual int stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override; |
425 | | virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const override; |
426 | | |
427 | | void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si); |
428 | | virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) override; |
429 | | |
430 | | virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override; |
431 | | virtual glyph_metrics_t boundingBox(glyph_t glyph) override; |
432 | | virtual QFontEngine *cloneWithSize(qreal pixelSize) const override; |
433 | | |
434 | 35.4k | virtual QFixed emSquareSize() const override { return _size; } |
435 | | virtual QFixed ascent() const override; |
436 | | virtual QFixed capHeight() const override; |
437 | | virtual QFixed descent() const override; |
438 | | virtual QFixed leading() const override; |
439 | | virtual qreal maxCharWidth() const override; |
440 | 0 | virtual qreal minLeftBearing() const override { return 0; } |
441 | 2.50M | virtual qreal minRightBearing() const override { return 0; } |
442 | | virtual QImage alphaMapForGlyph(glyph_t) override; |
443 | | |
444 | | virtual bool canRender(const QChar *string, int len) const override; |
445 | | |
446 | 0 | inline int size() const { return _size; } |
447 | | |
448 | | protected: |
449 | | explicit QFontEngineBox(Type type, int size); |
450 | | |
451 | | private: |
452 | | friend class QFontPrivate; |
453 | | int _size; |
454 | | }; |
455 | | |
456 | | class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine |
457 | | { |
458 | | public: |
459 | | explicit QFontEngineMulti(QFontEngine *engine, int script, const QStringList &fallbackFamilies = QStringList()); |
460 | | ~QFontEngineMulti(); |
461 | | |
462 | | virtual int glyphCount() const override; |
463 | | virtual glyph_t glyphIndex(uint ucs4) const override; |
464 | | virtual int stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override; |
465 | | |
466 | | virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override; |
467 | | virtual glyph_metrics_t boundingBox(glyph_t glyph) override; |
468 | | |
469 | | virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const override; |
470 | | virtual void doKerning(QGlyphLayout *, ShaperFlags) const override; |
471 | | virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags) override; |
472 | | virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr) override; |
473 | | |
474 | | virtual QFixed emSquareSize() const override; |
475 | | virtual QFixed ascent() const override; |
476 | | virtual QFixed capHeight() const override; |
477 | | virtual QFixed descent() const override; |
478 | | virtual QFixed leading() const override; |
479 | | virtual QFixed xHeight() const override; |
480 | | virtual QFixed averageCharWidth() const override; |
481 | | virtual QImage alphaMapForGlyph(glyph_t) override; |
482 | | virtual QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition) override; |
483 | | virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t) override; |
484 | | virtual QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override; |
485 | | virtual QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override; |
486 | | |
487 | | virtual QFixed lineThickness() const override; |
488 | | virtual QFixed underlinePosition() const override; |
489 | | virtual qreal maxCharWidth() const override; |
490 | | virtual qreal minLeftBearing() const override; |
491 | | virtual qreal minRightBearing() const override; |
492 | | |
493 | | virtual QList<QFontVariableAxis> variableAxes() const override; |
494 | | |
495 | | virtual bool canRender(const QChar *string, int len) const override; |
496 | | QString glyphName(glyph_t glyph) const override; |
497 | | glyph_t findGlyph(QLatin1StringView name) const override; |
498 | | |
499 | 0 | inline int fallbackFamilyCount() const { return m_fallbackFamilies.size(); } |
500 | 0 | inline QString fallbackFamilyAt(int at) const { return m_fallbackFamilies.at(at); } |
501 | | |
502 | | void setFallbackFamiliesList(const QStringList &fallbackFamilies); |
503 | | |
504 | | static uchar highByte(glyph_t glyph); // Used for determining engine |
505 | | |
506 | | inline QFontEngine *engine(int at) const |
507 | 0 | { Q_ASSERT(at < m_engines.size()); return m_engines.at(at); } |
508 | | |
509 | | void ensureEngineAt(int at); |
510 | | |
511 | | static QFontEngine *createMultiFontEngine(QFontEngine *fe, int script); |
512 | | |
513 | | protected: |
514 | | virtual void ensureFallbackFamiliesQueried(); |
515 | | virtual bool shouldLoadFontEngineForCharacter(int at, uint ucs4) const; |
516 | | virtual QFontEngine *loadEngine(int at); |
517 | | |
518 | | private: |
519 | | QList<QFontEngine *> m_engines; |
520 | | QStringList m_fallbackFamilies; |
521 | | const int m_script; |
522 | | bool m_fallbackFamiliesQueried; |
523 | | }; |
524 | | |
525 | | class QTestFontEngine : public QFontEngineBox |
526 | | { |
527 | | public: |
528 | | QTestFontEngine(int size); |
529 | | }; |
530 | | |
531 | | QT_END_NAMESPACE |
532 | | |
533 | | |
534 | | |
535 | | #endif // QFONTENGINE_P_H |