1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QFONTENGINE_P_H
43 #define QFONTENGINE_P_H
44
45 //
46 // W A R N I N G
47 // -------------
48 //
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "QtCore/qglobal.h"
57 #include "QtCore/qatomic.h"
58 #include <QtCore/qvarlengtharray.h>
59 #include <QtCore/QLinkedList>
60 #include "private/qtextengine_p.h"
61 #include "private/qfont_p.h"
62
63 #ifdef Q_WS_WIN
64 # include "QtCore/qt_windows.h"
65 #endif
66
67 #ifdef Q_WS_MAC
68 # include "private/qt_mac_p.h"
69 # include "QtCore/qmap.h"
70 # include "QtCore/qcache.h"
71 # include "private/qcore_mac_p.h"
72 #endif
73
74 #include <private/qfontengineglyphcache_p.h>
75
76 struct glyph_metrics_t;
77 typedef unsigned int glyph_t;
78
79 QT_BEGIN_NAMESPACE
80
81 class QChar;
82 class QPainterPath;
83
84 class QTextEngine;
85 struct QGlyphLayout;
86
87 #define MAKE_TAG(ch1, ch2, ch3, ch4) (\
88 (((quint32)(ch1)) << 24) | \
89 (((quint32)(ch2)) << 16) | \
90 (((quint32)(ch3)) << 8) | \
91 ((quint32)(ch4)) \
92 )
93
94
95 class Q_GUI_EXPORT QFontEngine : public QObject
96 {
97 public:
98 enum Type {
99 Box,
100 Multi,
101
102 // X11 types
103 XLFD,
104
105 // MS Windows types
106 Win,
107
108 // Apple Mac OS types
109 Mac,
110
111 // QWS types
112 Freetype,
113 QPF1,
114 QPF2,
115 Proxy,
116
117 // S60 types
118 S60FontEngine, // Cannot be simply called "S60". Reason is qt_s60Data.h
119
120 DirectWrite,
121
122 TestFontEngine = 0x1000
123 };
124
125 enum GlyphFormat {
126 Format_None,
127 Format_Render = Format_None,
128 Format_Mono,
129 Format_A8,
130 Format_A32
131 };
132
133 QFontEngine();
134 virtual ~QFontEngine();
135
136 // all of these are in unscaled metrics if the engine supports uncsaled metrics,
137 // otherwise in design metrics
138 struct Properties {
139 QByteArray postscriptName;
140 QByteArray copyright;
141 QRectF boundingBox;
142 QFixed emSquare;
143 QFixed ascent;
144 QFixed descent;
145 QFixed leading;
146 QFixed italicAngle;
147 QFixed capHeight;
148 QFixed lineWidth;
149 };
150 virtual Properties properties() const;
151 virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
152 QByteArray getSfntTable(uint /*tag*/) const;
getSfntTableData(uint,uchar *,uint *)153 virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const { return false; }
154
155 struct FaceId {
FaceIdFaceId156 FaceId() : index(0), encoding(0) {}
157 QByteArray filename;
158 QByteArray uuid;
159 int index;
160 int encoding;
161 };
faceId()162 virtual FaceId faceId() const { return FaceId(); }
163 enum SynthesizedFlags {
164 SynthesizedItalic = 0x1,
165 SynthesizedBold = 0x2,
166 SynthesizedStretch = 0x4
167 };
synthesized()168 virtual int synthesized() const { return 0; }
supportsSubPixelPositions()169 virtual bool supportsSubPixelPositions() const { return false; }
170
emSquareSize()171 virtual QFixed emSquareSize() const { return ascent(); }
172
173 /* returns 0 as glyph index for non existent glyphs */
174 virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const = 0;
175
176 /**
177 * This is a callback from harfbuzz. The font engine uses the font-system in use to find out the
178 * advances of each glyph and set it on the layout.
179 */
recalcAdvances(QGlyphLayout *,QTextEngine::ShaperFlags)180 virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const {}
181 virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
182
183 #if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(Q_WS_QPA)
184 virtual void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si) = 0;
185 #endif
186 virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
187 QPainterPath *path, QTextItem::RenderFlags flags);
188
189 void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags,
190 QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions);
191
192 virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags);
193 void addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags);
194 /**
195 * Create a qimage with the alpha values for the glyph.
196 * Returns an image indexed_8 with index values ranging from 0=fully transparent to 255=opaque
197 */
198 virtual QImage alphaMapForGlyph(glyph_t);
199 virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
200 virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
201 virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
202 virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
203
alphaMapBoundingBox(glyph_t glyph,QFixed,const QTransform & matrix,GlyphFormat)204 virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/)
205 {
206 return boundingBox(glyph, matrix);
207 }
208
209 virtual void removeGlyphFromCache(glyph_t);
210
211 virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) = 0;
212 virtual glyph_metrics_t boundingBox(glyph_t glyph) = 0;
213 virtual glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix);
214 glyph_metrics_t tightBoundingBox(const QGlyphLayout &glyphs);
215
216 virtual QFixed ascent() const = 0;
217 virtual QFixed descent() const = 0;
218 virtual QFixed leading() const = 0;
219 virtual QFixed xHeight() const;
220 virtual QFixed averageCharWidth() const;
221
222 virtual QFixed lineThickness() const;
223 virtual QFixed underlinePosition() const;
224
225 virtual qreal maxCharWidth() const = 0;
minLeftBearing()226 virtual qreal minLeftBearing() const { return qreal(); }
minRightBearing()227 virtual qreal minRightBearing() const { return qreal(); }
228
229 virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
230
231 virtual const char *name() const = 0;
232
233 virtual bool canRender(const QChar *string, int len) = 0;
234
235 virtual Type type() const = 0;
236
237 virtual int glyphCount() const;
238
cloneWithSize(qreal)239 virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; }
240
241 HB_Font harfbuzzFont() const;
242 HB_Face harfbuzzFace() const;
243
244 virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
245
246 void setGlyphCache(void *key, QFontEngineGlyphCache *data);
247 QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
248
249 static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
250 static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode);
251
252 static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
253
254 QAtomicInt ref;
255 QFontDef fontDef;
256 uint cache_cost; // amount of mem used in kb by the font
257 int cache_count;
258 uint fsType : 16;
259 bool symbol;
260 mutable HB_FontRec hbFont;
261 mutable HB_Face hbFace;
262 #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
263 struct KernPair {
264 uint left_right;
265 QFixed adjust;
266
267 inline bool operator<(const KernPair &other) const
268 {
269 return left_right < other.left_right;
270 }
271 };
272 QVector<KernPair> kerning_pairs;
273 void loadKerningPairs(QFixed scalingFactor);
274 #endif
275
276 int glyphFormat;
277
278 protected:
279 static const QVector<QRgb> &grayPalette();
280 QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false);
281
282 private:
283 struct GlyphCacheEntry {
284 void *context;
285 QExplicitlySharedDataPointer<QFontEngineGlyphCache> cache;
286 bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; }
287 };
288
289 mutable QLinkedList<GlyphCacheEntry> m_glyphCaches;
290 };
291
292 inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2)
293 {
294 return (f1.index == f2.index) && (f1.encoding == f2.encoding) && (f1.filename == f2.filename);
295 }
296
qHash(const QFontEngine::FaceId & f)297 inline uint qHash(const QFontEngine::FaceId &f)
298 {
299 return qHash((f.index << 16) + f.encoding) + qHash(f.filename + f.uuid);
300 }
301
302
303 class QGlyph;
304
305 #if defined(Q_WS_QWS)
306
307 #ifndef QT_NO_QWS_QPF
308
309 class QFontEngineQPF1Data;
310
311 class QFontEngineQPF1 : public QFontEngine
312 {
313 public:
314 QFontEngineQPF1(const QFontDef&, const QString &fn);
315 ~QFontEngineQPF1();
316
317 virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
318 virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
319
320 virtual void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si);
321 virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
322
323 virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
324 virtual glyph_metrics_t boundingBox(glyph_t glyph);
325
326 virtual QFixed ascent() const;
327 virtual QFixed descent() const;
328 virtual QFixed leading() const;
329 virtual qreal maxCharWidth() const;
330 virtual qreal minLeftBearing() const;
331 virtual qreal minRightBearing() const;
332 virtual QFixed underlinePosition() const;
333 virtual QFixed lineThickness() const;
334
335 virtual Type type() const;
336
337 virtual bool canRender(const QChar *string, int len);
name()338 inline const char *name() const { return 0; }
339 virtual QImage alphaMapForGlyph(glyph_t);
340
341
342 QFontEngineQPF1Data *d;
343 };
344 #endif // QT_NO_QWS_QPF
345
346 #endif // QWS
347
348
349 class QFontEngineBox : public QFontEngine
350 {
351 public:
352 QFontEngineBox(int size);
353 ~QFontEngineBox();
354
355 virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
356 virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
357
358 #if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
359 void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si);
360 #endif
361 virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
362
363 virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
364 virtual glyph_metrics_t boundingBox(glyph_t glyph);
365
366 virtual QFixed ascent() const;
367 virtual QFixed descent() const;
368 virtual QFixed leading() const;
369 virtual qreal maxCharWidth() const;
minLeftBearing()370 virtual qreal minLeftBearing() const { return 0; }
minRightBearing()371 virtual qreal minRightBearing() const { return 0; }
372 virtual QImage alphaMapForGlyph(glyph_t);
373
374 #ifdef Q_WS_X11
375 int cmap() const;
376 #endif
377 virtual const char *name() const;
378
379 virtual bool canRender(const QChar *string, int len);
380
381 virtual Type type() const;
size()382 inline int size() const { return _size; }
383
384 private:
385 friend class QFontPrivate;
386 int _size;
387 };
388
389 class QFontEngineMulti : public QFontEngine
390 {
391 public:
392 explicit QFontEngineMulti(int engineCount);
393 ~QFontEngineMulti();
394
395 virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
396 QTextEngine::ShaperFlags flags) const;
397
398 virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
399 virtual glyph_metrics_t boundingBox(glyph_t glyph);
400
401 virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
402 virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
403 virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags);
404 virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
405
406 virtual QFixed ascent() const;
407 virtual QFixed descent() const;
408 virtual QFixed leading() const;
409 virtual QFixed xHeight() const;
410 virtual QFixed averageCharWidth() const;
411 virtual QImage alphaMapForGlyph(glyph_t);
412
413 virtual QFixed lineThickness() const;
414 virtual QFixed underlinePosition() const;
415 virtual qreal maxCharWidth() const;
416 virtual qreal minLeftBearing() const;
417 virtual qreal minRightBearing() const;
418
type()419 virtual inline Type type() const
420 { return QFontEngine::Multi; }
421
422 virtual bool canRender(const QChar *string, int len);
name()423 inline virtual const char *name() const
424 { return "Multi"; }
425
engine(int at)426 QFontEngine *engine(int at) const
427 {Q_ASSERT(at < engines.size()); return engines.at(at); }
428
429
430 protected:
431 friend class QPSPrintEnginePrivate;
432 friend class QPSPrintEngineFontMulti;
433 friend class QRawFont;
434 virtual void loadEngine(int at) = 0;
435 QVector<QFontEngine *> engines;
436 };
437
438 class QTestFontEngine : public QFontEngineBox
439 {
440 public:
QTestFontEngine(int size)441 QTestFontEngine(int size) : QFontEngineBox(size) {}
type()442 virtual Type type() const { return TestFontEngine; }
443 };
444
445 QT_END_NAMESPACE
446
447 #ifdef Q_WS_WIN
448 # include "private/qfontengine_win_p.h"
449 #endif
450
451 #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
452 # include "private/qfontengine_ft_p.h"
453 #endif
454
455 #endif // QFONTENGINE_P_H
456