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