1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2013 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkFontMgr.h" 9cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h" 10cb93a386Sopenharmony_ci#include "src/sfnt/SkOTTable_name.h" 11cb93a386Sopenharmony_ci#include "tests/Test.h" 12cb93a386Sopenharmony_ci#include "tools/flags/CommandLineFlags.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci#include <stddef.h> 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cinamespace { 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_citemplate <size_t R, size_t D> struct Format0NameTable { 19cb93a386Sopenharmony_ci SkOTTableName header; 20cb93a386Sopenharmony_ci SkOTTableName::Record nameRecord[R]; 21cb93a386Sopenharmony_ci char data[D]; 22cb93a386Sopenharmony_ci}; 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_citemplate <size_t R, size_t L, size_t D> struct Format1NameTable { 25cb93a386Sopenharmony_ci SkOTTableName header; 26cb93a386Sopenharmony_ci SkOTTableName::Record nameRecord[R]; 27cb93a386Sopenharmony_ci struct { 28cb93a386Sopenharmony_ci SkOTTableName::Format1Ext header; 29cb93a386Sopenharmony_ci SkOTTableName::Format1Ext::LangTagRecord langTagRecord[L]; 30cb93a386Sopenharmony_ci } format1ext; 31cb93a386Sopenharmony_ci char data[D]; 32cb93a386Sopenharmony_ci}; 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_citypedef Format0NameTable<1, 9> SimpleFormat0NameTable; 35cb93a386Sopenharmony_ciconstexpr SimpleFormat0NameTable simpleFormat0NameTable = { 36cb93a386Sopenharmony_ci /*header*/ { 37cb93a386Sopenharmony_ci /*format*/ SkOTTableName::format_0, 38cb93a386Sopenharmony_ci /*count*/ SkTEndianSwap16<1>::value, 39cb93a386Sopenharmony_ci /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat0NameTable, data)>::value, 40cb93a386Sopenharmony_ci }, 41cb93a386Sopenharmony_ci /*nameRecord[]*/ { 42cb93a386Sopenharmony_ci /*Record*/ { 43cb93a386Sopenharmony_ci /*platformID*/ { SkOTTableName::Record::PlatformID::Windows }, 44cb93a386Sopenharmony_ci /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 }, 45cb93a386Sopenharmony_ci /*languageID*/ { SkOTTableName::Record::LanguageID::Windows::English_UnitedStates }, 46cb93a386Sopenharmony_ci /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName }, 47cb93a386Sopenharmony_ci /*length*/ SkTEndianSwap16<8>::value, 48cb93a386Sopenharmony_ci /*offset*/ SkTEndianSwap16<0>::value, 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci }, 51cb93a386Sopenharmony_ci /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t", 52cb93a386Sopenharmony_ci}; 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_citypedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable; 55cb93a386Sopenharmony_ciconstexpr SimpleFormat1NameTable simpleFormat1NameTable = { 56cb93a386Sopenharmony_ci /*header*/ { 57cb93a386Sopenharmony_ci /*format*/ SkOTTableName::format_1, 58cb93a386Sopenharmony_ci /*count*/ SkTEndianSwap16<1>::value, 59cb93a386Sopenharmony_ci /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat1NameTable, data)>::value, 60cb93a386Sopenharmony_ci }, 61cb93a386Sopenharmony_ci /*nameRecord[]*/ { 62cb93a386Sopenharmony_ci /*Record*/ { 63cb93a386Sopenharmony_ci /*platformID*/ { SkOTTableName::Record::PlatformID::Windows }, 64cb93a386Sopenharmony_ci /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 }, 65cb93a386Sopenharmony_ci /*languageID*/ { SkTEndianSwap16<0x8000 + 0>::value }, 66cb93a386Sopenharmony_ci /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName }, 67cb93a386Sopenharmony_ci /*length*/ SkTEndianSwap16<8>::value, 68cb93a386Sopenharmony_ci /*offset*/ SkTEndianSwap16<0>::value, 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci }, 71cb93a386Sopenharmony_ci /*format1ext*/ { 72cb93a386Sopenharmony_ci /*header*/ { 73cb93a386Sopenharmony_ci /*langTagCount*/ SkTEndianSwap16<1>::value, 74cb93a386Sopenharmony_ci }, 75cb93a386Sopenharmony_ci /*langTagRecord[]*/ { 76cb93a386Sopenharmony_ci /*LangTagRecord*/ { 77cb93a386Sopenharmony_ci /*length*/ SkTEndianSwap16<10>::value, 78cb93a386Sopenharmony_ci /*offset*/ SkTEndianSwap16<8>::value, 79cb93a386Sopenharmony_ci }, 80cb93a386Sopenharmony_ci }, 81cb93a386Sopenharmony_ci }, 82cb93a386Sopenharmony_ci /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t" 83cb93a386Sopenharmony_ci "\x0" "e" "\x0" "n" "\x0" "-" "\x0" "U" "\x0" "S", 84cb93a386Sopenharmony_ci}; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_cistruct FontNamesTest { 87cb93a386Sopenharmony_ci const uint8_t* data; 88cb93a386Sopenharmony_ci size_t size; 89cb93a386Sopenharmony_ci SkOTTableName::Record::NameID nameID; 90cb93a386Sopenharmony_ci size_t nameCount; 91cb93a386Sopenharmony_ci struct { 92cb93a386Sopenharmony_ci const char* name; 93cb93a386Sopenharmony_ci const char* language; 94cb93a386Sopenharmony_ci } names[10]; 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci} tests[] = { 97cb93a386Sopenharmony_ci { 98cb93a386Sopenharmony_ci reinterpret_cast<const uint8_t*>(&simpleFormat0NameTable), 99cb93a386Sopenharmony_ci sizeof(simpleFormat0NameTable), 100cb93a386Sopenharmony_ci { SkOTTableName::Record::NameID::Predefined::FontFamilyName }, 101cb93a386Sopenharmony_ci 1, 102cb93a386Sopenharmony_ci { 103cb93a386Sopenharmony_ci { "Test", "en-US" }, 104cb93a386Sopenharmony_ci }, 105cb93a386Sopenharmony_ci }, 106cb93a386Sopenharmony_ci { 107cb93a386Sopenharmony_ci reinterpret_cast<const uint8_t*>(&simpleFormat1NameTable), 108cb93a386Sopenharmony_ci sizeof(simpleFormat1NameTable), 109cb93a386Sopenharmony_ci { SkOTTableName::Record::NameID::Predefined::FontFamilyName }, 110cb93a386Sopenharmony_ci 1, 111cb93a386Sopenharmony_ci { 112cb93a386Sopenharmony_ci { "Test", "en-US" }, 113cb93a386Sopenharmony_ci }, 114cb93a386Sopenharmony_ci }, 115cb93a386Sopenharmony_ci}; 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_cistatic void test_synthetic(skiatest::Reporter* reporter, bool verbose) { 118cb93a386Sopenharmony_ci for (const auto& test : tests) { 119cb93a386Sopenharmony_ci SkOTTableName::Iterator iter(test.data, test.size, test.nameID.predefined.value); 120cb93a386Sopenharmony_ci SkOTTableName::Iterator::Record record; 121cb93a386Sopenharmony_ci size_t nameIndex = 0; 122cb93a386Sopenharmony_ci while (nameIndex < test.nameCount && iter.next(record)) { 123cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 124cb93a386Sopenharmony_ci strcmp(test.names[nameIndex].name, record.name.c_str()) == 0, 125cb93a386Sopenharmony_ci "Name did not match."); 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 128cb93a386Sopenharmony_ci strcmp(test.names[nameIndex].language, record.language.c_str()) == 0, 129cb93a386Sopenharmony_ci "Language did not match."); 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci if (verbose) { 132cb93a386Sopenharmony_ci SkDebugf("%s <%s>\n", record.name.c_str(), record.language.c_str()); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci ++nameIndex; 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, nameIndex == test.nameCount, "Fewer names than expected."); 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !iter.next(record), "More names than expected."); 141cb93a386Sopenharmony_ci } 142cb93a386Sopenharmony_ci} 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci#define MAX_FAMILIES 1000 145cb93a386Sopenharmony_cistatic void test_systemfonts(skiatest::Reporter* reporter, bool verbose) { 146cb93a386Sopenharmony_ci static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e'); 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 149cb93a386Sopenharmony_ci int count = std::min(fm->countFamilies(), MAX_FAMILIES); 150cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 151cb93a386Sopenharmony_ci sk_sp<SkFontStyleSet> set(fm->createStyleSet(i)); 152cb93a386Sopenharmony_ci for (int j = 0; j < set->count(); ++j) { 153cb93a386Sopenharmony_ci SkString sname; 154cb93a386Sopenharmony_ci SkFontStyle fs; 155cb93a386Sopenharmony_ci set->getStyle(j, &fs, &sname); 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ci sk_sp<SkTypeface> typeface(set->createTypeface(j)); 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci SkString familyName; 160cb93a386Sopenharmony_ci typeface->getFamilyName(&familyName); 161cb93a386Sopenharmony_ci if (verbose) { 162cb93a386Sopenharmony_ci SkDebugf("[%s]\n", familyName.c_str()); 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci sk_sp<SkTypeface::LocalizedStrings> familyNamesIter( 166cb93a386Sopenharmony_ci typeface->createFamilyNameIterator()); 167cb93a386Sopenharmony_ci SkTypeface::LocalizedString familyNameLocalized; 168cb93a386Sopenharmony_ci while (familyNamesIter->next(&familyNameLocalized)) { 169cb93a386Sopenharmony_ci if (verbose) { 170cb93a386Sopenharmony_ci SkDebugf("(%s) <%s>\n", familyNameLocalized.fString.c_str(), 171cb93a386Sopenharmony_ci familyNameLocalized.fLanguage.c_str()); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci size_t nameTableSize = typeface->getTableSize(nameTag); 176cb93a386Sopenharmony_ci if (0 == nameTableSize) { 177cb93a386Sopenharmony_ci continue; 178cb93a386Sopenharmony_ci } 179cb93a386Sopenharmony_ci SkAutoTMalloc<uint8_t> nameTableData(nameTableSize); 180cb93a386Sopenharmony_ci size_t copied = typeface->getTableData(nameTag, 0, nameTableSize, nameTableData.get()); 181cb93a386Sopenharmony_ci if (copied != nameTableSize) { 182cb93a386Sopenharmony_ci continue; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci SkOTTableName::Iterator::Record record; 186cb93a386Sopenharmony_ci SkOTTableName::Iterator familyNameIter(nameTableData.get(), nameTableSize, 187cb93a386Sopenharmony_ci SkOTTableName::Record::NameID::Predefined::FontFamilyName); 188cb93a386Sopenharmony_ci while (familyNameIter.next(record)) { 189cb93a386Sopenharmony_ci REPORTER_ASSERT( 190cb93a386Sopenharmony_ci reporter, 191cb93a386Sopenharmony_ci SkOTTableName::Record::NameID::Predefined::FontFamilyName == record.type, 192cb93a386Sopenharmony_ci "Requested family name, got something else."); 193cb93a386Sopenharmony_ci if (verbose) { 194cb93a386Sopenharmony_ci SkDebugf("{%s} <%s>\n", record.name.c_str(), record.language.c_str()); 195cb93a386Sopenharmony_ci } 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_ci SkOTTableName::Iterator styleNameIter(nameTableData.get(), nameTableSize, 199cb93a386Sopenharmony_ci SkOTTableName::Record::NameID::Predefined::FontSubfamilyName); 200cb93a386Sopenharmony_ci while (styleNameIter.next(record)) { 201cb93a386Sopenharmony_ci REPORTER_ASSERT( 202cb93a386Sopenharmony_ci reporter, 203cb93a386Sopenharmony_ci SkOTTableName::Record::NameID::Predefined::FontSubfamilyName == record.type, 204cb93a386Sopenharmony_ci "Requested subfamily name, got something else."); 205cb93a386Sopenharmony_ci if (verbose) { 206cb93a386Sopenharmony_ci SkDebugf("{{%s}} <%s>\n", record.name.c_str(), record.language.c_str()); 207cb93a386Sopenharmony_ci } 208cb93a386Sopenharmony_ci } 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ci if (verbose) { 211cb93a386Sopenharmony_ci SkDebugf("\n"); 212cb93a386Sopenharmony_ci } 213cb93a386Sopenharmony_ci } 214cb93a386Sopenharmony_ci } 215cb93a386Sopenharmony_ci} 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci} // namespace 218cb93a386Sopenharmony_ci 219cb93a386Sopenharmony_cistatic DEFINE_bool(verboseFontNames, false, "verbose FontNames test."); 220cb93a386Sopenharmony_ci 221cb93a386Sopenharmony_ciDEF_TEST(FontNames, reporter) { 222cb93a386Sopenharmony_ci test_synthetic(reporter, FLAGS_verboseFontNames); 223cb93a386Sopenharmony_ci test_systemfonts(reporter, FLAGS_verboseFontNames); 224cb93a386Sopenharmony_ci} 225