QtBase  v6.3.1
qfontengine_ft_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 #ifndef QFONTENGINE_FT_P_H
40 #define QFONTENGINE_FT_P_H
41 //
42 // W A R N I N G
43 // -------------
44 //
45 // This file is not part of the Qt API. It exists purely as an
46 // implementation detail. This header file may change from version to
47 // version without notice, or even be removed.
48 //
49 // We mean it.
50 //
51 
52 #include "private/qfontengine_p.h"
53 
54 #ifndef QT_NO_FREETYPE
55 
56 #include <ft2build.h>
57 #include FT_FREETYPE_H
58 
59 
60 #ifndef Q_OS_WIN
61 #include <unistd.h>
62 #endif
63 
64 #include <qmutex.h>
65 
66 #include <string.h>
67 
69 
70 class QFontEngineFTRawFont;
72 
73 /*
74  * This class represents one font file on disk (like Arial.ttf) and is shared between all the font engines
75  * that show this font file (at different pixel sizes).
76  */
77 class Q_GUI_EXPORT QFreetypeFace
78 {
79 public:
80  void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor);
81  QFontEngine::Properties properties() const;
82  bool getSfntTable(uint tag, uchar *buffer, uint *length) const;
83 
84  static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id,
85  const QByteArray &fontData = QByteArray());
86  void release(const QFontEngine::FaceId &face_id);
87 
88  static int getFaceIndexByStyleName(const QString &faceFileName, const QString &styleName);
89 
90  // locks the struct for usage. Any read/write operations require locking.
91  void lock()
92  {
93  _lock.lock();
94  }
95  void unlock()
96  {
97  _lock.unlock();
98  }
99 
101  int xsize; // 26.6
102  int ysize; // 26.6
106 
107  enum { cmapCacheSize = 0x200 };
108  glyph_t cmapCache[cmapCacheSize];
109 
110  int fsType() const;
111 
112  int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);
113 
114  bool isScalableBitmap() const;
115 
116  static void addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale);
117  static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path);
118 
119 private:
120  friend class QFontEngineFT;
121  friend class QtFreetypeData;
122  QFreetypeFace() = default;
123  ~QFreetypeFace() {}
124  void cleanup();
125  QAtomicInt ref;
126  QRecursiveMutex _lock;
128 
129  QFontEngine::Holder hbFace;
130 };
131 
132 class Q_GUI_EXPORT QFontEngineFT : public QFontEngine
133 {
134 public:
135  struct GlyphInfo {
137  unsigned short width;
138  unsigned short height;
139  short x;
140  short y;
141  short xOff;
142  short yOff;
143  };
144 
146  {
147  GlyphAndSubPixelPosition(glyph_t g, const QFixedPoint spp) : glyph(g), subPixelPosition(spp) {}
148 
150  {
151  return glyph == other.glyph && subPixelPosition == other.subPixelPosition;
152  }
153 
156  };
157 
158  struct QGlyphSet
159  {
160  QGlyphSet();
161  ~QGlyphSet();
164 
165  void removeGlyphFromCache(glyph_t index, const QFixedPoint &subPixelPosition);
166  void clear();
167  inline bool useFastGlyphData(glyph_t index, const QFixedPoint &subPixelPosition) const {
168  return (index < 256 && subPixelPosition.x == 0 && subPixelPosition.y == 0);
169  }
170  inline Glyph *getGlyph(glyph_t index,
171  const QFixedPoint &subPixelPositionX = QFixedPoint()) const;
172  void setGlyph(glyph_t index, const QFixedPoint &spp, Glyph *glyph);
173 
174  inline bool isGlyphMissing(glyph_t index) const { return missing_glyphs.contains(index); }
175  inline void setGlyphMissing(glyph_t index) const { missing_glyphs.insert(index); }
176 private:
178  mutable QHash<GlyphAndSubPixelPosition, Glyph *> glyph_data; // maps from glyph index to glyph data
179  mutable QSet<glyph_t> missing_glyphs;
180  mutable Glyph *fast_glyph_data[256]; // for fast lookup of glyphs < 256
181  mutable int fast_glyph_count;
182  };
183 
184  QFontEngine::FaceId faceId() const override;
185  QFontEngine::Properties properties() const override;
186  QFixed emSquareSize() const override;
188  {
189  return default_hint_style == HintLight ||
190  default_hint_style == HintNone;
191  }
192 
193  bool supportsVerticalSubPixelPositions() const override
194  {
195  return supportsHorizontalSubPixelPositions();
196  }
197 
198  bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
199  int synthesized() const override;
200 
201  void initializeHeightMetrics() const override;
202  QFixed capHeight() const override;
203  QFixed xHeight() const override;
204  QFixed averageCharWidth() const override;
205 
206  qreal maxCharWidth() const override;
207  QFixed lineThickness() const override;
208  QFixed underlinePosition() const override;
209 
210  glyph_t glyphIndex(uint ucs4) const override;
211  void doKerning(QGlyphLayout *, ShaperFlags) const override;
212 
213  void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
214 
215  bool supportsTransformation(const QTransform &transform) const override;
216 
217  void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
218  QPainterPath *path, QTextItem::RenderFlags flags) override;
219  void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
220  QPainterPath *path, QTextItem::RenderFlags flags) override;
221 
222  bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
223 
224  glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
225  glyph_metrics_t boundingBox(glyph_t glyph) override;
226  glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) override;
227 
228  void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const override;
230  QImage alphaMapForGlyph(glyph_t, const QFixedPoint &) override;
231  QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &t) override;
232  QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override;
233  QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color) override;
234  glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
235  const QFixedPoint &subPixelPosition,
236  const QTransform &matrix,
238  Glyph *glyphData(glyph_t glyph,
239  const QFixedPoint &subPixelPosition,
240  GlyphFormat neededFormat,
241  const QTransform &t) override;
242  bool hasInternalCaching() const override { return cacheEnabled; }
243  bool expectsGammaCorrectedBlending() const override;
244 
245  void removeGlyphFromCache(glyph_t glyph) override;
246  int glyphMargin(QFontEngine::GlyphFormat /* format */) override { return 0; }
247 
248  int glyphCount() const override;
249 
250  enum Scaling {
252  Unscaled
253  };
254  FT_Face lockFace(Scaling scale = Scaled) const;
255  void unlockFace() const;
256 
257  FT_Face non_locked_face() const;
258 
259  inline bool drawAntialiased() const { return antialias; }
260  inline bool invalid() const { return xsize == 0 && ysize == 0; }
261  inline bool isBitmapFont() const { return defaultFormat == Format_Mono; }
262  inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); }
263 
264  inline Glyph *loadGlyph(uint glyph,
265  const QFixedPoint &subPixelPosition,
266  GlyphFormat format = Format_None,
267  bool fetchMetricsOnly = false,
268  bool disableOutlineDrawing = false) const
269  { return loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); }
270  Glyph *loadGlyph(QGlyphSet *set,
271  uint glyph,
272  const QFixedPoint &subPixelPosition,
273  GlyphFormat = Format_None,
274  bool fetchMetricsOnly = false,
275  bool disableOutlineDrawing = false) const;
276  Glyph *loadGlyphFor(glyph_t g,
277  const QFixedPoint &subPixelPosition,
278  GlyphFormat format,
279  const QTransform &t,
280  bool fetchBoundingBox = false,
281  bool disableOutlineDrawing = false);
282 
283  QGlyphSet *loadGlyphSet(const QTransform &matrix);
284 
285  QFontEngineFT(const QFontDef &fd);
286  virtual ~QFontEngineFT();
287 
288  bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None,
289  const QByteArray &fontData = QByteArray());
290  bool init(FaceId faceId, bool antialias, GlyphFormat format,
291  QFreetypeFace *freetypeFace);
292 
293  int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) override;
294 
295  void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
296  void setDefaultHintStyle(HintStyle style) override;
297 
298  QFontEngine *cloneWithSize(qreal pixelSize) const override;
299  Qt::HANDLE handle() const override;
300  bool initFromFontEngine(const QFontEngineFT *fontEngine);
301 
302  HintStyle defaultHintStyle() const { return default_hint_style; }
303 
304  static QFontEngineFT *create(const QFontDef &fontDef, FaceId faceId, const QByteArray &fontData = QByteArray());
305  static QFontEngineFT *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
306 
307 protected:
308 
310  mutable int default_load_flags;
312  bool antialias;
313  bool transform;
314  bool embolden;
315  bool obliquen;
322 
323 private:
324  friend class QFontEngineFTRawFont;
325  friend class QFontconfigDatabase;
326  friend class QFreeTypeFontDatabase;
328 
329  int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
330  bool shouldUseDesignMetrics(ShaperFlags flags) const;
331  QFixed scaledBitmapMetrics(QFixed m) const;
332  glyph_metrics_t scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &matrix) const;
333 
334  GlyphFormat defaultFormat;
336 
337  struct TransformedGlyphSets {
338  enum { nSets = 10 };
339  QGlyphSet *sets[nSets];
340 
341  QGlyphSet *findSet(const QTransform &matrix, const QFontDef &fontDef);
342  TransformedGlyphSets() { std::fill(&sets[0], &sets[nSets], nullptr); }
343  ~TransformedGlyphSets() { qDeleteAll(&sets[0], &sets[nSets]); }
344  private:
345  void moveToFront(int i);
346  Q_DISABLE_COPY(TransformedGlyphSets);
347  };
348  TransformedGlyphSets transformedGlyphSets;
349  mutable QGlyphSet defaultGlyphSet;
350 
351  QFontEngine::FaceId face_id;
352 
353  int xsize;
354  int ysize;
355 
356  QFixed line_thickness;
358 
360  mutable bool kerning_pairs_loaded;
361  QFixed scalableBitmapScaleFactor;
362 };
363 
365 
366 
367 inline size_t qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g, size_t seed = 0)
368 {
369  return qHashMulti(seed,
370  g.glyph,
371  g.subPixelPosition.x.value(),
372  g.subPixelPosition.y.value());
373 }
374 
376  const QFixedPoint &subPixelPosition) const
377 {
378  if (useFastGlyphData(index, subPixelPosition))
379  return fast_glyph_data[index];
380  return glyph_data.value(GlyphAndSubPixelPosition(index, subPixelPosition));
381 }
382 
383 Q_GUI_EXPORT FT_Library qt_getFreetype();
384 
386 
387 #endif // QT_NO_FREETYPE
388 
389 #endif // QFONTENGINE_FT_P_H
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
Arabic default style
Definition: afstyles.h:94
The QAtomicInt class provides platform-independent atomic operations on int.
Definition: qatomic.h:158
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
int glyphMargin(QFontEngine::GlyphFormat) override
HintStyle defaultHintStyle() const
Glyph * loadGlyph(uint glyph, const QFixedPoint &subPixelPosition, GlyphFormat format=Format_None, bool fetchMetricsOnly=false, bool disableOutlineDrawing=false) 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
bool supportsHorizontalSubPixelPositions() const override
bool isBitmapFont() const
bool hasInternalCaching() const override
SubpixelAntialiasingType subpixelType
HintingPreference
Definition: qfont.h:88
FT_CharMap symbol_map
FT_CharMap unicode_map
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qhash.h:773
template< typename... T > size_t qHashMulti(size_t seed, const T &...args)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:65
The QRecursiveMutex class provides access serialization between threads.
Definition: qmutex.h:313
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:56
b clear()
QString str
[2]
qDeleteAll(list.begin(), list.end())
signed long FT_Fixed
Definition: fttypes.h:287
void * HANDLE
Definition: qnamespace.h:1561
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld init[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld cleanup[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
Q_GUI_EXPORT FT_Library qt_getFreetype()
Q_DECLARE_TYPEINFO(QFontEngineFT::QGlyphSet, Q_RELOCATABLE_TYPE)
unsigned int quint32
Definition: qglobal.h:288
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
Definition: qglobal.h:332
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
unsigned int uint
Definition: qglobal.h:334
#define Q_DISABLE_COPY(Class)
Definition: qglobal.h:515
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLuint64 GLenum void * handle
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLuint index
[2]
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
Definition: qopenglext.h:11564
GLenum GLsizei len
Definition: qopenglext.h:3292
GLuint GLenum matrix
Definition: qopenglext.h:11564
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLsizei const GLchar *const * path
Definition: qopenglext.h:4283
GLenum GLenum GLenum GLenum GLenum scale
Definition: qopenglext.h:10817
unsigned int glyph_t
@ Q_RELOCATABLE_TYPE
Definition: qtypeinfo.h:156
QFuture< QSet< QChar > > set
[10]
sem release()
Definition: main.cpp:48
ba fill(true)
QSharedPointer< T > other(t)
[5]
view create()
QFixed y
Definition: qfixed_p.h:192
QFixed x
Definition: qfixed_p.h:191
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
T1_FIELD_DICT_FONTDICT T1_FIELD_DICT_FONTDICT T1_FIELD_DICT_FONTDICT underline_position
Definition: t1tokens.h:40
XmlOutput::xml_output tag(const QString &name)
Definition: xmloutput.h:154