diff options
author | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-06 22:53:04 +0000 |
---|---|---|
committer | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-06 22:53:04 +0000 |
commit | 990d85f02ba6efaf6f3d75262d7ed650edc8afd5 (patch) | |
tree | a78ea0deb1c45b661ac1bdd25036cafc35229f9b /src/sfnt | |
parent | 2273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37 (diff) |
Add getFamilyNames to SkTypeface.
Review URL: https://codereview.chromium.org/21716005
git-svn-id: http://skia.googlecode.com/svn/trunk@10589 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/sfnt')
-rw-r--r-- | src/sfnt/SkOTTable_name.cpp | 27 | ||||
-rw-r--r-- | src/sfnt/SkOTTable_name.h | 6 | ||||
-rw-r--r-- | src/sfnt/SkOTUtils.cpp | 42 | ||||
-rw-r--r-- | src/sfnt/SkOTUtils.h | 52 |
4 files changed, 119 insertions, 8 deletions
diff --git a/src/sfnt/SkOTTable_name.cpp b/src/sfnt/SkOTTable_name.cpp index e0440754ca..b536c0a115 100644 --- a/src/sfnt/SkOTTable_name.cpp +++ b/src/sfnt/SkOTTable_name.cpp @@ -451,6 +451,8 @@ bool SkOTTableName::Iterator::next(SkOTTableName::Iterator::Record& record) { ++fIndex; } while (fType != -1 && nameRecord->nameID.fontSpecific != fType); + record.type = nameRecord->nameID.fontSpecific; + const uint16_t stringTableOffset = SkEndian_SwapBE16(fName.stringOffset); const char* stringTable = SkTAddOffset<const char>(&fName, stringTableOffset); @@ -460,20 +462,29 @@ bool SkOTTableName::Iterator::next(SkOTTableName::Iterator::Record& record) { const char* nameString = SkTAddOffset<const char>(stringTable, nameOffset); switch (nameRecord->platformID.value) { case SkOTTableName::Record::PlatformID::Windows: - SkASSERT(SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 - == nameRecord->encodingID.windows.value - || SkOTTableName::Record::EncodingID::Windows::UnicodeUCS4 - == nameRecord->encodingID.windows.value - || SkOTTableName::Record::EncodingID::Windows::Symbol - == nameRecord->encodingID.windows.value); + if (SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 + != nameRecord->encodingID.windows.value + && SkOTTableName::Record::EncodingID::Windows::UnicodeUCS4 + != nameRecord->encodingID.windows.value + && SkOTTableName::Record::EncodingID::Windows::Symbol + != nameRecord->encodingID.windows.value) + { + record.name.reset(); + break; + } case SkOTTableName::Record::PlatformID::Unicode: case SkOTTableName::Record::PlatformID::ISO: SkStringFromUTF16BE((const uint16_t*)nameString, nameLength, record.name); break; case SkOTTableName::Record::PlatformID::Macintosh: - SkASSERT(SkOTTableName::Record::EncodingID::Macintosh::Roman - == nameRecord->encodingID.macintosh.value); + // TODO: need better decoding, especially on Mac. + if (SkOTTableName::Record::EncodingID::Macintosh::Roman + != nameRecord->encodingID.macintosh.value) + { + record.name.reset(); + break; + } SkStringFromMacRoman((const uint8_t*)nameString, nameLength, record.name); break; diff --git a/src/sfnt/SkOTTable_name.h b/src/sfnt/SkOTTable_name.h index 8dde1a4fc7..f3dae4085a 100644 --- a/src/sfnt/SkOTTable_name.h +++ b/src/sfnt/SkOTTable_name.h @@ -554,7 +554,13 @@ struct SkOTTableName { : fName(name), fIndex(0), fType(type) { } + void reset(SkOTTableName::Record::NameID::Predefined::Value type) { + fIndex = 0; + fType = type; + } + struct Record { + SK_OT_USHORT type; SkString name; SkString language; }; diff --git a/src/sfnt/SkOTUtils.cpp b/src/sfnt/SkOTUtils.cpp index c7716fffd5..004a888310 100644 --- a/src/sfnt/SkOTUtils.cpp +++ b/src/sfnt/SkOTUtils.cpp @@ -159,3 +159,45 @@ SkData* SkOTUtils::RenameFont(SkStream* fontData, const char* fontName, int font return rewrittenFontData.detach(); } + + +SkOTUtils::LocalizedStrings_NameTable* +SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(const SkTypeface& typeface) { + static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e'); + size_t nameTableSize = typeface.getTableSize(nameTag); + if (0 == nameTableSize) { + return NULL; + } + SkAutoTDeleteArray<uint8_t> nameTableData(new uint8_t[nameTableSize]); + size_t copied = typeface.getTableData(nameTag, 0, nameTableSize, nameTableData.get()); + if (copied != nameTableSize) { + return NULL; + } + + return new SkOTUtils::LocalizedStrings_NameTable((SkOTTableName*)nameTableData.detach(), + SkOTUtils::LocalizedStrings_NameTable::familyNameTypes, + SK_ARRAY_COUNT(SkOTUtils::LocalizedStrings_NameTable::familyNameTypes)); +} + +bool SkOTUtils::LocalizedStrings_NameTable::next(SkTypeface::LocalizedString* localizedString) { + do { + SkOTTableName::Iterator::Record record; + if (fFamilyNameIter.next(record)) { + localizedString->fString = record.name; + localizedString->fLanguage = record.language; + return true; + } + if (fTypesCount == fTypesIndex + 1) { + return false; + } + ++fTypesIndex; + fFamilyNameIter.reset(fTypes[fTypesIndex]); + } while (true); +} + +SkOTTableName::Record::NameID::Predefined::Value +SkOTUtils::LocalizedStrings_NameTable::familyNameTypes[3] = { + SkOTTableName::Record::NameID::Predefined::FontFamilyName, + SkOTTableName::Record::NameID::Predefined::PreferredFamily, + SkOTTableName::Record::NameID::Predefined::WWSFamilyName, +}; diff --git a/src/sfnt/SkOTUtils.h b/src/sfnt/SkOTUtils.h index 3c5ada25eb..4825fbeb2f 100644 --- a/src/sfnt/SkOTUtils.h +++ b/src/sfnt/SkOTUtils.h @@ -9,6 +9,9 @@ #define SkOTUtils_DEFINED #include "SkOTTableTypes.h" +#include "SkOTTable_name.h" +#include "SkTypeface.h" + class SkData; class SkStream; @@ -32,6 +35,55 @@ struct SkOTUtils { * fontName and fontNameLen must be specified in terms of ASCII chars. */ static SkData* RenameFont(SkStream* fontData, const char* fontName, int fontNameLen); + + /** An implementation of LocalizedStrings which obtains it's data from a 'name' table. */ + class LocalizedStrings_NameTable : public SkTypeface::LocalizedStrings { + public: + /** Takes ownership of the nameTableData and will free it with SK_DELETE. */ + LocalizedStrings_NameTable(SkOTTableName* nameTableData, + SkOTTableName::Record::NameID::Predefined::Value types[], + int typesCount) + : fTypes(types), fTypesCount(typesCount), fTypesIndex(0) + , fNameTableData(nameTableData), fFamilyNameIter(*nameTableData, fTypes[fTypesIndex]) + { } + + /** Creates an iterator over all the family names in the 'name' table of a typeface. + * If no valid 'name' table can be found, returns NULL. + */ + static LocalizedStrings_NameTable* CreateForFamilyNames(const SkTypeface& typeface); + + virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE; + private: + static SkOTTableName::Record::NameID::Predefined::Value familyNameTypes[3]; + + SkOTTableName::Record::NameID::Predefined::Value* fTypes; + int fTypesCount; + int fTypesIndex; + SkAutoTDeleteArray<SkOTTableName> fNameTableData; + SkOTTableName::Iterator fFamilyNameIter; + }; + + /** An implementation of LocalizedStrings which has one name. */ + class LocalizedStrings_SingleName : public SkTypeface::LocalizedStrings { + public: + LocalizedStrings_SingleName(SkString name, SkString language) + : fName(name), fLanguage(language), fHasNext(true) + { } + + virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE { + localizedString->fString = fName; + localizedString->fLanguage = fLanguage; + + bool hadNext = fHasNext; + fHasNext = false; + return hadNext; + } + + private: + SkString fName; + SkString fLanguage; + bool fHasNext; + }; }; #endif |