Add Symbol encoding when renaming a font.
GDI will not use a Symbol encoded cmap table if there is no Symbol
encoded name. Always output both Unicode and Symbol names (same data,
different name entries). This fixes test_symbolfont on GDI.
Change-Id: I05dea903b9c3914a852cf31472a19a6a06b274e0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233079
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
diff --git a/src/sfnt/SkOTUtils.cpp b/src/sfnt/SkOTUtils.cpp
index 869fec2..061ceb0 100644
--- a/src/sfnt/SkOTUtils.cpp
+++ b/src/sfnt/SkOTUtils.cpp
@@ -65,18 +65,25 @@
}
// The required 'name' record types: Family, Style, Unique, Full and PostScript.
- const SkOTTableName::Record::NameID::Predefined::Value namesToCreate[] = {
+ static constexpr std::array<SkOTTableName::Record::NameID::Predefined::Value, 5> names{{
SkOTTableName::Record::NameID::Predefined::FontFamilyName,
SkOTTableName::Record::NameID::Predefined::FontSubfamilyName,
SkOTTableName::Record::NameID::Predefined::UniqueFontIdentifier,
SkOTTableName::Record::NameID::Predefined::FullFontName,
SkOTTableName::Record::NameID::Predefined::PostscriptName,
- };
- const int namesCount = SK_ARRAY_COUNT(namesToCreate);
+ }};
+
+ // GDI will not use a Symbol cmap table if there is no Symbol encoded name.
+ static constexpr std::array<SkOTTableName::Record::EncodingID::Windows::Value, 2> encodings{{
+ SkOTTableName::Record::EncodingID::Windows::Symbol,
+ SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2,
+ }};
// Copy the data, leaving out the old name table.
// In theory, we could also remove the DSIG table if it exists.
- size_t nameTableLogicalSize = sizeof(SkOTTableName) + (namesCount * sizeof(SkOTTableName::Record)) + (fontNameLen * sizeof(wchar_t));
+ size_t nameTableLogicalSize = sizeof(SkOTTableName)
+ + (encodings.size() * names.size() * sizeof(SkOTTableName::Record))
+ + (fontNameLen * sizeof(SK_OT_USHORT));
size_t nameTablePhysicalSize = (nameTableLogicalSize + 3) & ~3; // Rounded up to a multiple of 4.
size_t oldNameTablePhysicalSize = (SkEndian_SwapBE32(tableEntry.logicalLength) + 3) & ~3; // Rounded up to a multiple of 4.
@@ -108,6 +115,7 @@
if (oldOffset > oldNameTableOffset) {
currentEntry->offset = SkEndian_SwapBE32(SkToU32(oldOffset - oldNameTablePhysicalSize));
}
+
if (SkOTTableHead::TAG == currentEntry->tag) {
headTableEntry = currentEntry;
}
@@ -120,19 +128,22 @@
// Write the new 'name' table after the original font data.
SkOTTableName* nameTable = reinterpret_cast<SkOTTableName*>(data + originalDataSize);
- unsigned short stringOffset = sizeof(SkOTTableName) + (namesCount * sizeof(SkOTTableName::Record));
+ unsigned short stringOffset = sizeof(SkOTTableName) + (encodings.size() * names.size() * sizeof(SkOTTableName::Record));
nameTable->format = SkOTTableName::format_0;
- nameTable->count = SkEndian_SwapBE16(namesCount);
+ nameTable->count = SkEndian_SwapBE16(encodings.size() * names.size());
nameTable->stringOffset = SkEndian_SwapBE16(stringOffset);
- SkOTTableName::Record* nameRecords = reinterpret_cast<SkOTTableName::Record*>(data + originalDataSize + sizeof(SkOTTableName));
- for (int i = 0; i < namesCount; ++i) {
- nameRecords[i].platformID.value = SkOTTableName::Record::PlatformID::Windows;
- nameRecords[i].encodingID.windows.value = SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2;
- nameRecords[i].languageID.windows.value = SkOTTableName::Record::LanguageID::Windows::English_UnitedStates;
- nameRecords[i].nameID.predefined.value = namesToCreate[i];
- nameRecords[i].offset = SkEndian_SwapBE16(0);
- nameRecords[i].length = SkEndian_SwapBE16(SkToU16(fontNameLen * sizeof(wchar_t)));
+ SkOTTableName::Record* nameRecord = reinterpret_cast<SkOTTableName::Record*>(data + originalDataSize + sizeof(SkOTTableName));
+ for (const auto& encoding : encodings) {
+ for (const auto& name : names) {
+ nameRecord->platformID.value = SkOTTableName::Record::PlatformID::Windows;
+ nameRecord->encodingID.windows.value = encoding;
+ nameRecord->languageID.windows.value = SkOTTableName::Record::LanguageID::Windows::English_UnitedStates;
+ nameRecord->nameID.predefined.value = name;
+ nameRecord->offset = SkEndian_SwapBE16(0);
+ nameRecord->length = SkEndian_SwapBE16(SkToU16(fontNameLen * sizeof(SK_OT_USHORT)));
+ ++nameRecord;
+ }
}
SK_OT_USHORT* nameString = reinterpret_cast<SK_OT_USHORT*>(data + originalDataSize + stringOffset);