1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtGui module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
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;
153
    virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const { return false; }
154
155
    struct FaceId {
156
        FaceId() : index(0), encoding(0) {}
157
        QByteArray filename;
158
        QByteArray uuid;
159
        int index;
160
        int encoding;
161
    };
162
    virtual FaceId faceId() const { return FaceId(); }
163
    enum SynthesizedFlags {
164
        SynthesizedItalic = 0x1,
165
        SynthesizedBold = 0x2,
166
        SynthesizedStretch = 0x4
167
    };
168
    virtual int synthesized() const { return 0; }
169
    virtual bool supportsSubPixelPositions() const { return false; }
170
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
     */
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
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;
226
    virtual qreal minLeftBearing() const { return qreal(); }
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
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, 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
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);
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;
370
    virtual qreal minLeftBearing() const { return 0; }
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;
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
419
    virtual inline Type type() const
420
    { return QFontEngine::Multi; }
421
422
    virtual bool canRender(const QChar *string, int len);
423
    inline virtual const char *name() const
424
    { return "Multi"; }
425
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:
441
    QTestFontEngine(int size) : QFontEngineBox(size) {}
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