68 TestFontEngine = 0x1000
73 Format_Render = Format_None,
81 DesignMetrics = 0x0002,
82 GlyphIndicesOnly = 0x0004,
83 FullStringFallback = 0x008
85 Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag)
90 ~Glyph() {
delete [] data; }
91 short linearAdvance = 0;
92 unsigned short width = 0;
93 unsigned short height = 0;
97 signed char format = 0;
98 uchar *data =
nullptr;
100 Q_DISABLE_COPY(Glyph)
103 virtual ~QFontEngine();
105 inline Type type()
const {
return m_type; }
110 QByteArray postscriptName;
111 QByteArray copyright;
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;
127 FaceId() : index(0), instanceIndex(-1), encoding(0) {}
133 QMap<QFont::Tag,
float> variableAxes;
135 virtual FaceId faceId()
const {
return FaceId(); }
136 enum SynthesizedFlags {
137 SynthesizedItalic = 0x1,
138 SynthesizedBold = 0x2,
139 SynthesizedStretch = 0x4
141 virtual int synthesized()
const {
return 0; }
142 inline bool supportsSubPixelPositions()
const
144 return supportsHorizontalSubPixelPositions() || supportsVerticalSubPixelPositions();
146 virtual bool supportsHorizontalSubPixelPositions()
const {
return false; }
147 virtual bool supportsVerticalSubPixelPositions()
const {
return false; }
148 virtual QFixedPoint subPixelPositionFor(
const QFixedPoint &position)
const;
149 QFixed subPixelPositionForX(QFixed x)
const
151 return subPixelPositionFor(QFixedPoint(x, 0)).x;
154 bool preferTypoLineMetrics()
const;
155 bool isColorFont()
const {
return glyphFormat == Format_ARGB; }
156 static bool isIgnorableChar(
char32_t ucs4)
158 return ucs4 == QChar::LineSeparator
159 || ucs4 == QChar::LineFeed
160 || ucs4 == QChar::CarriageReturn
161 || ucs4 == QChar::ParagraphSeparator
162 || (!disableEmojiSegmenter() && (ucs4 & 0xFFF0) == 0xFE00)
163 || QChar::category(ucs4) == QChar::Other_Control;
166 static int maxCachedGlyphSize();
168 virtual QFixed emSquareSize()
const;
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 virtual void recalcAdvances(QGlyphLayout *, ShaperFlags)
const {}
174 virtual void doKerning(QGlyphLayout *, ShaperFlags)
const;
176 virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions,
int nglyphs,
177 QPainterPath *path, QTextItem::RenderFlags flags);
179 void getGlyphPositions(
const QGlyphLayout &glyphs,
const QTransform &matrix, QTextItem::RenderFlags flags,
180 QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions);
182 virtual void addOutlineToPath(qreal, qreal,
const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags);
183 void addBitmapFontToPath(qreal x, qreal y,
const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags);
185
186
187
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);
197 qreal effectivePixelSizeSquared(
const QTransform &transform)
const;
198 static bool glyphBoundingBoxExceedsLimit(qreal glyphWidth,
200 qreal effectivePixelSizeSquared);
201 bool glyphTransformExceedsLimit(glyph_t glyph,
const QTransform &transform);
203 virtual Glyph *glyphData(glyph_t glyph,
const QFixedPoint &subPixelPosition, GlyphFormat neededFormat,
const QTransform &t);
204 virtual bool hasInternalCaching()
const {
return false; }
206 virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
const QFixedPoint &,
const QTransform &matrix, GlyphFormat )
208 return boundingBox(glyph, matrix);
211 virtual void removeGlyphFromCache(glyph_t);
213 virtual glyph_metrics_t boundingBox(
const QGlyphLayout &glyphs);
214 virtual glyph_metrics_t boundingBox(glyph_t glyph) = 0;
215 virtual glyph_metrics_t boundingBox(glyph_t glyph,
const QTransform &matrix);
216 glyph_metrics_t tightBoundingBox(
const QGlyphLayout &glyphs, QTextItem::RenderFlags flags);
218 virtual QFixed ascent()
const;
219 virtual QFixed capHeight()
const = 0;
220 virtual QFixed descent()
const;
221 virtual QFixed leading()
const;
222 virtual QFixed xHeight()
const;
223 virtual QFixed averageCharWidth()
const;
225 virtual QFixed lineThickness()
const;
226 virtual QFixed underlinePosition()
const;
228 virtual qreal maxCharWidth()
const = 0;
229 virtual qreal minLeftBearing()
const;
230 virtual qreal minRightBearing()
const;
232 virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing =
nullptr, qreal *rightBearing =
nullptr);
234 inline bool canRender(uint ucs4)
const {
return glyphIndex(ucs4) != 0; }
235 virtual bool canRender(
const QChar *str,
int len)
const;
237 virtual bool supportsTransformation(
const QTransform &transform)
const;
239 virtual int glyphCount()
const;
240 virtual int glyphMargin(GlyphFormat format) {
return format == Format_A32 ? 2 : 0; }
241 bool hasHinting()
const;
243 virtual QFontEngine *cloneWithSize(qreal )
const {
return nullptr; }
245 virtual Qt::HANDLE handle()
const;
247 virtual QList<QFontVariableAxis> variableAxes()
const;
249 virtual QString glyphName(glyph_t index)
const;
250 virtual glyph_t findGlyph(QLatin1StringView name)
const;
252 void *harfbuzzFont()
const;
253 void *harfbuzzFace()
const;
254 bool supportsScript(QChar::Script script)
const;
256 inline static bool scriptRequiresOpenType(QChar::Script script)
258 return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala)
259 || script == QChar::Script_Khmer || script == QChar::Script_Nko);
262 virtual int getPointInOutline(glyph_t glyph,
int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);
264 void clearGlyphCache(
const void *key);
265 void setGlyphCache(
const void *key, QFontEngineGlyphCache *data);
266 QFontEngineGlyphCache *glyphCache(
const void *key, GlyphFormat format,
const QTransform &transform,
const QColor &color = QColor())
const;
268 static const uchar *getCMap(
const uchar *table, uint tableSize,
bool *isSymbolFont,
int *cmapSize);
269 static quint32 getTrueTypeGlyphIndex(
const uchar *cmap,
int cmapSize, uint unicode);
271 static QByteArray convertToPostscriptFontFamilyName(
const QByteArray &fontFamily);
273 virtual bool hasUnreliableGlyphOutline()
const;
274 virtual bool expectsGammaCorrectedBlending(QFontEngine::GlyphFormat format)
const;
276 static bool disableEmojiSegmenter();
278 static constexpr qsizetype maximumEngineCount() {
return 256; }
287 virtual void setDefaultHintStyle(HintStyle) { }
289 enum SubpixelAntialiasingType {
307 qt_destroy_func_t destroy_func;
309 Holder() : ptr(
nullptr), destroy_func(
nullptr) {}
310 explicit Holder(
void *p, qt_destroy_func_t d) : ptr(p), destroy_func(d) {}
311 ~Holder() {
if (ptr && destroy_func) destroy_func(ptr); }
312 Holder(Holder &&other)
noexcept
313 : ptr(std::exchange(other.ptr,
nullptr)),
314 destroy_func(std::exchange(other.destroy_func,
nullptr))
317 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Holder)
319 void swap(Holder &other)
noexcept
321 qSwap(ptr, other.ptr);
322 qSwap(destroy_func, other.destroy_func);
325 void *get()
const noexcept {
return ptr; }
326 void *release()
noexcept {
329 destroy_func =
nullptr;
332 void reset()
noexcept { Holder().swap(*
this); }
333 qt_destroy_func_t get_deleter()
const noexcept {
return destroy_func; }
335 bool operator!()
const noexcept {
return !ptr; }
338 mutable Holder font_;
339 mutable Holder face_;
343 qt_get_font_table_func_t get_font_table;
349 bool isSmoothlyScalable;
354 inline bool operator<(
const KernPair &other)
const
356 return left_right < other.left_right;
359 QList<KernPair> kerning_pairs;
360 void loadKerningPairs(QFixed scalingFactor);
362 GlyphFormat glyphFormat;
363 int m_subPixelPositionCount;
366 explicit QFontEngine(Type type);
368 QFixed firstLeftBearing(
const QGlyphLayout &glyphs);
369 QFixed lastRightBearing(
const QGlyphLayout &glyphs);
371 QFixed calculatedCapHeight()
const;
373 mutable QFixed m_ascent;
374 mutable QFixed m_descent;
375 mutable QFixed m_leading;
376 mutable bool m_heightMetricsQueried;
378 virtual void initializeHeightMetrics()
const;
379 bool processHheaTable()
const;
380 bool processOS2Table()
const;
383 struct GlyphCacheEntry {
385 GlyphCacheEntry(
const GlyphCacheEntry &);
388 GlyphCacheEntry &operator=(
const GlyphCacheEntry &);
390 QExplicitlySharedDataPointer<QFontEngineGlyphCache> cache;
391 bool operator==(
const GlyphCacheEntry &other)
const {
return cache == other.cache; }
393 typedef std::list<GlyphCacheEntry> GlyphCaches;
394 mutable QHash<
const void *, GlyphCaches> m_glyphCaches;
397 mutable qreal m_minLeftBearing;
398 mutable qreal m_minRightBearing;
399 mutable int m_hasHinting = -1;
468 explicit QFontEngineMulti(QFontEngine *engine,
int script,
const QStringList &fallbackFamilies = QStringList());
471 virtual int glyphCount()
const override;
472 virtual glyph_t glyphIndex(uint ucs4)
const override;
473 virtual int stringToCMap(
const QChar *str,
int len, QGlyphLayout *glyphs,
int *nglyphs, ShaperFlags flags)
const override;
475 virtual glyph_metrics_t boundingBox(
const QGlyphLayout &glyphs) override;
476 virtual glyph_metrics_t boundingBox(glyph_t glyph) override;
478 virtual void recalcAdvances(QGlyphLayout *, ShaperFlags)
const override;
479 virtual void doKerning(QGlyphLayout *, ShaperFlags)
const override;
480 virtual void addOutlineToPath(qreal, qreal,
const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags) override;
481 virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing =
nullptr, qreal *rightBearing =
nullptr) override;
483 virtual QFixed emSquareSize()
const override;
484 virtual QFixed ascent()
const override;
485 virtual QFixed capHeight()
const override;
486 virtual QFixed descent()
const override;
487 virtual QFixed leading()
const override;
488 virtual QFixed xHeight()
const override;
489 virtual QFixed averageCharWidth()
const override;
490 virtual QImage alphaMapForGlyph(glyph_t) override;
491 virtual QImage alphaMapForGlyph(glyph_t glyph,
const QFixedPoint &subPixelPosition) override;
492 virtual QImage alphaMapForGlyph(glyph_t,
const QTransform &t) override;
493 virtual QImage alphaMapForGlyph(glyph_t,
const QFixedPoint &subPixelPosition,
const QTransform &t) override;
494 virtual QImage alphaRGBMapForGlyph(glyph_t,
const QFixedPoint &subPixelPosition,
const QTransform &t) override;
496 virtual QFixed lineThickness()
const override;
497 virtual QFixed underlinePosition()
const override;
498 virtual qreal maxCharWidth()
const override;
499 virtual qreal minLeftBearing()
const override;
500 virtual qreal minRightBearing()
const override;
502 virtual QList<QFontVariableAxis> variableAxes()
const override;
504 virtual bool canRender(
const QChar *string,
int len)
const override;
505 QString glyphName(glyph_t glyph)
const override;
506 glyph_t findGlyph(QLatin1StringView name)
const override;
508 inline int fallbackFamilyCount()
const {
return m_fallbackFamilies.size(); }
509 inline QString fallbackFamilyAt(
int at)
const {
return m_fallbackFamilies.at(at); }
511 void setFallbackFamiliesList(
const QStringList &fallbackFamilies);
513 static uchar highByte(glyph_t glyph);
515 inline QFontEngine *engine(
int at)
const
516 { Q_ASSERT(at < m_engines.size());
return m_engines.at(at); }
518 void ensureEngineAt(
int at);
520 static QFontEngine *createMultiFontEngine(QFontEngine *fe,
int script);
523 virtual void ensureFallbackFamiliesQueried();
524 virtual bool shouldLoadFontEngineForCharacter(
int at, uint ucs4)
const;
525 virtual QFontEngine *loadEngine(
int at);
528 QList<QFontEngine *> m_engines;
529 QStringList m_fallbackFamilies;
531 bool m_fallbackFamiliesQueried;