2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkCommandLineFlags.h"
10 #include "SkOTTable_name.h"
11 #include "SkTypeface.h"
16 template <size_t R, size_t D> struct Format0NameTable {
18 SkOTTableName::Record nameRecord[R];
22 template <size_t R, size_t L, size_t D> struct Format1NameTable {
24 SkOTTableName::Record nameRecord[R];
26 SkOTTableName::Format1Ext header;
27 SkOTTableName::Format1Ext::LangTagRecord langTagRecord[L];
32 typedef Format0NameTable<1, 9> SimpleFormat0NameTable;
33 SimpleFormat0NameTable simpleFormat0NameTable = {
35 /*format*/ SkOTTableName::format_0,
36 /*count*/ SkTEndianSwap16<1>::value,
37 /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat0NameTable, data)>::value,
41 /*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
42 /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
43 /*languageID*/ { SkOTTableName::Record::LanguageID::Windows::English_UnitedStates },
44 /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
45 /*length*/ SkTEndianSwap16<8>::value,
46 /*offset*/ SkTEndianSwap16<0>::value,
49 /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t",
52 typedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable;
53 SimpleFormat1NameTable simpleFormat1NameTable = {
55 /*format*/ SkOTTableName::format_1,
56 /*count*/ SkTEndianSwap16<1>::value,
57 /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat1NameTable, data)>::value,
61 /*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
62 /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
63 /*languageID*/ { SkTEndianSwap16<0x8000 + 0>::value },
64 /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
65 /*length*/ SkTEndianSwap16<8>::value,
66 /*offset*/ SkTEndianSwap16<0>::value,
71 /*langTagCount*/ SkTEndianSwap16<1>::value,
75 /*length*/ SkTEndianSwap16<10>::value,
76 /*offset*/ SkTEndianSwap16<8>::value,
80 /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t"
81 "\x0" "e" "\x0" "n" "\x0" "-" "\x0" "U" "\x0" "S",
84 struct FontNamesTest {
86 SkOTTableName::Record::NameID nameID;
95 (SkOTTableName*)&simpleFormat0NameTable,
96 { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
103 (SkOTTableName*)&simpleFormat1NameTable,
104 { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
112 static void test_synthetic(skiatest::Reporter* reporter, bool verbose) {
113 for (size_t i = 0; i < SK_ARRAY_COUNT(test); ++i) {
114 SkOTTableName::Iterator iter(*test[i].data, test[i].nameID.predefined.value);
115 SkOTTableName::Iterator::Record record;
116 size_t nameIndex = 0;
117 while (nameIndex < test[i].nameCount && iter.next(record)) {
118 REPORTER_ASSERT_MESSAGE(reporter,
119 strcmp(test[i].names[nameIndex].name, record.name.c_str()) == 0,
120 "Name did not match."
123 REPORTER_ASSERT_MESSAGE(reporter,
124 strcmp(test[i].names[nameIndex].language, record.language.c_str()) == 0,
125 "Language did not match."
128 //printf("%s <%s>\n", record.name.c_str(), record.language.c_str());
133 REPORTER_ASSERT_MESSAGE(reporter, nameIndex == test[i].nameCount,
134 "Fewer names than expected.");
136 REPORTER_ASSERT_MESSAGE(reporter, !iter.next(record),
137 "More names than expected.");
141 #define MAX_FAMILIES 1000
142 static void test_systemfonts(skiatest::Reporter* reporter, bool verbose) {
143 static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e');
145 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
146 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
147 for (int i = 0; i < count; ++i) {
148 SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i));
149 for (int j = 0; j < set->count(); ++j) {
152 set->getStyle(j, &fs, &sname);
154 SkAutoTUnref<SkTypeface> typeface(set->createTypeface(j));
157 typeface->getFamilyName(&familyName);
159 SkDebugf("[%s]\n", familyName.c_str());
162 SkAutoTUnref<SkTypeface::LocalizedStrings> familyNamesIter(
163 typeface->createFamilyNameIterator());
164 SkTypeface::LocalizedString familyNameLocalized;
165 while (familyNamesIter->next(&familyNameLocalized)) {
167 SkDebugf("(%s) <%s>\n", familyNameLocalized.fString.c_str(),
168 familyNameLocalized.fLanguage.c_str());
172 size_t nameTableSize = typeface->getTableSize(nameTag);
173 if (0 == nameTableSize) {
176 SkAutoTMalloc<uint8_t> nameTableData(nameTableSize);
177 size_t copied = typeface->getTableData(nameTag, 0, nameTableSize, nameTableData.get());
178 if (copied != nameTableSize) {
182 SkOTTableName::Iterator::Record record;
183 SkOTTableName::Iterator familyNameIter(*((SkOTTableName*)nameTableData.get()),
184 SkOTTableName::Record::NameID::Predefined::FontFamilyName);
185 while (familyNameIter.next(record)) {
186 REPORTER_ASSERT_MESSAGE(reporter,
187 SkOTTableName::Record::NameID::Predefined::FontFamilyName == record.type,
188 "Requested family name, got something else."
191 SkDebugf("{%s} <%s>\n", record.name.c_str(), record.language.c_str());
195 SkOTTableName::Iterator styleNameIter(*((SkOTTableName*)nameTableData.get()),
196 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName);
197 while (styleNameIter.next(record)) {
198 REPORTER_ASSERT_MESSAGE(reporter,
199 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName == record.type,
200 "Requested subfamily name, got something else."
203 SkDebugf("{{%s}} <%s>\n", record.name.c_str(), record.language.c_str());
214 DEFINE_bool(verboseFontNames, false, "verbose FontNames test.");
216 DEF_TEST(FontNames, reporter) {
217 test_synthetic(reporter, FLAGS_verboseFontNames);
218 test_systemfonts(reporter, FLAGS_verboseFontNames);