1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://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 https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QFONTENGINE_QPF2_P_H
41 #define QFONTENGINE_QPF2_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 #include <QtCore/qconfig.h>
54 #include <QtCore/qglobal.h>
55 #include <QtCore/qendian.h>
56 #include <QtCore/QBuffer>
57 
58 #include "qfontengine_p.h"
59 
60 #include <QtCore/QFile>
61 
62 QT_BEGIN_NAMESPACE
63 
64 class QFontEngine;
65 class QFreetypeFace;
66 class QBuffer;
67 
68 class Q_GUI_EXPORT QFontEngineQPF2 : public QFontEngine
69 {
70 public:
71     // if you add new tags please make sure to update the tables in
72     // qpfutil.cpp and tools/makeqpf/qpf2.cpp
73     enum HeaderTag {
74         Tag_FontName,          // 0 string
75         Tag_FileName,          // 1 string
76         Tag_FileIndex,         // 2 quint32
77         Tag_FontRevision,      // 3 quint32
78         Tag_FreeText,          // 4 string
79         Tag_Ascent,            // 5 QFixed
80         Tag_Descent,           // 6 QFixed
81         Tag_Leading,           // 7 QFixed
82         Tag_XHeight,           // 8 QFixed
83         Tag_AverageCharWidth,  // 9 QFixed
84         Tag_MaxCharWidth,      // 10 QFixed
85         Tag_LineThickness,     // 11 QFixed
86         Tag_MinLeftBearing,    // 12 QFixed
87         Tag_MinRightBearing,   // 13 QFixed
88         Tag_UnderlinePosition, // 14 QFixed
89         Tag_GlyphFormat,       // 15 quint8
90         Tag_PixelSize,         // 16 quint8
91         Tag_Weight,            // 17 quint8
92         Tag_Style,             // 18 quint8
93         Tag_EndOfHeader,       // 19 string
94         Tag_WritingSystems,    // 20 bitfield
95 
96         NumTags
97     };
98 
99     enum TagType {
100         StringType,
101         FixedType,
102         UInt8Type,
103         UInt32Type,
104         BitFieldType
105     };
106 
107     struct Tag
108     {
109         quint16 tag;
110         quint16 size;
111     };
112 
113     enum GlyphFormat {
114         BitmapGlyphs = 1,
115         AlphamapGlyphs = 8
116     };
117 
118     enum {
119         CurrentMajorVersion = 2,
120         CurrentMinorVersion = 0
121     };
122 
123     // The CMap is identical to the TrueType CMap table format
124     // The GMap table is a normal array with the total number of
125     // covered glyphs in the TrueType font
126     enum BlockTag {
127         CMapBlock,
128         GMapBlock,
129         GlyphBlock
130     };
131 
132     struct Header
133     {
134         char magic[4]; // 'QPF2'
135         quint32 lock;  // values: 0 = unlocked, 0xffffffff = read-only, otherwise qws client id of locking process
136         quint8 majorVersion;
137         quint8 minorVersion;
138         quint16 dataSize;
139     };
140 
141     struct Block
142     {
143         quint16 tag;
144         quint16 pad;
145         quint32 dataSize;
146     };
147 
148     struct Glyph
149     {
150         quint8 width;
151         quint8 height;
152         quint8 bytesPerLine;
153         qint8 x;
154         qint8 y;
155         qint8 advance;
156     };
157 
158     QFontEngineQPF2(const QFontDef &def, const QByteArray &data);
159     ~QFontEngineQPF2();
160 
faceId()161     FaceId faceId() const override { return face_id; }
162     bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
163 
164     virtual glyph_t glyphIndex(uint ucs4) const override;
165     bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
166     void recalcAdvances(QGlyphLayout *, ShaperFlags) const override;
167 
168     void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) override;
169     QImage alphaMapForGlyph(glyph_t t) override;
170 
171     glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
172     glyph_metrics_t boundingBox(glyph_t glyph) override;
173 
174     QFixed ascent() const override;
175     QFixed capHeight() const override;
176     QFixed descent() const override;
177     QFixed leading() const override;
178     qreal maxCharWidth() const override;
179     qreal minLeftBearing() const override;
180     qreal minRightBearing() const override;
181     QFixed underlinePosition() const override;
182     QFixed lineThickness() const override;
183 
glyphCount()184     virtual int glyphCount() const override { return glyphMapEntries; }
185 
186     bool isValid() const;
187 
188     const Glyph *findGlyph(glyph_t g) const;
189 
190     static bool verifyHeader(const uchar *data, int size);
191     static QVariant extractHeaderField(const uchar *data, HeaderTag tag);
192 
193 private:
194 
195     const uchar *fontData;
196     int dataSize;
197     const uchar *cmap;
198     quint32 cmapOffset;
199     int cmapSize;
200     quint32 glyphMapOffset;
201     quint32 glyphMapEntries;
202     quint32 glyphDataOffset;
203     quint32 glyphDataSize;
204     QString internalFileName;
205     QString encodedFileName;
206     bool readOnly;
207 
208     FaceId face_id;
209     QByteArray freetypeCMapTable;
210     mutable bool kerning_pairs_loaded;
211 };
212 
213 struct QPF2Generator
214 {
QPF2GeneratorQPF2Generator215     QPF2Generator(QBuffer *device, QFontEngine *engine)
216         : dev(device), fe(engine) {}
217 
218     void generate();
219     void writeHeader();
220     void writeGMap();
221     void writeBlock(QFontEngineQPF2::BlockTag tag, const QByteArray &data);
222 
223     void writeTaggedString(QFontEngineQPF2::HeaderTag tag, const QByteArray &string);
224     void writeTaggedUInt32(QFontEngineQPF2::HeaderTag tag, quint32 value);
225     void writeTaggedUInt8(QFontEngineQPF2::HeaderTag tag, quint8 value);
226     void writeTaggedQFixed(QFontEngineQPF2::HeaderTag tag, QFixed value);
227 
writeUInt16QPF2Generator228     void writeUInt16(quint16 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); }
writeUInt32QPF2Generator229     void writeUInt32(quint32 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); }
writeUInt8QPF2Generator230     void writeUInt8(quint8 value) { dev->write((const char *)&value, sizeof(value)); }
writeInt8QPF2Generator231     void writeInt8(qint8 value) { dev->write((const char *)&value, sizeof(value)); }
232 
align4QPF2Generator233     void align4() { while (dev->pos() & 3) { dev->putChar('\0'); } }
234 
235     QBuffer *dev;
236     QFontEngine *fe;
237 };
238 
239 QT_END_NAMESPACE
240 
241 #endif // QFONTENGINE_QPF2_P_H
242