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