]> git.pld-linux.org Git - packages/qt4.git/blame - Better-handling-of-invalid-font-tables.patch
icu rebuild
[packages/qt4.git] / Better-handling-of-invalid-font-tables.patch
CommitLineData
519bda15
AM
1From 0a2f2382541424726168804be2c90b91381608c6 Mon Sep 17 00:00:00 2001
2From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
3Date: Fri, 10 Jul 2015 13:22:32 +0200
4Subject: [PATCH] Better handling of invalid font tables
5
6Specifically when reading files with broken cmap tables, we could
7get some undeterministic results. We handle this more gracefully
8by verifying that the offsets are sane and bailing out early if not.
9This replaces the current pattern throughout the font engine for
10consistency.
11
12This is a back-port of 4a1e5dbade4bab55f39bd368480dcca9a11e4b38
13from Qt 5.
14
15Change-Id: If4172b9ef0808801c8e27ffaad962535afe572ed
16Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
17Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
18---
19 src/gui/text/qfontengine.cpp | 212 +++++++++++++++++++++++++++++----------
20 src/gui/text/qfontengine_mac.mm | 11 +-
21 src/gui/text/qfontengine_mac_p.h | 1 +
22 src/gui/text/qfontengine_p.h | 2 +-
23 src/gui/text/qfontengine_qpa.cpp | 12 +--
24 src/gui/text/qfontengine_qpf.cpp | 12 +--
25 src/gui/text/qfontengine_s60.cpp | 9 +-
26 src/gui/text/qfontengine_s60_p.h | 1 +
27 src/gui/text/qfontengine_win.cpp | 22 ++--
28 src/gui/text/qfontengine_win_p.h | 1 +
29 10 files changed, 198 insertions(+), 85 deletions(-)
30
31diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
32index 67b8798..3f7d831 100644
33--- a/src/gui/text/qfontengine.cpp
34+++ b/src/gui/text/qfontengine.cpp
35@@ -69,6 +69,16 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr
36 }
37 }
38
39+template<typename T>
40+static inline bool qSafeFromBigEndian(const uchar *source, const uchar *end, T *output)
41+{
42+ if (source + sizeof(T) > end)
43+ return false;
44+
45+ *output = qFromBigEndian<T>(source);
46+ return true;
47+}
48+
49 // Harfbuzz helper functions
50
51 static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)
52@@ -808,26 +818,38 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
53 return;
54
55 const uchar *table = reinterpret_cast<const uchar *>(tab.constData());
56+ const uchar *end = table + tab.size();
57+
58+ quint16 version;
59+ if (!qSafeFromBigEndian(table, end, &version))
60+ return;
61
62- unsigned short version = qFromBigEndian<quint16>(table);
63 if (version != 0) {
64 // qDebug("wrong version");
65 return;
66 }
67
68- unsigned short numTables = qFromBigEndian<quint16>(table + 2);
69+ quint16 numTables;
70+ if (!qSafeFromBigEndian(table + 2, end, &numTables))
71+ return;
72+
73 {
74 int offset = 4;
75 for(int i = 0; i < numTables; ++i) {
76- if (offset + 6 > tab.size()) {
77-// qDebug("offset out of bounds");
78- goto end;
79- }
80 const uchar *header = table + offset;
81
82- ushort version = qFromBigEndian<quint16>(header);
83- ushort length = qFromBigEndian<quint16>(header+2);
84- ushort coverage = qFromBigEndian<quint16>(header+4);
85+ quint16 version;
86+ if (!qSafeFromBigEndian(header, end, &version))
87+ goto end;
88+
89+ quint16 length;
90+ if (!qSafeFromBigEndian(header + 2, end, &length))
91+ goto end;
92+
93+ quint16 coverage;
94+ if (!qSafeFromBigEndian(header + 4, end, &coverage))
95+ goto end;
96+
97 // qDebug("subtable: version=%d, coverage=%x",version, coverage);
98 if(version == 0 && coverage == 0x0001) {
99 if (offset + length > tab.size()) {
100@@ -836,7 +858,10 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
101 }
102 const uchar *data = table + offset + 6;
103
104- ushort nPairs = qFromBigEndian<quint16>(data);
105+ quint16 nPairs;
106+ if (!qSafeFromBigEndian(data, end, &nPairs))
107+ goto end;
108+
109 if(nPairs * 6 + 8 > length - 6) {
110 // qDebug("corrupt table!");
111 // corrupt table
112@@ -846,8 +871,21 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
113 int off = 8;
114 for(int i = 0; i < nPairs; ++i) {
115 QFontEngine::KernPair p;
116- p.left_right = (((uint)qFromBigEndian<quint16>(data+off)) << 16) + qFromBigEndian<quint16>(data+off+2);
117- p.adjust = QFixed(((int)(short)qFromBigEndian<quint16>(data+off+4))) / scalingFactor;
118+
119+ quint16 tmp;
120+ if (!qSafeFromBigEndian(data + off, end, &tmp))
121+ goto end;
122+
123+ p.left_right = uint(tmp) << 16;
124+ if (!qSafeFromBigEndian(data + off + 2, end, &tmp))
125+ goto end;
126+
127+ p.left_right |= tmp;
128+
129+ if (!qSafeFromBigEndian(data + off + 4, end, &tmp))
130+ goto end;
131+
132+ p.adjust = QFixed(int(short(tmp))) / scalingFactor;
133 kerning_pairs.append(p);
134 off += 6;
135 }
136@@ -872,26 +910,31 @@ int QFontEngine::glyphCount() const
137 QByteArray maxpTable = getSfntTable(MAKE_TAG('m', 'a', 'x', 'p'));
138 if (maxpTable.size() < 6)
139 return 0;
140- return qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(maxpTable.constData() + 4));
141+
142+ const uchar *source = reinterpret_cast<const uchar *>(maxpTable.constData() + 4);
143+ const uchar *end = source + maxpTable.size();
144+
145+ quint16 count = 0;
146+ qSafeFromBigEndian(source, end, &count);
147+ return count;
148 }
149
150 const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize)
151 {
152 const uchar *header = table;
153- if (tableSize < 4)
154- return 0;
155-
156 const uchar *endPtr = table + tableSize;
157
158 // version check
159- if (qFromBigEndian<quint16>(header) != 0)
160+ quint16 version;
161+ if (!qSafeFromBigEndian(header, endPtr, &version) || version != 0)
162 return 0;
163
164- unsigned short numTables = qFromBigEndian<quint16>(header + 2);
165- const uchar *maps = table + 4;
166- if (maps + 8 * numTables > endPtr)
167+ quint16 numTables;
168+ if (!qSafeFromBigEndian(header + 2, endPtr, &numTables))
169 return 0;
170
171+ const uchar *maps = table + 4;
172+
173 enum {
174 Invalid,
175 AppleRoman,
176@@ -906,8 +949,14 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
177 int tableToUse = -1;
178 int score = Invalid;
179 for (int n = 0; n < numTables; ++n) {
180- const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);
181- const quint16 platformSpecificId = qFromBigEndian<quint16>(maps + 8 * n + 2);
182+ quint16 platformId;
183+ if (!qSafeFromBigEndian(maps + 8 * n, endPtr, &platformId))
184+ return 0;
185+
186+ quint16 platformSpecificId;
187+ if (!qSafeFromBigEndian(maps + 8 * n + 2, endPtr, &platformSpecificId))
188+ return 0;
189+
190 switch (platformId) {
191 case 0: // Unicode
192 if (score < Unicode &&
193@@ -961,20 +1010,30 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
194 resolveTable:
195 *isSymbolFont = (symbolTable > -1);
196
197- unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);
198+ quint32 unicode_table;
199+ if (!qSafeFromBigEndian(maps + 8 * tableToUse + 4, endPtr, &unicode_table))
200+ return 0;
201
202- if (!unicode_table || unicode_table + 8 > tableSize)
203+ if (!unicode_table)
204 return 0;
205
206 // get the header of the unicode table
207 header = table + unicode_table;
208
209- unsigned short format = qFromBigEndian<quint16>(header);
210- unsigned int length;
211- if(format < 8)
212- length = qFromBigEndian<quint16>(header + 2);
213- else
214- length = qFromBigEndian<quint32>(header + 4);
215+ quint16 format;
216+ if (!qSafeFromBigEndian(header, endPtr, &format))
217+ return 0;
218+
219+ quint32 length;
220+ if (format < 8) {
221+ quint16 tmp;
222+ if (!qSafeFromBigEndian(header + 2, endPtr, &tmp))
223+ return 0;
224+ length = tmp;
225+ } else {
226+ if (!qSafeFromBigEndian(header + 4, endPtr, &length))
227+ return 0;
228+ }
229
230 if (table + unicode_table + length > endPtr)
231 return 0;
232@@ -989,7 +1048,7 @@ resolveTable:
233 // Check that none of the latin1 range are in the unicode table
234 bool unicodeTableHasLatin1 = false;
235 for (int uc=0x00; uc<0x100; ++uc) {
236- if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
237+ if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
238 unicodeTableHasLatin1 = true;
239 break;
240 }
241@@ -999,7 +1058,7 @@ resolveTable:
242 bool unicodeTableHasSymbols = false;
243 if (!unicodeTableHasLatin1) {
244 for (int uc=0xf000; uc<0xf100; ++uc) {
245- if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
246+ if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
247 unicodeTableHasSymbols = true;
248 break;
249 }
250@@ -1017,12 +1076,17 @@ resolveTable:
251 return table + unicode_table;
252 }
253
254-quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
255+quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode)
256 {
257- unsigned short format = qFromBigEndian<quint16>(cmap);
258+ const uchar *end = cmap + cmapSize;
259+ quint16 format;
260+ if (!qSafeFromBigEndian(cmap, end, &format))
261+ return 0;
262+
263 if (format == 0) {
264- if (unicode < 256)
265- return (int) *(cmap+6+unicode);
266+ const uchar *ptr = cmap + 6 + unicode;
267+ if (unicode < 256 && ptr < end)
268+ return quint32(*ptr);
269 } else if (format == 4) {
270 /* some fonts come with invalid cmap tables, where the last segment
271 specified end = start = rangeoffset = 0xffff, delta = 0x0001
272@@ -1031,25 +1095,49 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
273 */
274 if(unicode >= 0xffff)
275 return 0;
276- quint16 segCountX2 = qFromBigEndian<quint16>(cmap + 6);
277+
278+ quint16 segCountX2;
279+ if (!qSafeFromBigEndian(cmap + 6, end, &segCountX2))
280+ return 0;
281+
282 const unsigned char *ends = cmap + 14;
283+
284 int i = 0;
285- for (; i < segCountX2/2 && qFromBigEndian<quint16>(ends + 2*i) < unicode; i++) {}
286+ for (; i < segCountX2/2; ++i) {
287+ quint16 codePoint;
288+ if (!qSafeFromBigEndian(ends + 2 * i, end, &codePoint))
289+ return 0;
290+ if (codePoint >= unicode)
291+ break;
292+ }
293
294 const unsigned char *idx = ends + segCountX2 + 2 + 2*i;
295- quint16 startIndex = qFromBigEndian<quint16>(idx);
296
297+ quint16 startIndex;
298+ if (!qSafeFromBigEndian(idx, end, &startIndex))
299+ return 0;
300 if (startIndex > unicode)
301 return 0;
302
303 idx += segCountX2;
304- qint16 idDelta = (qint16)qFromBigEndian<quint16>(idx);
305+
306+ quint16 tmp;
307+ if (!qSafeFromBigEndian(idx, end, &tmp))
308+ return 0;
309+ qint16 idDelta = qint16(tmp);
310+
311 idx += segCountX2;
312- quint16 idRangeoffset_t = (quint16)qFromBigEndian<quint16>(idx);
313+
314+ quint16 idRangeoffset_t;
315+ if (!qSafeFromBigEndian(idx, end, &idRangeoffset_t))
316+ return 0;
317
318 quint16 glyphIndex;
319 if (idRangeoffset_t) {
320- quint16 id = qFromBigEndian<quint16>(idRangeoffset_t + 2*(unicode - startIndex) + idx);
321+ quint16 id;
322+ if (!qSafeFromBigEndian(idRangeoffset_t + 2 * (unicode - startIndex) + idx, end, &id))
323+ return 0;
324+
325 if (id)
326 glyphIndex = (idDelta + id) % 0x10000;
327 else
328@@ -1059,13 +1147,19 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
329 }
330 return glyphIndex;
331 } else if (format == 6) {
332- quint16 tableSize = qFromBigEndian<quint16>(cmap + 2);
333+ quint16 tableSize;
334+ if (!qSafeFromBigEndian(cmap + 2, end, &tableSize))
335+ return 0;
336
337- quint16 firstCode6 = qFromBigEndian<quint16>(cmap + 6);
338+ quint16 firstCode6;
339+ if (!qSafeFromBigEndian(cmap + 6, end, &firstCode6))
340+ return 0;
341 if (unicode < firstCode6)
342 return 0;
343
344- quint16 entryCount6 = qFromBigEndian<quint16>(cmap + 8);
345+ quint16 entryCount6;
346+ if (!qSafeFromBigEndian(cmap + 8, end, &entryCount6))
347+ return 0;
348 if (entryCount6 * 2 + 10 > tableSize)
349 return 0;
350
351@@ -1074,9 +1168,14 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
352 return 0;
353
354 quint16 entryIndex6 = unicode - firstCode6;
355- return qFromBigEndian<quint16>(cmap + 10 + (entryIndex6 * 2));
356+
357+ quint16 index = 0;
358+ qSafeFromBigEndian(cmap + 10 + (entryIndex6 * 2), end, &index);
359+ return index;
360 } else if (format == 12) {
361- quint32 nGroups = qFromBigEndian<quint32>(cmap + 12);
362+ quint32 nGroups;
363+ if (!qSafeFromBigEndian(cmap + 12, end, &nGroups))
364+ return 0;
365
366 cmap += 16; // move to start of groups
367
368@@ -1084,13 +1183,24 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
369 while (left <= right) {
370 int middle = left + ( ( right - left ) >> 1 );
371
372- quint32 startCharCode = qFromBigEndian<quint32>(cmap + 12*middle);
373+ quint32 startCharCode;
374+ if (!qSafeFromBigEndian(cmap + 12 * middle, end, &startCharCode))
375+ return 0;
376+
377 if(unicode < startCharCode)
378 right = middle - 1;
379 else {
380- quint32 endCharCode = qFromBigEndian<quint32>(cmap + 12*middle + 4);
381- if(unicode <= endCharCode)
382- return qFromBigEndian<quint32>(cmap + 12*middle + 8) + unicode - startCharCode;
383+ quint32 endCharCode;
384+ if (!qSafeFromBigEndian(cmap + 12 * middle + 4, end, &endCharCode))
385+ return 0;
386+
387+ if (unicode <= endCharCode) {
388+ quint32 index;
389+ if (!qSafeFromBigEndian(cmap + 12 * middle + 8, end, &index))
390+ return 0;
391+
392+ return index + unicode - startCharCode;
393+ }
394 left = middle + 1;
395 }
396 }
397diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
398index ba01f4c..460aa5f 100644
399--- a/src/gui/text/qfontengine_mac.mm
400+++ b/src/gui/text/qfontengine_mac.mm
401@@ -625,7 +625,7 @@ bool QFontEngineMacMulti::canRender(const QChar *string, int len)
402 }
403
404 QFontEngineMac::QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine)
405- : fontID(fontID), multiEngine(multiEngine), cmap(0), symbolCMap(false)
406+ : fontID(fontID), multiEngine(multiEngine), cmap(0), symbolCMap(false), cmapSize(0)
407 {
408 fontDef = def;
409 ATSUCreateAndCopyStyle(baseStyle, &style);
410@@ -747,22 +747,21 @@ bool QFontEngineMac::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
411 {
412 if (!cmap) {
413 cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
414- int size = 0;
415- cmap = getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symbolCMap, &size);
416+ cmap = getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symbolCMap, &cmapSize);
417 if (!cmap)
418 return false;
419 }
420 if (symbolCMap) {
421 for (int i = 0; i < len; ++i) {
422 unsigned int uc = getChar(str, i, len);
423- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
424+ glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
425 if(!glyphs->glyphs[i] && uc < 0x100)
426- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
427+ glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
428 }
429 } else {
430 for (int i = 0; i < len; ++i) {
431 unsigned int uc = getChar(str, i, len);
432- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
433+ glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
434 }
435 }
436
437diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h
438index 7d70c24..844d421 100644
439--- a/src/gui/text/qfontengine_mac_p.h
440+++ b/src/gui/text/qfontengine_mac_p.h
441@@ -108,6 +108,7 @@ private:
442 qreal m_maxCharWidth;
443 QFixed m_xHeight;
444 QFixed m_averageCharWidth;
445+ mutable int cmapSize;
446 };
447
448 class QFontEngineMacMulti : public QFontEngineMulti
449diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
450index f29ac47..9c3435f 100644
451--- a/src/gui/text/qfontengine_p.h
452+++ b/src/gui/text/qfontengine_p.h
453@@ -247,7 +247,7 @@ public:
454 QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
455
456 static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
457- static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode);
458+ static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode);
459
460 static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
461
462diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
463index 04f7b76..011d233 100644
464--- a/src/gui/text/qfontengine_qpa.cpp
465+++ b/src/gui/text/qfontengine_qpa.cpp
466@@ -358,9 +358,9 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
467 unsigned int uc = getChar(str, i, len);
468 if (mirrored)
469 uc = QChar::mirroredChar(uc);
470- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
471+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
472 if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
473- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
474+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
475 ++glyph_pos;
476 }
477 } else {
478@@ -368,7 +368,7 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
479 unsigned int uc = getChar(str, i, len);
480 if (mirrored)
481 uc = QChar::mirroredChar(uc);
482- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
483+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
484 #if 0 && defined(DEBUG_FONTENGINE)
485 QChar c(uc);
486 if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
487@@ -511,16 +511,16 @@ bool QFontEngineQPA::canRender(const QChar *string, int len)
488 if (symbol) {
489 for (int i = 0; i < len; ++i) {
490 unsigned int uc = getChar(string, i, len);
491- glyph_t g = getTrueTypeGlyphIndex(cmap, uc);
492+ glyph_t g = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
493 if(!g && uc < 0x100)
494- g = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
495+ g = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
496 if (!g)
497 return false;
498 }
499 } else {
500 for (int i = 0; i < len; ++i) {
501 unsigned int uc = getChar(string, i, len);
502- if (!getTrueTypeGlyphIndex(cmap, uc))
503+ if (!getTrueTypeGlyphIndex(cmap, cmapSize, uc))
504 return false;
505 }
506 }
507diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
508index 8d5e71b..9087cff 100644
509--- a/src/gui/text/qfontengine_qpf.cpp
510+++ b/src/gui/text/qfontengine_qpf.cpp
511@@ -577,9 +577,9 @@ bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
512 if (symbol) {
513 for (int i = 0; i < len; ++i) {
514 unsigned int uc = getChar(str, i, len);
515- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
516+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
517 if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
518- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
519+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
520 ++glyph_pos;
521 }
522 } else {
523@@ -587,7 +587,7 @@ bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
524 unsigned int uc = getChar(str, i, len);
525 if (mirrored)
526 uc = QChar::mirroredChar(uc);
527- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
528+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
529 #if 0 && defined(DEBUG_FONTENGINE)
530 QChar c(uc);
531 if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
532@@ -786,16 +786,16 @@ bool QFontEngineQPF::canRender(const QChar *string, int len)
533 if (symbol) {
534 for (int i = 0; i < len; ++i) {
535 unsigned int uc = getChar(string, i, len);
536- glyph_t g = getTrueTypeGlyphIndex(cmap, uc);
537+ glyph_t g = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
538 if(!g && uc < 0x100)
539- g = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
540+ g = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
541 if (!g)
542 return false;
543 }
544 } else {
545 for (int i = 0; i < len; ++i) {
546 unsigned int uc = getChar(string, i, len);
547- if (!getTrueTypeGlyphIndex(cmap, uc))
548+ if (!getTrueTypeGlyphIndex(cmap, cmapSize, uc))
549 return false;
550 }
551 }
552diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
553index 1da501a..b2bb561 100644
554--- a/src/gui/text/qfontengine_s60.cpp
555+++ b/src/gui/text/qfontengine_s60.cpp
556@@ -77,6 +77,7 @@ QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont
557 : m_cFont(cFont)
558 , m_symbolCMap(false)
559 , m_openFont(openFont)
560+ , m_cmapSize(0)
561 {
562 if (!symbianFontTableApiAvailable()) {
563 TAny *trueTypeExtension = NULL;
564@@ -161,10 +162,9 @@ const uchar *QSymbianTypeFaceExtras::cmap() const
565 {
566 if (m_cmapTable.isNull()) {
567 const QByteArray cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
568- int size = 0;
569 const uchar *cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>
570- (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &size);
571- m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), size);
572+ (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &m_cmapSize);
573+ m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), m_cmapSize);
574 }
575 return reinterpret_cast<const uchar *>(m_cmapTable.constData());
576 }
577@@ -324,6 +324,7 @@ bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout
578 for (int i = 0; i < len; ++i) {
579 const unsigned int uc = getChar(characters, i, len);
580 *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap,
581+ m_cmapSize,
582 (isRtl && !m_extras->isSymbolCMap()) ? QChar::mirroredChar(uc) : uc);
583 }
584
585@@ -463,7 +464,7 @@ bool QFontEngineS60::canRender(const QChar *string, int len)
586 const unsigned char *cmap = m_extras->cmap();
587 for (int i = 0; i < len; ++i) {
588 const unsigned int uc = getChar(string, i, len);
589- if (QFontEngine::getTrueTypeGlyphIndex(cmap, uc) == 0)
590+ if (QFontEngine::getTrueTypeGlyphIndex(cmap, m_cmapSize, uc) == 0)
591 return false;
592 }
593 return true;
594diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
595index 17e2207..9e38570 100644
596--- a/src/gui/text/qfontengine_s60_p.h
597+++ b/src/gui/text/qfontengine_s60_p.h
598@@ -93,6 +93,7 @@ private:
599 // the Font Table API
600 COpenFont *m_openFont;
601 mutable MOpenFontTrueTypeExtension *m_trueTypeExtension;
602+ mutable int m_cmapSize;
603 };
604
605 class QFontEngineS60 : public QFontEngine
606diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
607index bd9a437..6ad5eb4 100644
608--- a/src/gui/text/qfontengine_win.cpp
609+++ b/src/gui/text/qfontengine_win.cpp
610@@ -215,9 +215,8 @@ void QFontEngineWin::getCMap()
611 bool symb = false;
612 if (ttf) {
613 cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
614- int size = 0;
615 cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
616- cmapTable.size(), &symb, &size);
617+ cmapTable.size(), &symb, &cmapSize);
618 }
619 if (!cmap) {
620 ttf = false;
621@@ -263,14 +262,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout
622 if (symbol) {
623 for (; i < numChars; ++i, ++glyph_pos) {
624 unsigned int uc = getChar(str, i, numChars);
625- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
626+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
627 if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
628- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
629+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
630 }
631 } else if (ttf) {
632 for (; i < numChars; ++i, ++glyph_pos) {
633 unsigned int uc = getChar(str, i, numChars);
634- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
635+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, QChar::mirroredChar(uc));
636 }
637 } else {
638 #endif
639@@ -296,14 +295,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout
640 if (symbol) {
641 for (; i < numChars; ++i, ++glyph_pos) {
642 unsigned int uc = getChar(str, i, numChars);
643- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
644+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
645 if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
646- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
647+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
648 }
649 } else if (ttf) {
650 for (; i < numChars; ++i, ++glyph_pos) {
651 unsigned int uc = getChar(str, i, numChars);
652- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
653+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
654 }
655 } else {
656 #endif
657@@ -335,6 +334,7 @@ QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont
658 _name = name;
659
660 cmap = 0;
661+ cmapSize = 0;
662 hfont = _hfont;
663 logfont = lf;
664 HDC hdc = shared_dc();
665@@ -811,9 +811,9 @@ bool QFontEngineWin::canRender(const QChar *string, int len)
666 if (symbol) {
667 for (int i = 0; i < len; ++i) {
668 unsigned int uc = getChar(string, i, len);
669- if (getTrueTypeGlyphIndex(cmap, uc) == 0) {
670+ if (getTrueTypeGlyphIndex(cmap, cmapSize, uc) == 0) {
671 if (uc < 0x100) {
672- if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0)
673+ if (getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000) == 0)
674 return false;
675 } else {
676 return false;
677@@ -823,7 +823,7 @@ bool QFontEngineWin::canRender(const QChar *string, int len)
678 } else if (ttf) {
679 for (int i = 0; i < len; ++i) {
680 unsigned int uc = getChar(string, i, len);
681- if (getTrueTypeGlyphIndex(cmap, uc) == 0)
682+ if (getTrueTypeGlyphIndex(cmap, cmapSize, uc) == 0)
683 return false;
684 }
685 } else {
686diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
687index 0c8df72..27f0355 100644
688--- a/src/gui/text/qfontengine_win_p.h
689+++ b/src/gui/text/qfontengine_win_p.h
690@@ -144,6 +144,7 @@ public:
691 mutable uint widthCacheSize;
692 mutable QFixed *designAdvances;
693 mutable int designAdvancesSize;
694+ int cmapSize;
695
696 private:
697 bool hasCFFTable() const;
698--
6992.8.1
700
This page took 0.169954 seconds and 4 git commands to generate.