diff options
Diffstat (limited to 'gfx/2d/SFNTNameTable.cpp')
-rw-r--r-- | gfx/2d/SFNTNameTable.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/gfx/2d/SFNTNameTable.cpp b/gfx/2d/SFNTNameTable.cpp index e7da2305c9..e187b7f047 100644 --- a/gfx/2d/SFNTNameTable.cpp +++ b/gfx/2d/SFNTNameTable.cpp @@ -9,6 +9,10 @@ #include "Logging.h" #include "mozilla/Move.h" +#if defined(XP_MACOSX) +#include <CoreFoundation/CoreFoundation.h> +#endif + namespace mozilla { namespace gfx { @@ -57,6 +61,9 @@ struct NameRecord enum ENameDecoder : int { eNameDecoderUTF16, +#if defined(XP_MACOSX) + eNameDecoderMacRoman, +#endif eNameDecoderNone }; @@ -121,6 +128,19 @@ IsUTF16Encoding(const NameRecord *aNameRecord) return false; } +#if defined(XP_MACOSX) +static bool +IsMacRomanEncoding(const NameRecord *aNameRecord) +{ + if (aNameRecord->platformID == PLATFORM_ID_MAC && + aNameRecord->encodingID == ENCODING_ID_MAC_ROMAN) { + return true; + } + + return false; +} +#endif + static NameRecordMatchers* CreateCanonicalMatchers(const BigEndianUint16& aNameID) { @@ -129,6 +149,37 @@ CreateCanonicalMatchers(const BigEndianUint16& aNameID) // records and Mac platform records. NameRecordMatchers *matchers = new NameRecordMatchers(); +#if defined(XP_MACOSX) + // First, look for the English name. + if (!matchers->append( + [=](const NameRecord *aNameRecord) { + if (aNameRecord->nameID == aNameID && + aNameRecord->languageID == LANG_ID_MAC_ENGLISH && + aNameRecord->platformID == PLATFORM_ID_MAC && + IsMacRomanEncoding(aNameRecord)) { + return eNameDecoderMacRoman; + } else { + return eNameDecoderNone; + } + })) { + MOZ_CRASH(); + } + + // Second, look for all languages. + if (!matchers->append( + [=](const NameRecord *aNameRecord) { + if (aNameRecord->nameID == aNameID && + aNameRecord->platformID == PLATFORM_ID_MAC && + IsMacRomanEncoding(aNameRecord)) { + return eNameDecoderMacRoman; + } else { + return eNameDecoderNone; + } + })) { + MOZ_CRASH(); + } +#endif /* defined(XP_MACOSX) */ + // First, look for the English name (this will normally succeed). if (!matchers->append( [=](const NameRecord *aNameRecord) { @@ -222,6 +273,10 @@ SFNTNameTable::ReadU16Name(const NameRecordMatchers& aMatchers, switch (aMatchers[i](record)) { case eNameDecoderUTF16: return ReadU16NameFromU16Record(record, aU16Name); +#if defined(XP_MACOSX) + case eNameDecoderMacRoman: + return ReadU16NameFromMacRomanRecord(record, aU16Name); +#endif case eNameDecoderNone: break; default: @@ -256,5 +311,46 @@ SFNTNameTable::ReadU16NameFromU16Record(const NameRecord *aNameRecord, return true; } +#if defined(XP_MACOSX) +bool +SFNTNameTable::ReadU16NameFromMacRomanRecord(const NameRecord *aNameRecord, + mozilla::u16string& aU16Name) +{ + uint32_t offset = aNameRecord->offset; + uint32_t length = aNameRecord->length; + if (mStringDataLength < offset + length) { + gfxWarning() << "Name data too short to contain name string."; + return false; + } + if (length > INT_MAX) { + gfxWarning() << "Name record too long to decode."; + return false; + } + + // pointer to the Mac Roman encoded string in the name record + const uint8_t *encodedStr = mStringData + offset; + + CFStringRef cfString; + cfString = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, encodedStr, + length, kCFStringEncodingMacRoman, + false, kCFAllocatorNull); + + // length (in UTF-16 code pairs) of the decoded string + CFIndex decodedLength = CFStringGetLength(cfString); + + // temporary buffer + UniquePtr<UniChar[]> u16Buffer = MakeUnique<UniChar[]>(decodedLength); + + CFStringGetCharacters(cfString, CFRangeMake(0, decodedLength), + u16Buffer.get()); + + CFRelease(cfString); + + aU16Name.assign(reinterpret_cast<char16_t*>(u16Buffer.get()), decodedLength); + + return true; +} +#endif + } // gfx } // mozilla |