зеркало из https://github.com/mozilla/gecko-dev.git
bug 1060791 - support cmap subtable format 10, for the Apple Symbols font. r=jdaggett
This commit is contained in:
Родитель
a8ded9bf3a
Коммит
f0d7e96094
|
@ -41,6 +41,15 @@ using namespace mozilla;
|
|||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
AutoSwap_PRUint16 format;
|
||||
AutoSwap_PRUint16 reserved;
|
||||
AutoSwap_PRUint32 length;
|
||||
AutoSwap_PRUint32 language;
|
||||
AutoSwap_PRUint32 startCharCode;
|
||||
AutoSwap_PRUint32 numChars;
|
||||
} Format10CmapHeader;
|
||||
|
||||
typedef struct {
|
||||
AutoSwap_PRUint16 format;
|
||||
AutoSwap_PRUint16 reserved;
|
||||
|
@ -87,6 +96,53 @@ gfxSparseBitSet::Dump(const char* aPrefix, eGfxLog aWhichLog) const
|
|||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
gfxFontUtils::ReadCMAPTableFormat10(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap)
|
||||
{
|
||||
// Ensure table is large enough that we can safely read the header
|
||||
NS_ENSURE_TRUE(aLength >= sizeof(Format10CmapHeader),
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
// Sanity-check header fields
|
||||
const Format10CmapHeader *cmap10 =
|
||||
reinterpret_cast<const Format10CmapHeader*>(aBuf);
|
||||
NS_ENSURE_TRUE(uint16_t(cmap10->format) == 10,
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
NS_ENSURE_TRUE(uint16_t(cmap10->reserved) == 0,
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
uint32_t tablelen = cmap10->length;
|
||||
NS_ENSURE_TRUE(tablelen >= sizeof(Format10CmapHeader) &&
|
||||
tablelen <= aLength, NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
NS_ENSURE_TRUE(cmap10->language == 0, NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
uint32_t numChars = cmap10->numChars;
|
||||
NS_ENSURE_TRUE(tablelen == sizeof(Format10CmapHeader) +
|
||||
numChars * sizeof(uint16_t), NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
uint32_t charCode = cmap10->startCharCode;
|
||||
NS_ENSURE_TRUE(charCode <= CMAP_MAX_CODEPOINT &&
|
||||
charCode + numChars <= CMAP_MAX_CODEPOINT,
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
// glyphs[] array immediately follows the subtable header
|
||||
const AutoSwap_PRUint16 *glyphs =
|
||||
reinterpret_cast<const AutoSwap_PRUint16 *>(cmap10 + 1);
|
||||
|
||||
for (uint32_t i = 0; i < numChars; ++i) {
|
||||
if (uint16_t(*glyphs) != 0) {
|
||||
aCharacterMap.set(charCode);
|
||||
}
|
||||
++charCode;
|
||||
++glyphs;
|
||||
}
|
||||
|
||||
aCharacterMap.Compact();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxFontUtils::ReadCMAPTableFormat12(const uint8_t *aBuf, uint32_t aLength,
|
||||
|
@ -422,7 +478,8 @@ gfxFontUtils::FindPreferredSubtable(const uint8_t *aBuf, uint32_t aBufLength,
|
|||
keepFormat = format;
|
||||
*aTableOffset = offset;
|
||||
*aSymbolEncoding = false;
|
||||
} else if (format == 12 && acceptableUCS4Encoding(platformID, encodingID, keepFormat)) {
|
||||
} else if ((format == 10 || format == 12) &&
|
||||
acceptableUCS4Encoding(platformID, encodingID, keepFormat)) {
|
||||
keepFormat = format;
|
||||
*aTableOffset = offset;
|
||||
*aSymbolEncoding = false;
|
||||
|
@ -431,7 +488,7 @@ gfxFontUtils::FindPreferredSubtable(const uint8_t *aBuf, uint32_t aBufLength,
|
|||
}
|
||||
} else if (format == 14 && isUVSEncoding(platformID, encodingID) && aUVSTableOffset) {
|
||||
*aUVSTableOffset = offset;
|
||||
if (keepFormat == 12) {
|
||||
if (keepFormat == 10 || keepFormat == 12) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -451,7 +508,8 @@ gfxFontUtils::ReadCMAP(const uint8_t *aBuf, uint32_t aBufLength,
|
|||
uint32_t format = FindPreferredSubtable(aBuf, aBufLength,
|
||||
&offset, &aUVSOffset, &symbol);
|
||||
|
||||
if (format == 4) {
|
||||
switch (format) {
|
||||
case 4:
|
||||
if (symbol) {
|
||||
aUnicodeFont = false;
|
||||
aSymbolFont = true;
|
||||
|
@ -461,13 +519,21 @@ gfxFontUtils::ReadCMAP(const uint8_t *aBuf, uint32_t aBufLength,
|
|||
}
|
||||
return ReadCMAPTableFormat4(aBuf + offset, aBufLength - offset,
|
||||
aCharacterMap);
|
||||
}
|
||||
|
||||
if (format == 12) {
|
||||
case 10:
|
||||
aUnicodeFont = true;
|
||||
aSymbolFont = false;
|
||||
return ReadCMAPTableFormat10(aBuf + offset, aBufLength - offset,
|
||||
aCharacterMap);
|
||||
|
||||
case 12:
|
||||
aUnicodeFont = true;
|
||||
aSymbolFont = false;
|
||||
return ReadCMAPTableFormat12(aBuf + offset, aBufLength - offset,
|
||||
aCharacterMap);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -570,6 +636,26 @@ gfxFontUtils::MapCharToGlyphFormat4(const uint8_t *aBuf, char16_t aCh)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
gfxFontUtils::MapCharToGlyphFormat10(const uint8_t *aBuf, uint32_t aCh)
|
||||
{
|
||||
const Format10CmapHeader *cmap10 =
|
||||
reinterpret_cast<const Format10CmapHeader*>(aBuf);
|
||||
|
||||
uint32_t startChar = cmap10->startCharCode;
|
||||
uint32_t numChars = cmap10->numChars;
|
||||
|
||||
if (aCh < startChar || aCh >= startChar + numChars) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const AutoSwap_PRUint16 *glyphs =
|
||||
reinterpret_cast<const AutoSwap_PRUint16 *>(cmap10 + 1);
|
||||
|
||||
uint16_t glyph = glyphs[aCh - startChar];
|
||||
return glyph;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
gfxFontUtils::MapCharToGlyphFormat12(const uint8_t *aBuf, uint32_t aCh)
|
||||
{
|
||||
|
@ -681,6 +767,9 @@ gfxFontUtils::MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength,
|
|||
gid = aUnicode < UNICODE_BMP_LIMIT ?
|
||||
MapCharToGlyphFormat4(aCmapBuf + offset, char16_t(aUnicode)) : 0;
|
||||
break;
|
||||
case 10:
|
||||
gid = MapCharToGlyphFormat10(aCmapBuf + offset, aUnicode);
|
||||
break;
|
||||
case 12:
|
||||
gid = MapCharToGlyphFormat12(aCmapBuf + offset, aUnicode);
|
||||
break;
|
||||
|
@ -703,6 +792,10 @@ gfxFontUtils::MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength,
|
|||
char16_t(aUnicode));
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
varGID = MapCharToGlyphFormat10(aCmapBuf + offset,
|
||||
aUnicode);
|
||||
break;
|
||||
case 12:
|
||||
varGID = MapCharToGlyphFormat12(aCmapBuf + offset,
|
||||
aUnicode);
|
||||
|
|
|
@ -770,6 +770,10 @@ public:
|
|||
(aBuf[aIndex + 2] << 8) | (aBuf[aIndex + 3]));
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ReadCMAPTableFormat10(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap);
|
||||
|
||||
static nsresult
|
||||
ReadCMAPTableFormat12(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap);
|
||||
|
@ -796,6 +800,9 @@ public:
|
|||
static uint32_t
|
||||
MapCharToGlyphFormat4(const uint8_t *aBuf, char16_t aCh);
|
||||
|
||||
static uint32_t
|
||||
MapCharToGlyphFormat10(const uint8_t *aBuf, uint32_t aCh);
|
||||
|
||||
static uint32_t
|
||||
MapCharToGlyphFormat12(const uint8_t *aBuf, uint32_t aCh);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче