diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2009-09-17 11:21:14 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2009-09-17 12:30:16 (GMT) |
commit | 992f1b36dc7c246bb978c9c60b11369e3d1cce9d (patch) | |
tree | 8b79a434b441d6ed285756c3f223de42af2ca16f /src | |
parent | d8a862b403ea0801088f0be7ba8223743172702f (diff) | |
download | Qt-992f1b36dc7c246bb978c9c60b11369e3d1cce9d.zip Qt-992f1b36dc7c246bb978c9c60b11369e3d1cce9d.tar.gz Qt-992f1b36dc7c246bb978c9c60b11369e3d1cce9d.tar.bz2 |
Fix glyph selection in symbol fonts that contain unicode cmap table
Some symbol fonts will contain a unicode cmap table in addition to the
microsoft symbol cmap table that maps the symbol range (private range
0xf000 - 0xf100) into the correct glyphs. This is essentially a broken
unicode table, and we should not prefer it if these conditions are true.
In the strict cases where these conditions apply, we fall back to the
symbol table instead.
Task-number: QT-2354
Done-with: Lars
Reviewed by: Lars
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/text/qfontengine.cpp | 77 |
1 files changed, 63 insertions, 14 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 8dd01d7..e5a88fc 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -946,48 +946,60 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy if (maps + 8 * numTables > endPtr) return 0; + enum { + Invalid, + Symbol, + AppleRoman, + Unicode11, + Unicode, + MicrosoftUnicode, + MicrosoftUnicodeExtended + }; + + int symbolTable = -1; int tableToUse = -1; - int score = 0; + int score = Invalid; for (int n = 0; n < numTables; ++n) { const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n); const quint16 platformSpecificId = qFromBigEndian<quint16>(maps + 8 * n + 2); switch (platformId) { case 0: // Unicode - if (score < 4 && + if (score < Unicode && (platformSpecificId == 0 || platformSpecificId == 2 || platformSpecificId == 3)) { tableToUse = n; - score = 4; - } else if (score < 3 && platformSpecificId == 1) { + score = Unicode; + } else if (score < Unicode11 && platformSpecificId == 1) { tableToUse = n; - score = 3; + score = Unicode11; } break; case 1: // Apple - if (score < 2 && platformSpecificId == 0) { // Apple Roman + if (score < AppleRoman && platformSpecificId == 0) { // Apple Roman tableToUse = n; - score = 2; + score = AppleRoman; } break; case 3: // Microsoft switch (platformSpecificId) { case 0: - if (score < 1) { + symbolTable = n; + if (score < Symbol) { tableToUse = n; - score = 1; + score = Symbol; } break; case 1: - if (score < 5) { + if (score < MicrosoftUnicode) { tableToUse = n; - score = 5; + score = MicrosoftUnicode; } break; case 0xa: - if (score < 6) { + if (score < MicrosoftUnicodeExtended) { tableToUse = n; - score = 6; + score = MicrosoftUnicodeExtended; } break; default: @@ -999,7 +1011,9 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy } if(tableToUse < 0) return 0; - *isSymbolFont = (score == 1); + +resolveTable: + *isSymbolFont = (score == Symbol); unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4); @@ -1019,6 +1033,41 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy if (table + unicode_table + length > endPtr) return 0; *cmapSize = length; + + // To support symbol fonts that contain a unicode table for the symbol area + // we check the cmap tables and fall back to symbol font unless that would + // involve losing information from the unicode table + if (symbolTable > -1 && ((score == Unicode) || (score == Unicode11))) { + const uchar *selectedTable = table + unicode_table; + + // Check that none of the latin1 range are in the unicode table + bool unicodeTableHasLatin1 = false; + for (int uc=0x00; uc<0x100; ++uc) { + if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) { + unicodeTableHasLatin1 = true; + break; + } + } + + // Check that at least one symbol char is in the unicode table + bool unicodeTableHasSymbols = false; + if (!unicodeTableHasLatin1) { + for (int uc=0xf000; uc<0xf100; ++uc) { + if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) { + unicodeTableHasSymbols = true; + break; + } + } + } + + // Fall back to symbol table + if (!unicodeTableHasLatin1 && unicodeTableHasSymbols) { + tableToUse = symbolTable; + score = Symbol; + goto resolveTable; + } + } + return table + unicode_table; } |