qfontengine_qpf2.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qfontengine_qpf2.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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#include "qfontengine_qpf2_p.h"-
41-
42#include <QtCore/QFile>-
43#include <QtCore/QFileInfo>-
44#include <QtCore/QDir>-
45#include <QtCore/QBuffer>-
46#include <QtCore/private/qstringiterator_p.h>-
47-
48#include <QtGui/private/qpaintengine_raster_p.h>-
49#include <QtGui/private/qguiapplication_p.h>-
50#include <qpa/qplatformfontdatabase.h>-
51#include <qpa/qplatformintegration.h>-
52-
53QT_BEGIN_NAMESPACE-
54-
55//#define DEBUG_HEADER-
56//#define DEBUG_FONTENGINE-
57-
58static const QFontEngineQPF2::TagType tagTypes[QFontEngineQPF2::NumTags] = {-
59 QFontEngineQPF2::StringType, // FontName-
60 QFontEngineQPF2::StringType, // FileName-
61 QFontEngineQPF2::UInt32Type, // FileIndex-
62 QFontEngineQPF2::UInt32Type, // FontRevision-
63 QFontEngineQPF2::StringType, // FreeText-
64 QFontEngineQPF2::FixedType, // Ascent-
65 QFontEngineQPF2::FixedType, // Descent-
66 QFontEngineQPF2::FixedType, // Leading-
67 QFontEngineQPF2::FixedType, // XHeight-
68 QFontEngineQPF2::FixedType, // AverageCharWidth-
69 QFontEngineQPF2::FixedType, // MaxCharWidth-
70 QFontEngineQPF2::FixedType, // LineThickness-
71 QFontEngineQPF2::FixedType, // MinLeftBearing-
72 QFontEngineQPF2::FixedType, // MinRightBearing-
73 QFontEngineQPF2::FixedType, // UnderlinePosition-
74 QFontEngineQPF2::UInt8Type, // GlyphFormat-
75 QFontEngineQPF2::UInt8Type, // PixelSize-
76 QFontEngineQPF2::UInt8Type, // Weight-
77 QFontEngineQPF2::UInt8Type, // Style-
78 QFontEngineQPF2::StringType, // EndOfHeader-
79 QFontEngineQPF2::BitFieldType// WritingSystems-
80};-
81-
82-
83#if defined(DEBUG_HEADER)-
84# define DEBUG_VERIFY qDebug-
85#else-
86# define DEBUG_VERIFY if (0) qDebug-
87#endif-
88-
89#define READ_VERIFY(type, variable) \-
90 if (tagPtr + sizeof(type) > endPtr) { \-
91 DEBUG_VERIFY() << "read verify failed in line" << __LINE__; \-
92 return 0; \-
93 } \-
94 variable = qFromBigEndian<type>(tagPtr); \-
95 DEBUG_VERIFY() << "read value" << variable << "of type " #type; \-
96 tagPtr += sizeof(type)-
97-
98template <typename T>-
99T readValue(const uchar *&data)-
100{-
101 T value = qFromBigEndian<T>(data);-
102 data += sizeof(T);-
103 return value;
never executed: return value;
0
104}-
105-
106#define VERIFY(condition) \-
107 if (!(condition)) { \-
108 DEBUG_VERIFY() << "condition " #condition " failed in line" << __LINE__; \-
109 return 0; \-
110 }-
111-
112#define VERIFY_TAG(condition) \-
113 if (!(condition)) { \-
114 DEBUG_VERIFY() << "verifying tag condition " #condition " failed in line" << __LINE__ << "with tag" << tag; \-
115 return 0; \-
116 }-
117-
118static inline const uchar *verifyTag(const uchar *tagPtr, const uchar *endPtr)-
119{-
120 quint16 tag, length;-
121 READ_VERIFY(quint16, tag);
never executed: return 0;
tagPtr + sizeo...nt16) > endPtrDescription
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 121, __PRETTY_FUNCTION__).debug() << "read verify failed in line" << 121;
dead code: QMessageLogger(__FILE__, 121, __PRETTY_FUNCTION__).debug() << "read value" << tag << "of type " "quint16";
-
122 READ_VERIFY(quint16, length);
never executed: return 0;
tagPtr + sizeo...nt16) > endPtrDescription
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 122, __PRETTY_FUNCTION__).debug() << "read verify failed in line" << 122;
dead code: QMessageLogger(__FILE__, 122, __PRETTY_FUNCTION__).debug() << "read value" << length << "of type " "quint16";
-
123 if (tag == QFontEngineQPF2::Tag_EndOfHeader)
tag == QFontEn...ag_EndOfHeaderDescription
TRUEnever evaluated
FALSEnever evaluated
0
124 return endPtr;
never executed: return endPtr;
0
125 if (tag < QFontEngineQPF2::NumTags) {
tag < QFontEngineQPF2::NumTagsDescription
TRUEnever evaluated
FALSEnever evaluated
0
126 switch (tagTypes[tag]) {-
127 case QFontEngineQPF2::BitFieldType:
never executed: case QFontEngineQPF2::BitFieldType:
0
128 case QFontEngineQPF2::StringType:
never executed: case QFontEngineQPF2::StringType:
0
129 // can't do anything...-
130 break;
never executed: break;
0
131 case QFontEngineQPF2::UInt32Type:
never executed: case QFontEngineQPF2::UInt32Type:
0
132 VERIFY_TAG(length == sizeof(quint32));
never executed: return 0;
!(length == sizeof(quint32))Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 132, __PRETTY_FUNCTION__).debug() << "verifying tag condition " "length == sizeof(quint32)" " failed in line" << 132 << "with tag" << tag;
-
133 break;
never executed: break;
0
134 case QFontEngineQPF2::FixedType:
never executed: case QFontEngineQPF2::FixedType:
0
135 VERIFY_TAG(length == sizeof(quint32));
never executed: return 0;
!(length == sizeof(quint32))Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 135, __PRETTY_FUNCTION__).debug() << "verifying tag condition " "length == sizeof(quint32)" " failed in line" << 135 << "with tag" << tag;
-
136 break;
never executed: break;
0
137 case QFontEngineQPF2::UInt8Type:
never executed: case QFontEngineQPF2::UInt8Type:
0
138 VERIFY_TAG(length == sizeof(quint8));
never executed: return 0;
!(length == sizeof(quint8))Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 138, __PRETTY_FUNCTION__).debug() << "verifying tag condition " "length == sizeof(quint8)" " failed in line" << 138 << "with tag" << tag;
-
139 break;
never executed: break;
0
140 }-
141#if defined(DEBUG_HEADER)-
142 if (length == 1)-
143 qDebug() << "tag data" << hex << *tagPtr;-
144 else if (length == 4)-
145 qDebug() << "tag data" << hex << tagPtr[0] << tagPtr[1] << tagPtr[2] << tagPtr[3];-
146#endif-
147 }
never executed: end of block
0
148 return tagPtr + length;
never executed: return tagPtr + length;
0
149}-
150-
151const QFontEngineQPF2::Glyph *QFontEngineQPF2::findGlyph(glyph_t g) const-
152{-
153 if (!g || g >= glyphMapEntries)
!gDescription
TRUEnever evaluated
FALSEnever evaluated
g >= glyphMapEntriesDescription
TRUEnever evaluated
FALSEnever evaluated
0
154 return 0;
never executed: return 0;
0
155 const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);-
156 quint32 glyphPos = qFromBigEndian<quint32>(gmapPtr[g]);-
157 if (glyphPos > glyphDataSize) {
glyphPos > glyphDataSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
158 if (glyphPos == 0xffffffff)
glyphPos == 0xffffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
159 return 0;
never executed: return 0;
0
160#if defined(DEBUG_FONTENGINE)-
161 qDebug() << "glyph" << g << "outside of glyphData, remapping font file";-
162#endif-
163 if (glyphPos > glyphDataSize)
glyphPos > glyphDataSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
164 return 0;
never executed: return 0;
0
165 }
never executed: end of block
0
166 return reinterpret_cast<const Glyph *>(fontData + glyphDataOffset + glyphPos);
never executed: return reinterpret_cast<const Glyph *>(fontData + glyphDataOffset + glyphPos);
0
167}-
168-
169bool QFontEngineQPF2::verifyHeader(const uchar *data, int size)-
170{-
171 VERIFY(quintptr(data) % Q_ALIGNOF(Header) == 0);
never executed: return 0;
!(quintptr(dat...(Header) == 0)Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 171, __PRETTY_FUNCTION__).debug() << "condition " "quintptr(data) % Q_ALIGNOF(Header) == 0" " failed in line" << 171;
-
172 VERIFY(size >= int(sizeof(Header)));
never executed: return 0;
!(size >= int(sizeof(Header)))Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 172, __PRETTY_FUNCTION__).debug() << "condition " "size >= int(sizeof(Header))" " failed in line" << 172;
-
173 const Header *header = reinterpret_cast<const Header *>(data);-
174 if (header->magic[0] != 'Q'
header->magic[0] != 'Q'Description
TRUEnever evaluated
FALSEnever evaluated
0
175 || header->magic[1] != 'P'
header->magic[1] != 'P'Description
TRUEnever evaluated
FALSEnever evaluated
0
176 || header->magic[2] != 'F'
header->magic[2] != 'F'Description
TRUEnever evaluated
FALSEnever evaluated
0
177 || header->magic[3] != '2')
header->magic[3] != '2'Description
TRUEnever evaluated
FALSEnever evaluated
0
178 return false;
never executed: return false;
0
179-
180 VERIFY(header->majorVersion <= CurrentMajorVersion);
never executed: return 0;
!(header->majo...tMajorVersion)Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 180, __PRETTY_FUNCTION__).debug() << "condition " "header->majorVersion <= CurrentMajorVersion" " failed in line" << 180;
-
181 const quint16 dataSize = qFromBigEndian<quint16>(header->dataSize);-
182 VERIFY(size >= int(sizeof(Header)) + dataSize);
never executed: return 0;
!(size >= int(...)) + dataSize)Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 182, __PRETTY_FUNCTION__).debug() << "condition " "size >= int(sizeof(Header)) + dataSize" " failed in line" << 182;
-
183-
184 const uchar *tagPtr = data + sizeof(Header);-
185 const uchar *tagEndPtr = tagPtr + dataSize;-
186 while (tagPtr < tagEndPtr - 3) {
tagPtr < tagEndPtr - 3Description
TRUEnever evaluated
FALSEnever evaluated
0
187 tagPtr = verifyTag(tagPtr, tagEndPtr);-
188 VERIFY(tagPtr);
never executed: return 0;
!(tagPtr)Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 188, __PRETTY_FUNCTION__).debug() << "condition " "tagPtr" " failed in line" << 188;
-
189 }
never executed: end of block
0
190-
191 VERIFY(tagPtr <= tagEndPtr);
never executed: return 0;
!(tagPtr <= tagEndPtr)Description
TRUEnever evaluated
FALSEnever evaluated
dead code: QMessageLogger(__FILE__, 191, __PRETTY_FUNCTION__).debug() << "condition " "tagPtr <= tagEndPtr" " failed in line" << 191;
-
192 return true;
never executed: return true;
0
193}-
194-
195QVariant QFontEngineQPF2::extractHeaderField(const uchar *data, HeaderTag requestedTag)-
196{-
197 const Header *header = reinterpret_cast<const Header *>(data);-
198 const uchar *tagPtr = data + sizeof(Header);-
199 const uchar *endPtr = tagPtr + qFromBigEndian<quint16>(header->dataSize);-
200 while (tagPtr < endPtr - 3) {
tagPtr < endPtr - 3Description
TRUEnever evaluated
FALSEnever evaluated
0
201 quint16 tag = readValue<quint16>(tagPtr);-
202 quint16 length = readValue<quint16>(tagPtr);-
203 if (tag == requestedTag) {
tag == requestedTagDescription
TRUEnever evaluated
FALSEnever evaluated
0
204 switch (tagTypes[requestedTag]) {-
205 case StringType:
never executed: case StringType:
0
206 return QVariant(QString::fromUtf8(reinterpret_cast<const char *>(tagPtr), length));
never executed: return QVariant(QString::fromUtf8(reinterpret_cast<const char *>(tagPtr), length));
0
207 case UInt32Type:
never executed: case UInt32Type:
0
208 return QVariant(readValue<quint32>(tagPtr));
never executed: return QVariant(readValue<quint32>(tagPtr));
0
209 case UInt8Type:
never executed: case UInt8Type:
0
210 return QVariant(uint(*tagPtr));
never executed: return QVariant(uint(*tagPtr));
0
211 case FixedType:
never executed: case FixedType:
0
212 return QVariant(QFixed::fromFixed(readValue<quint32>(tagPtr)).toReal());
never executed: return QVariant(QFixed::fromFixed(readValue<quint32>(tagPtr)).toReal());
0
213 case BitFieldType:
never executed: case BitFieldType:
0
214 return QVariant(QByteArray(reinterpret_cast<const char *>(tagPtr), length));
never executed: return QVariant(QByteArray(reinterpret_cast<const char *>(tagPtr), length));
0
215 }-
216 return QVariant();
never executed: return QVariant();
0
217 } else if (tag == Tag_EndOfHeader) {
tag == Tag_EndOfHeaderDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 break;
never executed: break;
0
219 }-
220 tagPtr += length;-
221 }
never executed: end of block
0
222-
223 return QVariant();
never executed: return QVariant();
0
224}-
225-
226-
227QFontEngineQPF2::QFontEngineQPF2(const QFontDef &def, const QByteArray &data)-
228 : QFontEngine(QPF2),-
229 fontData(reinterpret_cast<const uchar *>(data.constData())), dataSize(data.size())-
230{-
231 fontDef = def;-
232 cache_cost = 100;-
233 cmap = 0;-
234 cmapOffset = 0;-
235 cmapSize = 0;-
236 glyphMapOffset = 0;-
237 glyphMapEntries = 0;-
238 glyphDataOffset = 0;-
239 glyphDataSize = 0;-
240 kerning_pairs_loaded = false;-
241 readOnly = true;-
242-
243#if defined(DEBUG_FONTENGINE)-
244 qDebug() << "QFontEngineQPF2::QFontEngineQPF2( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')';-
245#endif-
246-
247 if (!verifyHeader(fontData, dataSize)) {
!verifyHeader(...ata, dataSize)Description
TRUEnever evaluated
FALSEnever evaluated
0
248#if defined(DEBUG_FONTENGINE)-
249 qDebug("verifyHeader failed!");-
250#endif-
251 return;
never executed: return;
0
252 }-
253-
254 const Header *header = reinterpret_cast<const Header *>(fontData);-
255-
256 readOnly = (header->lock == 0xffffffff);-
257-
258 const uchar *imgData = fontData + sizeof(Header) + qFromBigEndian<quint16>(header->dataSize);-
259 const uchar *endPtr = fontData + dataSize;-
260 while (imgData <= endPtr - 8) {
imgData <= endPtr - 8Description
TRUEnever evaluated
FALSEnever evaluated
0
261 quint16 blockTag = readValue<quint16>(imgData);-
262 imgData += 2; // skip padding-
263 quint32 blockSize = readValue<quint32>(imgData);-
264-
265 if (blockTag == CMapBlock) {
blockTag == CMapBlockDescription
TRUEnever evaluated
FALSEnever evaluated
0
266 cmapOffset = imgData - fontData;-
267 cmapSize = blockSize;-
268 } else if (blockTag == GMapBlock) {
never executed: end of block
blockTag == GMapBlockDescription
TRUEnever evaluated
FALSEnever evaluated
0
269 glyphMapOffset = imgData - fontData;-
270 glyphMapEntries = blockSize / 4;-
271 } else if (blockTag == GlyphBlock) {
never executed: end of block
blockTag == GlyphBlockDescription
TRUEnever evaluated
FALSEnever evaluated
0
272 glyphDataOffset = imgData - fontData;-
273 glyphDataSize = blockSize;-
274 }
never executed: end of block
0
275-
276 imgData += blockSize;-
277 }
never executed: end of block
0
278-
279 face_id.filename = QFile::encodeName(extractHeaderField(fontData, Tag_FileName).toString());-
280 face_id.index = extractHeaderField(fontData, Tag_FileIndex).toInt();-
281-
282 // get the real cmap-
283 if (cmapOffset) {
cmapOffsetDescription
TRUEnever evaluated
FALSEnever evaluated
0
284 cmap = QFontEngine::getCMap(fontData + cmapOffset, cmapSize, &symbol, &cmapSize);-
285 cmapOffset = cmap ? cmap - fontData : 0;
cmapDescription
TRUEnever evaluated
FALSEnever evaluated
0
286 }
never executed: end of block
0
287-
288 // verify all the positions in the glyphMap-
289 if (glyphMapOffset) {
glyphMapOffsetDescription
TRUEnever evaluated
FALSEnever evaluated
0
290 const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);-
291 for (uint i = 0; i < glyphMapEntries; ++i) {
i < glyphMapEntriesDescription
TRUEnever evaluated
FALSEnever evaluated
0
292 quint32 glyphDataPos = qFromBigEndian<quint32>(gmapPtr[i]);-
293 if (glyphDataPos == 0xffffffff)
glyphDataPos == 0xffffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
294 continue;
never executed: continue;
0
295 if (glyphDataPos >= glyphDataSize) {
glyphDataPos >= glyphDataSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
296 // error-
297 glyphMapOffset = 0;-
298 glyphMapEntries = 0;-
299 break;
never executed: break;
0
300 }-
301 }
never executed: end of block
0
302 }
never executed: end of block
0
303-
304#if defined(DEBUG_FONTENGINE)-
305 if (!isValid())-
306 qDebug() << "fontData" << fontData << "dataSize" << dataSize-
307 << "cmap" << cmap << "cmapOffset" << cmapOffset-
308 << "glyphMapOffset" << glyphMapOffset << "glyphDataOffset" << glyphDataOffset-
309 << "fd" << fd << "glyphDataSize" << glyphDataSize;-
310#endif-
311}
never executed: end of block
0
312-
313QFontEngineQPF2::~QFontEngineQPF2()-
314{-
315}-
316-
317bool QFontEngineQPF2::getSfntTableData(uint tag, uchar *buffer, uint *length) const-
318{-
319 if (tag != MAKE_TAG('c', 'm', 'a', 'p') || !cmap)
tag != ( (((qu...int32)('p')) )Description
TRUEnever evaluated
FALSEnever evaluated
!cmapDescription
TRUEnever evaluated
FALSEnever evaluated
0
320 return false;
never executed: return false;
0
321-
322 if (buffer && int(*length) >= cmapSize)
bufferDescription
TRUEnever evaluated
FALSEnever evaluated
int(*length) >= cmapSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
323 memcpy(buffer, cmap, cmapSize);
never executed: memcpy(buffer, cmap, cmapSize);
0
324 *length = cmapSize;-
325 Q_ASSERT(int(*length) > 0);-
326 return true;
never executed: return true;
0
327}-
328-
329glyph_t QFontEngineQPF2::glyphIndex(uint ucs4) const-
330{-
331 glyph_t glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);-
332 if (glyph == 0 && symbol && ucs4 < 0x100)
glyph == 0Description
TRUEnever evaluated
FALSEnever evaluated
symbolDescription
TRUEnever evaluated
FALSEnever evaluated
ucs4 < 0x100Description
TRUEnever evaluated
FALSEnever evaluated
0
333 glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
never executed: glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
0
334 if (!findGlyph(glyph))
!findGlyph(glyph)Description
TRUEnever evaluated
FALSEnever evaluated
0
335 glyph = 0;
never executed: glyph = 0;
0
336-
337 return glyph;
never executed: return glyph;
0
338}-
339-
340bool QFontEngineQPF2::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const-
341{-
342 Q_ASSERT(glyphs->numGlyphs >= *nglyphs);-
343 if (*nglyphs < len) {
*nglyphs < lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
344 *nglyphs = len;-
345 return false;
never executed: return false;
0
346 }-
347-
348#if defined(DEBUG_FONTENGINE)-
349 QSet<QChar> seenGlyphs;-
350#endif-
351-
352 int glyph_pos = 0;-
353 if (symbol) {
symbolDescription
TRUEnever evaluated
FALSEnever evaluated
0
354 QStringIterator it(str, str + len);-
355 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
356 const uint uc = it.next();-
357 glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);-
358 if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
!glyphs->glyphs[glyph_pos]Description
TRUEnever evaluated
FALSEnever evaluated
uc < 0x100Description
TRUEnever evaluated
FALSEnever evaluated
0
359 glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
never executed: glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
0
360 ++glyph_pos;-
361 }
never executed: end of block
0
362 } else {
never executed: end of block
0
363 QStringIterator it(str, str + len);-
364 while (it.hasNext()) {
it.hasNext()Description
TRUEnever evaluated
FALSEnever evaluated
0
365 const uint uc = it.next();-
366 glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);-
367#if 0 && defined(DEBUG_FONTENGINE)-
368 QChar c(uc);-
369 if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))-
370 qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph;-
371-
372 seenGlyphs.insert(c);-
373#endif-
374 ++glyph_pos;-
375 }
never executed: end of block
0
376 }
never executed: end of block
0
377-
378 *nglyphs = glyph_pos;-
379 glyphs->numGlyphs = glyph_pos;-
380-
381 if (!(flags & GlyphIndicesOnly))
!(flags & GlyphIndicesOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
382 recalcAdvances(glyphs, flags);
never executed: recalcAdvances(glyphs, flags);
0
383-
384 return true;
never executed: return true;
0
385}-
386-
387void QFontEngineQPF2::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const-
388{-
389 for (int i = 0; i < glyphs->numGlyphs; ++i) {
i < glyphs->numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
390 const Glyph *g = findGlyph(glyphs->glyphs[i]);-
391 if (!g)
!gDescription
TRUEnever evaluated
FALSEnever evaluated
0
392 continue;
never executed: continue;
0
393 glyphs->advances[i] = g->advance;-
394 }
never executed: end of block
0
395}
never executed: end of block
0
396-
397QImage QFontEngineQPF2::alphaMapForGlyph(glyph_t g)-
398{-
399 const Glyph *glyph = findGlyph(g);-
400 if (!glyph)
!glyphDescription
TRUEnever evaluated
FALSEnever evaluated
0
401 return QImage();
never executed: return QImage();
0
402-
403 const uchar *bits = ((const uchar *) glyph) + sizeof(Glyph);-
404-
405 QImage image(bits,glyph->width, glyph->height, glyph->bytesPerLine, QImage::Format_Alpha8);-
406-
407 return image;
never executed: return image;
0
408}-
409-
410void QFontEngineQPF2::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)-
411{-
412 addBitmapFontToPath(x, y, glyphs, path, flags);-
413}
never executed: end of block
0
414-
415glyph_metrics_t QFontEngineQPF2::boundingBox(const QGlyphLayout &glyphs)-
416{-
417 glyph_metrics_t overall;-
418 // initialize with line height, we get the same behaviour on all platforms-
419 overall.y = -ascent();-
420 overall.height = ascent() + descent() + 1;-
421-
422 QFixed ymax = 0;-
423 QFixed xmax = 0;-
424 for (int i = 0; i < glyphs.numGlyphs; i++) {
i < glyphs.numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
425 const Glyph *g = findGlyph(glyphs.glyphs[i]);-
426 if (!g)
!gDescription
TRUEnever evaluated
FALSEnever evaluated
0
427 continue;
never executed: continue;
0
428-
429 QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;-
430 QFixed y = overall.yoff + glyphs.offsets[i].y + g->y;-
431 overall.x = qMin(overall.x, x);-
432 overall.y = qMin(overall.y, y);-
433 xmax = qMax(xmax, x + g->width);-
434 ymax = qMax(ymax, y + g->height);-
435 overall.xoff += g->advance;-
436 }
never executed: end of block
0
437 overall.height = qMax(overall.height, ymax - overall.y);-
438 overall.width = xmax - overall.x;-
439-
440 return overall;
never executed: return overall;
0
441}-
442-
443glyph_metrics_t QFontEngineQPF2::boundingBox(glyph_t glyph)-
444{-
445 glyph_metrics_t overall;-
446 const Glyph *g = findGlyph(glyph);-
447 if (!g)
!gDescription
TRUEnever evaluated
FALSEnever evaluated
0
448 return overall;
never executed: return overall;
0
449 overall.x = g->x;-
450 overall.y = g->y;-
451 overall.width = g->width;-
452 overall.height = g->height;-
453 overall.xoff = g->advance;-
454 return overall;
never executed: return overall;
0
455}-
456-
457QFixed QFontEngineQPF2::ascent() const-
458{-
459 return QFixed::fromReal(extractHeaderField(fontData, Tag_Ascent).value<qreal>());
never executed: return QFixed::fromReal(extractHeaderField(fontData, Tag_Ascent).value<qreal>());
0
460}-
461-
462QFixed QFontEngineQPF2::descent() const-
463{-
464 return QFixed::fromReal(extractHeaderField(fontData, Tag_Descent).value<qreal>());
never executed: return QFixed::fromReal(extractHeaderField(fontData, Tag_Descent).value<qreal>());
0
465}-
466-
467QFixed QFontEngineQPF2::leading() const-
468{-
469 return QFixed::fromReal(extractHeaderField(fontData, Tag_Leading).value<qreal>());
never executed: return QFixed::fromReal(extractHeaderField(fontData, Tag_Leading).value<qreal>());
0
470}-
471-
472qreal QFontEngineQPF2::maxCharWidth() const-
473{-
474 return extractHeaderField(fontData, Tag_MaxCharWidth).value<qreal>();
never executed: return extractHeaderField(fontData, Tag_MaxCharWidth).value<qreal>();
0
475}-
476-
477qreal QFontEngineQPF2::minLeftBearing() const-
478{-
479 return extractHeaderField(fontData, Tag_MinLeftBearing).value<qreal>();
never executed: return extractHeaderField(fontData, Tag_MinLeftBearing).value<qreal>();
0
480}-
481-
482qreal QFontEngineQPF2::minRightBearing() const-
483{-
484 return extractHeaderField(fontData, Tag_MinRightBearing).value<qreal>();
never executed: return extractHeaderField(fontData, Tag_MinRightBearing).value<qreal>();
0
485}-
486-
487QFixed QFontEngineQPF2::underlinePosition() const-
488{-
489 return QFixed::fromReal(extractHeaderField(fontData, Tag_UnderlinePosition).value<qreal>());
never executed: return QFixed::fromReal(extractHeaderField(fontData, Tag_UnderlinePosition).value<qreal>());
0
490}-
491-
492QFixed QFontEngineQPF2::lineThickness() const-
493{-
494 return QFixed::fromReal(extractHeaderField(fontData, Tag_LineThickness).value<qreal>());
never executed: return QFixed::fromReal(extractHeaderField(fontData, Tag_LineThickness).value<qreal>());
0
495}-
496-
497bool QFontEngineQPF2::isValid() const-
498{-
499 return fontData && dataSize && cmapOffset
never executed: return fontData && dataSize && cmapOffset && glyphMapOffset && glyphDataOffset && glyphDataSize > 0;
0
500 && glyphMapOffset && glyphDataOffset && glyphDataSize > 0;
never executed: return fontData && dataSize && cmapOffset && glyphMapOffset && glyphDataOffset && glyphDataSize > 0;
0
501}-
502-
503void QPF2Generator::generate()-
504{-
505 writeHeader();-
506 writeGMap();-
507 writeBlock(QFontEngineQPF2::GlyphBlock, QByteArray());-
508-
509 dev->seek(4); // position of header.lock-
510 writeUInt32(0);-
511}
never executed: end of block
0
512-
513void QPF2Generator::writeHeader()-
514{-
515 QFontEngineQPF2::Header header;-
516-
517 header.magic[0] = 'Q';-
518 header.magic[1] = 'P';-
519 header.magic[2] = 'F';-
520 header.magic[3] = '2';-
521 header.lock = 1;-
522 header.majorVersion = QFontEngineQPF2::CurrentMajorVersion;-
523 header.minorVersion = QFontEngineQPF2::CurrentMinorVersion;-
524 header.dataSize = 0;-
525 dev->write((const char *)&header, sizeof(header));-
526-
527 writeTaggedString(QFontEngineQPF2::Tag_FontName, fe->fontDef.family.toUtf8());-
528-
529 QFontEngine::FaceId face = fe->faceId();-
530 writeTaggedString(QFontEngineQPF2::Tag_FileName, face.filename);-
531 writeTaggedUInt32(QFontEngineQPF2::Tag_FileIndex, face.index);-
532-
533 {-
534 const QByteArray head = fe->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));-
535 if (head.size() >= 4) {
head.size() >= 4Description
TRUEnever evaluated
FALSEnever evaluated
0
536 const quint32 revision = qFromBigEndian<quint32>(head.constData());-
537 writeTaggedUInt32(QFontEngineQPF2::Tag_FontRevision, revision);-
538 }
never executed: end of block
0
539 }-
540-
541 writeTaggedQFixed(QFontEngineQPF2::Tag_Ascent, fe->ascent());-
542 writeTaggedQFixed(QFontEngineQPF2::Tag_Descent, fe->descent());-
543 writeTaggedQFixed(QFontEngineQPF2::Tag_Leading, fe->leading());-
544 writeTaggedQFixed(QFontEngineQPF2::Tag_XHeight, fe->xHeight());-
545 writeTaggedQFixed(QFontEngineQPF2::Tag_AverageCharWidth, fe->averageCharWidth());-
546 writeTaggedQFixed(QFontEngineQPF2::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth()));-
547 writeTaggedQFixed(QFontEngineQPF2::Tag_LineThickness, fe->lineThickness());-
548 writeTaggedQFixed(QFontEngineQPF2::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing()));-
549 writeTaggedQFixed(QFontEngineQPF2::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing()));-
550 writeTaggedQFixed(QFontEngineQPF2::Tag_UnderlinePosition, fe->underlinePosition());-
551 writeTaggedUInt8(QFontEngineQPF2::Tag_PixelSize, fe->fontDef.pixelSize);-
552 writeTaggedUInt8(QFontEngineQPF2::Tag_Weight, fe->fontDef.weight);-
553 writeTaggedUInt8(QFontEngineQPF2::Tag_Style, fe->fontDef.style);-
554-
555 writeTaggedUInt8(QFontEngineQPF2::Tag_GlyphFormat, QFontEngineQPF2::AlphamapGlyphs);-
556-
557 writeTaggedString(QFontEngineQPF2::Tag_EndOfHeader, QByteArray());-
558 align4();-
559-
560 const quint64 size = dev->pos();-
561 header.dataSize = qToBigEndian<quint16>(size - sizeof(header));-
562 dev->seek(0);-
563 dev->write((const char *)&header, sizeof(header));-
564 dev->seek(size);-
565}
never executed: end of block
0
566-
567void QPF2Generator::writeGMap()-
568{-
569 const quint16 glyphCount = fe->glyphCount();-
570-
571 writeUInt16(QFontEngineQPF2::GMapBlock);-
572 writeUInt16(0); // padding-
573 writeUInt32(glyphCount * 4);-
574-
575 QByteArray &buffer = dev->buffer();-
576 const int numBytes = glyphCount * sizeof(quint32);-
577 qint64 pos = buffer.size();-
578 buffer.resize(pos + numBytes);-
579 memset(buffer.data() + pos, 0xff, numBytes);-
580 dev->seek(pos + numBytes);-
581}
never executed: end of block
0
582-
583void QPF2Generator::writeBlock(QFontEngineQPF2::BlockTag tag, const QByteArray &data)-
584{-
585 writeUInt16(tag);-
586 writeUInt16(0); // padding-
587 const int padSize = ((data.size() + 3) / 4) * 4 - data.size();-
588 writeUInt32(data.size() + padSize);-
589 dev->write(data);-
590 for (int i = 0; i < padSize; ++i)
i < padSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
591 writeUInt8(0);
never executed: writeUInt8(0);
0
592}
never executed: end of block
0
593-
594void QPF2Generator::writeTaggedString(QFontEngineQPF2::HeaderTag tag, const QByteArray &string)-
595{-
596 writeUInt16(tag);-
597 writeUInt16(string.length());-
598 dev->write(string);-
599}
never executed: end of block
0
600-
601void QPF2Generator::writeTaggedUInt32(QFontEngineQPF2::HeaderTag tag, quint32 value)-
602{-
603 writeUInt16(tag);-
604 writeUInt16(sizeof(value));-
605 writeUInt32(value);-
606}
never executed: end of block
0
607-
608void QPF2Generator::writeTaggedUInt8(QFontEngineQPF2::HeaderTag tag, quint8 value)-
609{-
610 writeUInt16(tag);-
611 writeUInt16(sizeof(value));-
612 writeUInt8(value);-
613}
never executed: end of block
0
614-
615void QPF2Generator::writeTaggedQFixed(QFontEngineQPF2::HeaderTag tag, QFixed value)-
616{-
617 writeUInt16(tag);-
618 writeUInt16(sizeof(quint32));-
619 writeUInt32(value.value());-
620}
never executed: end of block
0
621-
622QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9