Improve name table handling.
Robust reading of name tables.
Internally use sk_sp with LocalizedStrings. After landing, update the
public api as well.
Replace High/Low with Leading/Trailing surrogates in naming. This naming
is far easier to get right.
Change-Id: I542934ea8189ced1c2cbdd1539f9ebba562f0731
Reviewed-on: https://skia-review.googlesource.com/148123
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/src/core/SkUtils.h b/src/core/SkUtils.h
index e18934d..cfbdaae 100644
--- a/src/core/SkUtils.h
+++ b/src/core/SkUtils.h
@@ -36,9 +36,9 @@
///////////////////////////////////////////////////////////////////////////////
-static inline bool SkUTF16_IsHighSurrogate(uint16_t c) { return ((c) & 0xFC00) == 0xD800; }
+static inline bool SkUTF16_IsLeadingSurrogate(uint16_t c) { return ((c) & 0xFC00) == 0xD800; }
-static inline bool SkUTF16_IsLowSurrogate (uint16_t c) { return ((c) & 0xFC00) == 0xDC00; }
+static inline bool SkUTF16_IsTrailingSurrogate (uint16_t c) { return ((c) & 0xFC00) == 0xDC00; }
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 53dc101..75099f4 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -1617,15 +1617,15 @@
}
SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() const {
- SkTypeface::LocalizedStrings* nameIter =
- SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
- if (nullptr == nameIter) {
+ sk_sp<SkTypeface::LocalizedStrings> nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
+ if (!nameIter) {
SkString familyName;
this->getFamilyName(&familyName);
SkString language("und"); //undetermined
- nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
+ nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(familyName, language);
}
- return nameIter;
+ return nameIter.release();
}
int SkTypeface_FreeType::onGetVariationDesignPosition(
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 370adc1..85625ea 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -2166,9 +2166,9 @@
}
SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
- SkTypeface::LocalizedStrings* nameIter =
- SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
- if (nullptr == nameIter) {
+ sk_sp<SkTypeface::LocalizedStrings> nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
+ if (!nameIter) {
CFStringRef cfLanguageRaw;
UniqueCFRef<CFStringRef> cfFamilyName(
CTFontCopyLocalizedName(fFontRef.get(), kCTFontFamilyNameKey, &cfLanguageRaw));
@@ -2185,9 +2185,9 @@
CFStringToSkString(cfFamilyName.get(), &skFamilyName);
}
- nameIter = new SkOTUtils::LocalizedStrings_SingleName(skFamilyName, skLanguage);
+ nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(skFamilyName, skLanguage);
}
- return nameIter;
+ return nameIter.release();
}
int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const {
@@ -2377,7 +2377,7 @@
src = reinterpret_cast<const UniChar*>(chars);
int extra = 0;
for (int i = 0; i < glyphCount; ++i) {
- if (SkUTF16_IsHighSurrogate(src[i + extra])) {
+ if (SkUTF16_IsLeadingSurrogate(src[i + extra])) {
++extra;
}
}
@@ -2418,7 +2418,7 @@
int extra = 0;
for (int i = 0; i < glyphCount; ++i) {
compactedGlyphs[i] = macGlyphs[i + extra];
- if (SkUTF16_IsHighSurrogate(src[i + extra])) {
+ if (SkUTF16_IsLeadingSurrogate(src[i + extra])) {
++extra;
}
}
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 380396b..3e18773 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -2122,7 +2122,7 @@
// Try a run of bmp.
int glyphsLeft = glyphCount - glyphIndex;
int runLength = 0;
- while (runLength < glyphsLeft && !SkUTF16_IsHighSurrogate(currentUtf16[runLength])) {
+ while (runLength < glyphsLeft && !SkUTF16_IsLeadingSurrogate(currentUtf16[runLength])) {
++runLength;
}
if (runLength) {
@@ -2132,7 +2132,7 @@
}
// Try a run of non-bmp.
- while (glyphIndex < glyphCount && SkUTF16_IsHighSurrogate(*currentUtf16)) {
+ while (glyphIndex < glyphCount && SkUTF16_IsLeadingSurrogate(*currentUtf16)) {
glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, currentUtf16);
++glyphIndex;
currentUtf16 += 2;
@@ -2212,15 +2212,15 @@
}
SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const {
- SkTypeface::LocalizedStrings* nameIter =
- SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
- if (nullptr == nameIter) {
+ sk_sp<SkTypeface::LocalizedStrings> nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
+ if (!nameIter) {
SkString familyName;
this->getFamilyName(&familyName);
SkString language("und"); //undetermined
- nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
+ nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(familyName, language);
}
- return nameIter;
+ return nameIter.release();
}
int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp
index e6a812f..dc2fc26 100644
--- a/src/ports/SkTypeface_win_dw.cpp
+++ b/src/ports/SkTypeface_win_dw.cpp
@@ -176,14 +176,14 @@
};
SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const {
- SkTypeface::LocalizedStrings* nameIter =
- SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
- if (nullptr == nameIter) {
+ sk_sp<SkTypeface::LocalizedStrings> nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
+ if (!nameIter) {
SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names.");
- nameIter = new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release());
+ nameIter = sk_make_sp<LocalizedStrings_IDWriteLocalizedStrings>(familyNames.release());
}
- return nameIter;
+ return nameIter.release();
}
int DWriteFontTypeface::onGetVariationDesignPosition(
diff --git a/src/sfnt/SkOTTable_name.cpp b/src/sfnt/SkOTTable_name.cpp
index 05230f4..0a2f47b 100644
--- a/src/sfnt/SkOTTable_name.cpp
+++ b/src/sfnt/SkOTTable_name.cpp
@@ -13,39 +13,49 @@
#include "SkTemplates.h"
#include "SkUtils.h"
-static SkUnichar next_unichar_UTF16BE(const char** srcPtr) {
- SkASSERT(srcPtr && *srcPtr);
+static SkUnichar next_unichar_UTF16BE(const uint8_t** srcPtr, size_t* length) {
+ SkASSERT(srcPtr && *srcPtr && length);
+ SkASSERT(*length > 0);
- const char* src = *srcPtr;
- uint16_t lo;
- memcpy(&lo, src, 2);
- src += 2;
+ uint16_t leading;
+ if (*length < sizeof(leading)) {
+ *length = 0;
+ return 0xFFFD;
+ }
+ memcpy(&leading, *srcPtr, sizeof(leading));
+ *srcPtr += sizeof(leading);
+ *length -= sizeof(leading);
+ SkUnichar c = SkEndian_SwapBE16(leading);
- SkUnichar c = SkEndian_SwapBE16(lo);
-
- SkASSERT(!SkUTF16_IsLowSurrogate(c));
- if (SkUTF16_IsHighSurrogate(c)) {
- uint16_t hi;
- memcpy(&hi, src, 2);
- src += 2;
- unsigned c2 = SkEndian_SwapBE16(hi);
- SkASSERT(SkUTF16_IsLowSurrogate(c2));
+ if (SkUTF16_IsTrailingSurrogate(c)) {
+ return 0xFFFD;
+ }
+ if (SkUTF16_IsLeadingSurrogate(c)) {
+ uint16_t trailing;
+ if (*length < sizeof(trailing)) {
+ *length = 0;
+ return 0xFFFD;
+ }
+ memcpy(&trailing, *srcPtr, sizeof(trailing));
+ SkUnichar c2 = SkEndian_SwapBE16(trailing);
+ if (!SkUTF16_IsTrailingSurrogate(c2)) {
+ return 0xFFFD;
+ }
+ *srcPtr += sizeof(trailing);
+ *length -= sizeof(trailing);
c = (c << 10) + c2 + (0x10000 - (0xD800 << 10) - 0xDC00);
}
- *srcPtr = src;
return c;
}
-static void SkString_from_UTF16BE(const char* utf16be, size_t length, SkString& utf8) {
+static void SkString_from_UTF16BE(const uint8_t* utf16be, size_t length, SkString& utf8) {
// Note that utf16be may not be 2-byte aligned.
SkASSERT(utf16be != nullptr);
utf8.reset();
- size_t numberOf16BitValues = length / 2;
- const char* end = utf16be + numberOf16BitValues*2;
- while (utf16be < end) {
- utf8.appendUnichar(next_unichar_UTF16BE(&utf16be));
+ while (length) {
+ utf8.appendUnichar(next_unichar_UTF16BE(&utf16be, &length));
}
}
@@ -446,40 +456,55 @@
}
bool SkOTTableName::Iterator::next(SkOTTableName::Iterator::Record& record) {
- const size_t nameRecordsCount = SkEndian_SwapBE16(fName.count);
- const SkOTTableName::Record* nameRecords = SkTAfter<const SkOTTableName::Record>(&fName);
- const SkOTTableName::Record* nameRecord;
+ SkOTTableName nameTable;
+ if (fNameTableSize < sizeof(nameTable)) {
+ return false;
+ }
+ memcpy(&nameTable, fNameTable, sizeof(nameTable));
+
+ const uint8_t* nameRecords = fNameTable + sizeof(nameTable);
+ const size_t nameRecordsSize = fNameTableSize - sizeof(nameTable);
+
+ const size_t stringTableOffset = SkEndian_SwapBE16(nameTable.stringOffset);
+ if (fNameTableSize < stringTableOffset) {
+ return false;
+ }
+ const uint8_t* stringTable = fNameTable + stringTableOffset;
+ const size_t stringTableSize = fNameTableSize - stringTableOffset;
// Find the next record which matches the requested type.
+ SkOTTableName::Record nameRecord;
+ const size_t nameRecordsCount = SkEndian_SwapBE16(nameTable.count);
+ const size_t nameRecordsMax = SkTMin(nameRecordsCount, nameRecordsSize / sizeof(nameRecord));
do {
- if (fIndex >= nameRecordsCount) {
+ if (fIndex >= nameRecordsMax) {
return false;
}
- nameRecord = &nameRecords[fIndex];
+ memcpy(&nameRecord, nameRecords + sizeof(nameRecord)*fIndex, sizeof(nameRecord));
++fIndex;
- } while (fType != -1 && nameRecord->nameID.fontSpecific != fType);
+ } 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);
+ record.type = nameRecord.nameID.fontSpecific;
// Decode the name into UTF-8.
- const uint16_t nameOffset = SkEndian_SwapBE16(nameRecord->offset);
- const uint16_t nameLength = SkEndian_SwapBE16(nameRecord->length);
- const char* nameString = SkTAddOffset<const char>(stringTable, nameOffset);
- switch (nameRecord->platformID.value) {
+ const size_t nameOffset = SkEndian_SwapBE16(nameRecord.offset);
+ const size_t nameLength = SkEndian_SwapBE16(nameRecord.length);
+ if (stringTableSize < nameOffset + nameLength) {
+ return false; // continue?
+ }
+ const uint8_t* nameString = stringTable + nameOffset;
+ switch (nameRecord.platformID.value) {
case SkOTTableName::Record::PlatformID::Windows:
if (SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2
- != nameRecord->encodingID.windows.value
+ != nameRecord.encodingID.windows.value
&& SkOTTableName::Record::EncodingID::Windows::UnicodeUCS4
- != nameRecord->encodingID.windows.value
+ != nameRecord.encodingID.windows.value
&& SkOTTableName::Record::EncodingID::Windows::Symbol
- != nameRecord->encodingID.windows.value)
+ != nameRecord.encodingID.windows.value)
{
record.name.reset();
- break;
+ break; // continue?
}
case SkOTTableName::Record::PlatformID::Unicode:
case SkOTTableName::Record::PlatformID::ISO:
@@ -489,12 +514,12 @@
case SkOTTableName::Record::PlatformID::Macintosh:
// TODO: need better decoding, especially on Mac.
if (SkOTTableName::Record::EncodingID::Macintosh::Roman
- != nameRecord->encodingID.macintosh.value)
+ != nameRecord.encodingID.macintosh.value)
{
record.name.reset();
- break;
+ break; // continue?
}
- SkStringFromMacRoman((const uint8_t*)nameString, nameLength, record.name);
+ SkStringFromMacRoman(nameString, nameLength, record.name);
break;
case SkOTTableName::Record::PlatformID::Custom:
@@ -502,27 +527,46 @@
default:
SkASSERT(false);
record.name.reset();
- break;
+ break; // continue?
}
// Determine the language.
- const uint16_t languageID = SkEndian_SwapBE16(nameRecord->languageID.languageTagID);
+ const uint16_t languageID = SkEndian_SwapBE16(nameRecord.languageID.languageTagID);
// Handle format 1 languages.
- if (SkOTTableName::format_1 == fName.format && languageID >= 0x8000) {
+ if (SkOTTableName::format_1 == nameTable.format && languageID >= 0x8000) {
const uint16_t languageTagRecordIndex = languageID - 0x8000;
- const SkOTTableName::Format1Ext* format1ext =
- SkTAfter<const SkOTTableName::Format1Ext>(nameRecords, nameRecordsCount);
+ if (nameRecordsSize < sizeof(nameRecord)*nameRecordsCount) {
+ return false; //"und" or break?
+ }
+ const uint8_t* format1extData = nameRecords + sizeof(nameRecord)*nameRecordsCount;
+ size_t format1extSize = nameRecordsSize - sizeof(nameRecord)*nameRecordsCount;
+ SkOTTableName::Format1Ext format1ext;
+ if (format1extSize < sizeof(format1ext)) {
+ return false; // "und" or break?
+ }
+ memcpy(&format1ext, format1extData, sizeof(format1ext));
- if (languageTagRecordIndex < SkEndian_SwapBE16(format1ext->langTagCount)) {
- const SkOTTableName::Format1Ext::LangTagRecord* languageTagRecord =
- SkTAfter<const SkOTTableName::Format1Ext::LangTagRecord>(format1ext);
+ const uint8_t* languageTagRecords = format1extData + sizeof(format1ext);
+ size_t languageTagRecordsSize = format1extSize - sizeof(format1ext);
+ if (languageTagRecordIndex < SkEndian_SwapBE16(format1ext.langTagCount)) {
+ SkOTTableName::Format1Ext::LangTagRecord languageTagRecord;
+ if (languageTagRecordsSize < sizeof(languageTagRecord)*(languageTagRecordIndex+1)) {
+ return false; // "und"?
+ }
+ const uint8_t* languageTagData = languageTagRecords
+ + sizeof(languageTagRecord)*languageTagRecordIndex;
+ memcpy(&languageTagRecord, languageTagData, sizeof(languageTagRecord));
- uint16_t offset = SkEndian_SwapBE16(languageTagRecord[languageTagRecordIndex].offset);
- uint16_t length = SkEndian_SwapBE16(languageTagRecord[languageTagRecordIndex].length);
- const char* string = SkTAddOffset<const char>(stringTable, offset);
- SkString_from_UTF16BE(string, length, record.language);
+ uint16_t languageOffset = SkEndian_SwapBE16(languageTagRecord.offset);
+ uint16_t languageLength = SkEndian_SwapBE16(languageTagRecord.length);
+
+ if (fNameTableSize < stringTableOffset + languageOffset + languageLength) {
+ return false; // "und"?
+ }
+ const uint8_t* languageString = stringTable + languageOffset;
+ SkString_from_UTF16BE(languageString, languageLength, record.language);
return true;
}
}
diff --git a/src/sfnt/SkOTTable_name.h b/src/sfnt/SkOTTable_name.h
index 4c1ce5b..6539d75 100644
--- a/src/sfnt/SkOTTable_name.h
+++ b/src/sfnt/SkOTTable_name.h
@@ -540,12 +540,13 @@
class Iterator {
public:
- Iterator(const SkOTTableName& name) : fName(name), fIndex(0), fType(-1) { }
- Iterator(const SkOTTableName& name, SkOTTableName::Record::NameID::Predefined::Value type)
- : fName(name), fIndex(0), fType(type)
+ Iterator(const uint8_t* nameTable, size_t size)
+ : fNameTable(nameTable), fNameTableSize(size), fIndex(0), fType(-1) { }
+ Iterator(const uint8_t* nameTable, size_t size, SK_OT_USHORT type)
+ : fNameTable(nameTable), fNameTableSize(size), fIndex(0), fType(type)
{ }
- void reset(SkOTTableName::Record::NameID::Predefined::Value type) {
+ void reset(SK_OT_USHORT type) {
fIndex = 0;
fType = type;
}
@@ -558,7 +559,8 @@
bool next(Record&);
private:
- const SkOTTableName& fName;
+ const uint8_t* fNameTable;
+ const size_t fNameTableSize;
size_t fIndex;
int fType;
};
diff --git a/src/sfnt/SkOTUtils.cpp b/src/sfnt/SkOTUtils.cpp
index 1bd051c..1631a4d 100644
--- a/src/sfnt/SkOTUtils.cpp
+++ b/src/sfnt/SkOTUtils.cpp
@@ -163,9 +163,11 @@
return rewrittenFontData.release();
}
-
-SkOTUtils::LocalizedStrings_NameTable*
-SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(const SkTypeface& typeface) {
+sk_sp<SkOTUtils::LocalizedStrings_NameTable>
+SkOTUtils::LocalizedStrings_NameTable::Make(const SkTypeface& typeface,
+ SK_OT_USHORT types[],
+ int typesCount)
+{
static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e');
size_t nameTableSize = typeface.getTableSize(nameTag);
if (0 == nameTableSize) {
@@ -177,9 +179,16 @@
return nullptr;
}
- return new SkOTUtils::LocalizedStrings_NameTable((SkOTTableName*)nameTableData.release(),
- SkOTUtils::LocalizedStrings_NameTable::familyNameTypes,
- SK_ARRAY_COUNT(SkOTUtils::LocalizedStrings_NameTable::familyNameTypes));
+ return sk_sp<SkOTUtils::LocalizedStrings_NameTable>(
+ new SkOTUtils::LocalizedStrings_NameTable(std::move(nameTableData), nameTableSize,
+ types, typesCount));
+}
+
+sk_sp<SkOTUtils::LocalizedStrings_NameTable>
+SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(const SkTypeface& typeface) {
+ return Make(typeface,
+ SkOTUtils::LocalizedStrings_NameTable::familyNameTypes,
+ SK_ARRAY_COUNT(SkOTUtils::LocalizedStrings_NameTable::familyNameTypes));
}
bool SkOTUtils::LocalizedStrings_NameTable::next(SkTypeface::LocalizedString* localizedString) {
@@ -198,8 +207,7 @@
} while (true);
}
-SkOTTableName::Record::NameID::Predefined::Value
-SkOTUtils::LocalizedStrings_NameTable::familyNameTypes[3] = {
+SK_OT_USHORT 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 64d3ae2..2f8fe0b 100644
--- a/src/sfnt/SkOTUtils.h
+++ b/src/sfnt/SkOTUtils.h
@@ -44,26 +44,35 @@
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[],
+ LocalizedStrings_NameTable(std::unique_ptr<uint8_t[]> nameTableData, size_t size,
+ SK_OT_USHORT types[],
int typesCount)
: fTypes(types), fTypesCount(typesCount), fTypesIndex(0)
- , fNameTableData(nameTableData), fFamilyNameIter(*nameTableData, fTypes[fTypesIndex])
+ , fNameTableData(std::move(nameTableData))
+ , fFamilyNameIter(fNameTableData.get(), size, fTypes[fTypesIndex])
{ }
+ /** Creates an iterator over all data in the 'name' table of a typeface.
+ * If no valid 'name' table can be found, returns nullptr.
+ */
+ static sk_sp<LocalizedStrings_NameTable> Make(
+ const SkTypeface& typeface,
+ SK_OT_USHORT types[],
+ int typesCount);
+
/** Creates an iterator over all the family names in the 'name' table of a typeface.
* If no valid 'name' table can be found, returns nullptr.
*/
- static LocalizedStrings_NameTable* CreateForFamilyNames(const SkTypeface& typeface);
+ static sk_sp<LocalizedStrings_NameTable> MakeForFamilyNames(const SkTypeface& typeface);
bool next(SkTypeface::LocalizedString* localizedString) override;
private:
- static SkOTTableName::Record::NameID::Predefined::Value familyNameTypes[3];
+ static SK_OT_USHORT familyNameTypes[3];
- SkOTTableName::Record::NameID::Predefined::Value* fTypes;
+ SK_OT_USHORT* fTypes;
int fTypesCount;
int fTypesIndex;
- std::unique_ptr<SkOTTableName[]> fNameTableData;
+ std::unique_ptr<uint8_t[]> fNameTableData;
SkOTTableName::Iterator fFamilyNameIter;
};
diff --git a/src/utils/SkWhitelistTypefaces.cpp b/src/utils/SkWhitelistTypefaces.cpp
index f51a3b3..e02fd6b 100644
--- a/src/utils/SkWhitelistTypefaces.cpp
+++ b/src/utils/SkWhitelistTypefaces.cpp
@@ -40,8 +40,8 @@
static int whitelist_name_index(const SkTypeface* tf) {
SkString fontNameStr;
- sk_sp<SkTypeface::LocalizedStrings> nameIter(
- SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*tf));
+ sk_sp<SkTypeface::LocalizedStrings> nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*tf);
SkTypeface::LocalizedString familyNameLocalized;
while (nameIter->next(&familyNameLocalized)) {
fontNameStr = familyNameLocalized.fString;
@@ -53,8 +53,8 @@
}
}
#if WHITELIST_DEBUG
- sk_sp<SkTypeface::LocalizedStrings> debugIter(
- SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*tf));
+ sk_sp<SkTypeface::LocalizedStrings> debugIter =
+ SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*tf);
while (debugIter->next(&familyNameLocalized)) {
SkDebugf("no match fontName=\"%s\"\n", familyNameLocalized.fString.c_str());
}
diff --git a/tests/FontNamesTest.cpp b/tests/FontNamesTest.cpp
index 3218b29..e3538dc 100644
--- a/tests/FontNamesTest.cpp
+++ b/tests/FontNamesTest.cpp
@@ -13,6 +13,8 @@
#include <stddef.h>
+namespace {
+
template <size_t R, size_t D> struct Format0NameTable {
SkOTTableName header;
SkOTTableName::Record nameRecord[R];
@@ -30,7 +32,7 @@
};
typedef Format0NameTable<1, 9> SimpleFormat0NameTable;
-SimpleFormat0NameTable simpleFormat0NameTable = {
+constexpr SimpleFormat0NameTable simpleFormat0NameTable = {
/*header*/ {
/*format*/ SkOTTableName::format_0,
/*count*/ SkTEndianSwap16<1>::value,
@@ -50,7 +52,7 @@
};
typedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable;
-SimpleFormat1NameTable simpleFormat1NameTable = {
+constexpr SimpleFormat1NameTable simpleFormat1NameTable = {
/*header*/ {
/*format*/ SkOTTableName::format_1,
/*count*/ SkTEndianSwap16<1>::value,
@@ -82,7 +84,8 @@
};
struct FontNamesTest {
- SkOTTableName* data;
+ const uint8_t* data;
+ size_t size;
SkOTTableName::Record::NameID nameID;
size_t nameCount;
struct {
@@ -90,9 +93,10 @@
const char* language;
} names[10];
-} test[] = {
+} tests[] = {
{
- (SkOTTableName*)&simpleFormat0NameTable,
+ reinterpret_cast<const uint8_t*>(&simpleFormat0NameTable),
+ sizeof(simpleFormat0NameTable),
{ SkOTTableName::Record::NameID::Predefined::FontFamilyName },
1,
{
@@ -100,7 +104,8 @@
},
},
{
- (SkOTTableName*)&simpleFormat1NameTable,
+ reinterpret_cast<const uint8_t*>(&simpleFormat1NameTable),
+ sizeof(simpleFormat1NameTable),
{ SkOTTableName::Record::NameID::Predefined::FontFamilyName },
1,
{
@@ -110,25 +115,27 @@
};
static void test_synthetic(skiatest::Reporter* reporter, bool verbose) {
- for (size_t i = 0; i < SK_ARRAY_COUNT(test); ++i) {
- SkOTTableName::Iterator iter(*test[i].data, test[i].nameID.predefined.value);
+ for (const auto& test : tests) {
+ SkOTTableName::Iterator iter(test.data, test.size, test.nameID.predefined.value);
SkOTTableName::Iterator::Record record;
size_t nameIndex = 0;
- while (nameIndex < test[i].nameCount && iter.next(record)) {
+ while (nameIndex < test.nameCount && iter.next(record)) {
REPORTER_ASSERT(reporter,
- strcmp(test[i].names[nameIndex].name, record.name.c_str()) == 0,
+ strcmp(test.names[nameIndex].name, record.name.c_str()) == 0,
"Name did not match.");
REPORTER_ASSERT(reporter,
- strcmp(test[i].names[nameIndex].language, record.language.c_str()) == 0,
+ strcmp(test.names[nameIndex].language, record.language.c_str()) == 0,
"Language did not match.");
- //printf("%s <%s>\n", record.name.c_str(), record.language.c_str());
+ if (verbose) {
+ SkDebugf("%s <%s>\n", record.name.c_str(), record.language.c_str());
+ }
++nameIndex;
}
- REPORTER_ASSERT(reporter, nameIndex == test[i].nameCount, "Fewer names than expected.");
+ REPORTER_ASSERT(reporter, nameIndex == test.nameCount, "Fewer names than expected.");
REPORTER_ASSERT(reporter, !iter.next(record), "More names than expected.");
}
@@ -176,7 +183,7 @@
}
SkOTTableName::Iterator::Record record;
- SkOTTableName::Iterator familyNameIter(*((SkOTTableName*)nameTableData.get()),
+ SkOTTableName::Iterator familyNameIter(nameTableData.get(), nameTableSize,
SkOTTableName::Record::NameID::Predefined::FontFamilyName);
while (familyNameIter.next(record)) {
REPORTER_ASSERT(
@@ -188,7 +195,7 @@
}
}
- SkOTTableName::Iterator styleNameIter(*((SkOTTableName*)nameTableData.get()),
+ SkOTTableName::Iterator styleNameIter(nameTableData.get(), nameTableSize,
SkOTTableName::Record::NameID::Predefined::FontSubfamilyName);
while (styleNameIter.next(record)) {
REPORTER_ASSERT(
@@ -207,6 +214,8 @@
}
}
+} // namespace
+
DEFINE_bool(verboseFontNames, false, "verbose FontNames test.");
DEF_TEST(FontNames, reporter) {