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

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