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_QPA_P_H
43 #define QFONTENGINE_QPA_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 #include <QtCore/qconfig.h>
56 #include <QtCore/qglobal.h>
57 #include <QtCore/qendian.h>
58 #include <QtCore/QBuffer>
59 
60 #include "qfontengine_p.h"
61 
62 #include <QtCore/QFile>
63 
64 QT_BEGIN_HEADER
65 
66 QT_BEGIN_NAMESPACE
67 
68 class QFontEngine;
69 class QFreetypeFace;
70 class QBuffer;
71 
72 class Q_GUI_EXPORT QFontEngineQPA : public QFontEngine
73 {
74 public:
75     // if you add new tags please make sure to update the tables in
76     // qpfutil.cpp and tools/makeqpf/qpf2.cpp
77     enum HeaderTag {
78         Tag_FontName,          // 0 string
79         Tag_FileName,          // 1 string
80         Tag_FileIndex,         // 2 quint32
81         Tag_FontRevision,      // 3 quint32
82         Tag_FreeText,          // 4 string
83         Tag_Ascent,            // 5 QFixed
84         Tag_Descent,           // 6 QFixed
85         Tag_Leading,           // 7 QFixed
86         Tag_XHeight,           // 8 QFixed
87         Tag_AverageCharWidth,  // 9 QFixed
88         Tag_MaxCharWidth,      // 10 QFixed
89         Tag_LineThickness,     // 11 QFixed
90         Tag_MinLeftBearing,    // 12 QFixed
91         Tag_MinRightBearing,   // 13 QFixed
92         Tag_UnderlinePosition, // 14 QFixed
93         Tag_GlyphFormat,       // 15 quint8
94         Tag_PixelSize,         // 16 quint8
95         Tag_Weight,            // 17 quint8
96         Tag_Style,             // 18 quint8
97         Tag_EndOfHeader,       // 19 string
98         Tag_WritingSystems,    // 20 bitfield
99 
100         NumTags
101     };
102 
103     enum TagType {
104         StringType,
105         FixedType,
106         UInt8Type,
107         UInt32Type,
108         BitFieldType
109     };
110 
111     struct Tag
112     {
113         quint16 tag;
114         quint16 size;
115     };
116 
117     enum GlyphFormat {
118         BitmapGlyphs = 1,
119         AlphamapGlyphs = 8
120     };
121 
122     enum {
123         CurrentMajorVersion = 2,
124         CurrentMinorVersion = 0
125     };
126 
127     // The CMap is identical to the TrueType CMap table format
128     // The GMap table is a normal array with the total number of
129     // covered glyphs in the TrueType font
130     enum BlockTag {
131         CMapBlock,
132         GMapBlock,
133         GlyphBlock
134     };
135 
136     struct Q_PACKED Header
137     {
138         char magic[4]; // 'QPF2'
139         quint32 lock;  // values: 0 = unlocked, 0xffffffff = read-only, otherwise qws client id of locking process
140         quint8 majorVersion;
141         quint8 minorVersion;
142         quint16 dataSize;
143     };
144 
145     struct Q_PACKED Block
146     {
147         quint16 tag;
148         quint16 pad;
149         quint32 dataSize;
150     };
151 
152     struct Q_PACKED Glyph
153     {
154         quint8 width;
155         quint8 height;
156         quint8 bytesPerLine;
157         qint8 x;
158         qint8 y;
159         qint8 advance;
160     };
161 
162     QFontEngineQPA(const QFontDef &def, const QByteArray &data);
163     ~QFontEngineQPA();
164 
faceId()165     FaceId faceId() const { return face_id; }
166     bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
167 
168     bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
169     void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
170 
171     void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
172     QImage alphaMapForGlyph(glyph_t t);
173 
174     glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
175     glyph_metrics_t boundingBox(glyph_t glyph);
176 
177     QFixed ascent() const;
178     QFixed descent() const;
179     QFixed leading() const;
180     qreal maxCharWidth() const;
181     qreal minLeftBearing() const;
182     qreal minRightBearing() const;
183     QFixed underlinePosition() const;
184     QFixed lineThickness() const;
185 
186     Type type() const;
187 
188     bool canRender(const QChar *string, int len);
name()189     inline const char *name() const { return "QPF2"; }
190 
glyphCount()191     virtual int glyphCount() const { return glyphMapEntries; }
192 
193     bool isValid() const;
194 
195     const Glyph *findGlyph(glyph_t g) const;
196 
197     static bool verifyHeader(const uchar *data, int size);
198     static QVariant extractHeaderField(const uchar *data, HeaderTag tag);
199 
200 private:
201 
202     const uchar *fontData;
203     int dataSize;
204     const uchar *externalCMap;
205     quint32 cmapOffset;
206     int cmapSize;
207     quint32 glyphMapOffset;
208     quint32 glyphMapEntries;
209     quint32 glyphDataOffset;
210     quint32 glyphDataSize;
211     QString internalFileName;
212     QString encodedFileName;
213     bool readOnly;
214 
215     FaceId face_id;
216     QByteArray freetypeCMapTable;
217     mutable bool kerning_pairs_loaded;
218 };
219 
220 struct QPAGenerator
221 {
QPAGeneratorQPAGenerator222     QPAGenerator(QBuffer *device, QFontEngine *engine)
223         : dev(device), fe(engine) {}
224 
225     void generate();
226     void writeHeader();
227     void writeGMap();
228     void writeBlock(QFontEngineQPA::BlockTag tag, const QByteArray &data);
229 
230     void writeTaggedString(QFontEngineQPA::HeaderTag tag, const QByteArray &string);
231     void writeTaggedUInt32(QFontEngineQPA::HeaderTag tag, quint32 value);
232     void writeTaggedUInt8(QFontEngineQPA::HeaderTag tag, quint8 value);
233     void writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value);
234 
writeUInt16QPAGenerator235     void writeUInt16(quint16 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); }
writeUInt32QPAGenerator236     void writeUInt32(quint32 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); }
writeUInt8QPAGenerator237     void writeUInt8(quint8 value) { dev->write((const char *)&value, sizeof(value)); }
writeInt8QPAGenerator238     void writeInt8(qint8 value) { dev->write((const char *)&value, sizeof(value)); }
239 
align4QPAGenerator240     void align4() { while (dev->pos() & 3) { dev->putChar('\0'); } }
241 
242     QBuffer *dev;
243     QFontEngine *fe;
244 };
245 
246 class QFontEngineMultiQPA : public QFontEngineMulti
247 {
248 public:
249     QFontEngineMultiQPA(QFontEngine *fe, int script, const QStringList &fallbacks);
250 
251     void loadEngine(int at);
252 
253 private:
254     QStringList fallbackFamilies;
255     int script;
256 };
257 
258 QT_END_NAMESPACE
259 
260 QT_END_HEADER
261 
262 #endif // QFONTENGINE_QPA_P_H
263