blob: 3218b29e52f8fa88128dad432f4cd1b1fa391611 [file] [log] [blame]
bungeman@google.com07a69f82013-04-02 14:12:38 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
bungeman@google.coma9802692013-08-07 02:45:25 +00008#include "SkCommandLineFlags.h"
9#include "SkFontMgr.h"
bungeman@google.com07a69f82013-04-02 14:12:38 +000010#include "SkOTTable_name.h"
11#include "SkTypeface.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000012#include "Test.h"
bungeman@google.com07a69f82013-04-02 14:12:38 +000013
14#include <stddef.h>
15
16template <size_t R, size_t D> struct Format0NameTable {
17 SkOTTableName header;
18 SkOTTableName::Record nameRecord[R];
19 char data[D];
20};
21
22template <size_t R, size_t L, size_t D> struct Format1NameTable {
23 SkOTTableName header;
24 SkOTTableName::Record nameRecord[R];
25 struct {
26 SkOTTableName::Format1Ext header;
27 SkOTTableName::Format1Ext::LangTagRecord langTagRecord[L];
28 } format1ext;
29 char data[D];
30};
31
32typedef Format0NameTable<1, 9> SimpleFormat0NameTable;
33SimpleFormat0NameTable simpleFormat0NameTable = {
34 /*header*/ {
35 /*format*/ SkOTTableName::format_0,
36 /*count*/ SkTEndianSwap16<1>::value,
37 /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat0NameTable, data)>::value,
38 },
39 /*nameRecord[]*/ {
40 /*Record*/ {
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,
47 }
48 },
49 /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t",
50};
51
52typedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable;
53SimpleFormat1NameTable simpleFormat1NameTable = {
54 /*header*/ {
55 /*format*/ SkOTTableName::format_1,
56 /*count*/ SkTEndianSwap16<1>::value,
57 /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat1NameTable, data)>::value,
58 },
59 /*nameRecord[]*/ {
60 /*Record*/ {
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,
67 }
68 },
69 /*format1ext*/ {
70 /*header*/ {
71 /*langTagCount*/ SkTEndianSwap16<1>::value,
72 },
73 /*langTagRecord[]*/ {
74 /*LangTagRecord*/ {
75 /*length*/ SkTEndianSwap16<10>::value,
76 /*offset*/ SkTEndianSwap16<8>::value,
77 },
78 },
79 },
80 /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t"
81 "\x0" "e" "\x0" "n" "\x0" "-" "\x0" "U" "\x0" "S",
82};
83
84struct FontNamesTest {
85 SkOTTableName* data;
86 SkOTTableName::Record::NameID nameID;
87 size_t nameCount;
88 struct {
89 const char* name;
90 const char* language;
91 } names[10];
92
93} test[] = {
94 {
95 (SkOTTableName*)&simpleFormat0NameTable,
96 { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
97 1,
98 {
99 { "Test", "en-US" },
100 },
101 },
102 {
103 (SkOTTableName*)&simpleFormat1NameTable,
104 { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
105 1,
106 {
107 { "Test", "en-US" },
108 },
109 },
110};
111
bungeman@google.coma9802692013-08-07 02:45:25 +0000112static void test_synthetic(skiatest::Reporter* reporter, bool verbose) {
bungeman@google.com07a69f82013-04-02 14:12:38 +0000113 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)) {
Brian Salomon1c80e992018-01-29 09:50:47 -0500118 REPORTER_ASSERT(reporter,
119 strcmp(test[i].names[nameIndex].name, record.name.c_str()) == 0,
120 "Name did not match.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000121
Brian Salomon1c80e992018-01-29 09:50:47 -0500122 REPORTER_ASSERT(reporter,
123 strcmp(test[i].names[nameIndex].language, record.language.c_str()) == 0,
124 "Language did not match.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000125
126 //printf("%s <%s>\n", record.name.c_str(), record.language.c_str());
127
128 ++nameIndex;
129 }
130
Brian Salomon1c80e992018-01-29 09:50:47 -0500131 REPORTER_ASSERT(reporter, nameIndex == test[i].nameCount, "Fewer names than expected.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000132
Brian Salomon1c80e992018-01-29 09:50:47 -0500133 REPORTER_ASSERT(reporter, !iter.next(record), "More names than expected.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000134 }
135}
136
bungeman@google.coma9802692013-08-07 02:45:25 +0000137#define MAX_FAMILIES 1000
138static void test_systemfonts(skiatest::Reporter* reporter, bool verbose) {
139 static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e');
140
Hal Canary342b7ac2016-11-04 11:49:42 -0400141 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
bungeman@google.coma9802692013-08-07 02:45:25 +0000142 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
143 for (int i = 0; i < count; ++i) {
Hal Canary342b7ac2016-11-04 11:49:42 -0400144 sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
bungeman@google.coma9802692013-08-07 02:45:25 +0000145 for (int j = 0; j < set->count(); ++j) {
146 SkString sname;
147 SkFontStyle fs;
148 set->getStyle(j, &fs, &sname);
149
Hal Canary342b7ac2016-11-04 11:49:42 -0400150 sk_sp<SkTypeface> typeface(set->createTypeface(j));
bungeman@google.coma9802692013-08-07 02:45:25 +0000151
152 SkString familyName;
153 typeface->getFamilyName(&familyName);
154 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000155 SkDebugf("[%s]\n", familyName.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000156 }
157
Hal Canary342b7ac2016-11-04 11:49:42 -0400158 sk_sp<SkTypeface::LocalizedStrings> familyNamesIter(
bungeman@google.com839702b2013-08-07 17:09:22 +0000159 typeface->createFamilyNameIterator());
bungeman@google.coma9802692013-08-07 02:45:25 +0000160 SkTypeface::LocalizedString familyNameLocalized;
161 while (familyNamesIter->next(&familyNameLocalized)) {
162 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000163 SkDebugf("(%s) <%s>\n", familyNameLocalized.fString.c_str(),
bungemana6785cc2014-08-25 12:00:49 -0700164 familyNameLocalized.fLanguage.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000165 }
166 }
167
168 size_t nameTableSize = typeface->getTableSize(nameTag);
169 if (0 == nameTableSize) {
170 continue;
171 }
172 SkAutoTMalloc<uint8_t> nameTableData(nameTableSize);
173 size_t copied = typeface->getTableData(nameTag, 0, nameTableSize, nameTableData.get());
174 if (copied != nameTableSize) {
175 continue;
176 }
177
178 SkOTTableName::Iterator::Record record;
179 SkOTTableName::Iterator familyNameIter(*((SkOTTableName*)nameTableData.get()),
180 SkOTTableName::Record::NameID::Predefined::FontFamilyName);
181 while (familyNameIter.next(record)) {
Brian Salomon1c80e992018-01-29 09:50:47 -0500182 REPORTER_ASSERT(
183 reporter,
184 SkOTTableName::Record::NameID::Predefined::FontFamilyName == record.type,
185 "Requested family name, got something else.");
bungeman@google.coma9802692013-08-07 02:45:25 +0000186 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000187 SkDebugf("{%s} <%s>\n", record.name.c_str(), record.language.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000188 }
189 }
190
191 SkOTTableName::Iterator styleNameIter(*((SkOTTableName*)nameTableData.get()),
192 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName);
193 while (styleNameIter.next(record)) {
Brian Salomon1c80e992018-01-29 09:50:47 -0500194 REPORTER_ASSERT(
195 reporter,
196 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName == record.type,
197 "Requested subfamily name, got something else.");
bungeman@google.coma9802692013-08-07 02:45:25 +0000198 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000199 SkDebugf("{{%s}} <%s>\n", record.name.c_str(), record.language.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000200 }
201 }
202
203 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000204 SkDebugf("\n");
bungeman@google.coma9802692013-08-07 02:45:25 +0000205 }
206 }
207 }
208}
209
210DEFINE_bool(verboseFontNames, false, "verbose FontNames test.");
211
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000212DEF_TEST(FontNames, reporter) {
bungeman@google.coma9802692013-08-07 02:45:25 +0000213 test_synthetic(reporter, FLAGS_verboseFontNames);
214 test_systemfonts(reporter, FLAGS_verboseFontNames);
215}