blob: e3538dc598354b13dc7d126bcc937061c724e6a9 [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
Ben Wagnerad031f52018-08-20 13:45:57 -040016namespace {
17
bungeman@google.com07a69f82013-04-02 14:12:38 +000018template <size_t R, size_t D> struct Format0NameTable {
19 SkOTTableName header;
20 SkOTTableName::Record nameRecord[R];
21 char data[D];
22};
23
24template <size_t R, size_t L, size_t D> struct Format1NameTable {
25 SkOTTableName header;
26 SkOTTableName::Record nameRecord[R];
27 struct {
28 SkOTTableName::Format1Ext header;
29 SkOTTableName::Format1Ext::LangTagRecord langTagRecord[L];
30 } format1ext;
31 char data[D];
32};
33
34typedef Format0NameTable<1, 9> SimpleFormat0NameTable;
Ben Wagnerad031f52018-08-20 13:45:57 -040035constexpr SimpleFormat0NameTable simpleFormat0NameTable = {
bungeman@google.com07a69f82013-04-02 14:12:38 +000036 /*header*/ {
37 /*format*/ SkOTTableName::format_0,
38 /*count*/ SkTEndianSwap16<1>::value,
39 /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat0NameTable, data)>::value,
40 },
41 /*nameRecord[]*/ {
42 /*Record*/ {
43 /*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
44 /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
45 /*languageID*/ { SkOTTableName::Record::LanguageID::Windows::English_UnitedStates },
46 /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
47 /*length*/ SkTEndianSwap16<8>::value,
48 /*offset*/ SkTEndianSwap16<0>::value,
49 }
50 },
51 /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t",
52};
53
54typedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable;
Ben Wagnerad031f52018-08-20 13:45:57 -040055constexpr SimpleFormat1NameTable simpleFormat1NameTable = {
bungeman@google.com07a69f82013-04-02 14:12:38 +000056 /*header*/ {
57 /*format*/ SkOTTableName::format_1,
58 /*count*/ SkTEndianSwap16<1>::value,
59 /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat1NameTable, data)>::value,
60 },
61 /*nameRecord[]*/ {
62 /*Record*/ {
63 /*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
64 /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
65 /*languageID*/ { SkTEndianSwap16<0x8000 + 0>::value },
66 /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
67 /*length*/ SkTEndianSwap16<8>::value,
68 /*offset*/ SkTEndianSwap16<0>::value,
69 }
70 },
71 /*format1ext*/ {
72 /*header*/ {
73 /*langTagCount*/ SkTEndianSwap16<1>::value,
74 },
75 /*langTagRecord[]*/ {
76 /*LangTagRecord*/ {
77 /*length*/ SkTEndianSwap16<10>::value,
78 /*offset*/ SkTEndianSwap16<8>::value,
79 },
80 },
81 },
82 /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t"
83 "\x0" "e" "\x0" "n" "\x0" "-" "\x0" "U" "\x0" "S",
84};
85
86struct FontNamesTest {
Ben Wagnerad031f52018-08-20 13:45:57 -040087 const uint8_t* data;
88 size_t size;
bungeman@google.com07a69f82013-04-02 14:12:38 +000089 SkOTTableName::Record::NameID nameID;
90 size_t nameCount;
91 struct {
92 const char* name;
93 const char* language;
94 } names[10];
95
Ben Wagnerad031f52018-08-20 13:45:57 -040096} tests[] = {
bungeman@google.com07a69f82013-04-02 14:12:38 +000097 {
Ben Wagnerad031f52018-08-20 13:45:57 -040098 reinterpret_cast<const uint8_t*>(&simpleFormat0NameTable),
99 sizeof(simpleFormat0NameTable),
bungeman@google.com07a69f82013-04-02 14:12:38 +0000100 { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
101 1,
102 {
103 { "Test", "en-US" },
104 },
105 },
106 {
Ben Wagnerad031f52018-08-20 13:45:57 -0400107 reinterpret_cast<const uint8_t*>(&simpleFormat1NameTable),
108 sizeof(simpleFormat1NameTable),
bungeman@google.com07a69f82013-04-02 14:12:38 +0000109 { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
110 1,
111 {
112 { "Test", "en-US" },
113 },
114 },
115};
116
bungeman@google.coma9802692013-08-07 02:45:25 +0000117static void test_synthetic(skiatest::Reporter* reporter, bool verbose) {
Ben Wagnerad031f52018-08-20 13:45:57 -0400118 for (const auto& test : tests) {
119 SkOTTableName::Iterator iter(test.data, test.size, test.nameID.predefined.value);
bungeman@google.com07a69f82013-04-02 14:12:38 +0000120 SkOTTableName::Iterator::Record record;
121 size_t nameIndex = 0;
Ben Wagnerad031f52018-08-20 13:45:57 -0400122 while (nameIndex < test.nameCount && iter.next(record)) {
Brian Salomon1c80e992018-01-29 09:50:47 -0500123 REPORTER_ASSERT(reporter,
Ben Wagnerad031f52018-08-20 13:45:57 -0400124 strcmp(test.names[nameIndex].name, record.name.c_str()) == 0,
Brian Salomon1c80e992018-01-29 09:50:47 -0500125 "Name did not match.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000126
Brian Salomon1c80e992018-01-29 09:50:47 -0500127 REPORTER_ASSERT(reporter,
Ben Wagnerad031f52018-08-20 13:45:57 -0400128 strcmp(test.names[nameIndex].language, record.language.c_str()) == 0,
Brian Salomon1c80e992018-01-29 09:50:47 -0500129 "Language did not match.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000130
Ben Wagnerad031f52018-08-20 13:45:57 -0400131 if (verbose) {
132 SkDebugf("%s <%s>\n", record.name.c_str(), record.language.c_str());
133 }
bungeman@google.com07a69f82013-04-02 14:12:38 +0000134
135 ++nameIndex;
136 }
137
Ben Wagnerad031f52018-08-20 13:45:57 -0400138 REPORTER_ASSERT(reporter, nameIndex == test.nameCount, "Fewer names than expected.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000139
Brian Salomon1c80e992018-01-29 09:50:47 -0500140 REPORTER_ASSERT(reporter, !iter.next(record), "More names than expected.");
bungeman@google.com07a69f82013-04-02 14:12:38 +0000141 }
142}
143
bungeman@google.coma9802692013-08-07 02:45:25 +0000144#define MAX_FAMILIES 1000
145static void test_systemfonts(skiatest::Reporter* reporter, bool verbose) {
146 static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e');
147
Hal Canary342b7ac2016-11-04 11:49:42 -0400148 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
bungeman@google.coma9802692013-08-07 02:45:25 +0000149 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
150 for (int i = 0; i < count; ++i) {
Hal Canary342b7ac2016-11-04 11:49:42 -0400151 sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
bungeman@google.coma9802692013-08-07 02:45:25 +0000152 for (int j = 0; j < set->count(); ++j) {
153 SkString sname;
154 SkFontStyle fs;
155 set->getStyle(j, &fs, &sname);
156
Hal Canary342b7ac2016-11-04 11:49:42 -0400157 sk_sp<SkTypeface> typeface(set->createTypeface(j));
bungeman@google.coma9802692013-08-07 02:45:25 +0000158
159 SkString familyName;
160 typeface->getFamilyName(&familyName);
161 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000162 SkDebugf("[%s]\n", familyName.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000163 }
164
Hal Canary342b7ac2016-11-04 11:49:42 -0400165 sk_sp<SkTypeface::LocalizedStrings> familyNamesIter(
bungeman@google.com839702b2013-08-07 17:09:22 +0000166 typeface->createFamilyNameIterator());
bungeman@google.coma9802692013-08-07 02:45:25 +0000167 SkTypeface::LocalizedString familyNameLocalized;
168 while (familyNamesIter->next(&familyNameLocalized)) {
169 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000170 SkDebugf("(%s) <%s>\n", familyNameLocalized.fString.c_str(),
bungemana6785cc2014-08-25 12:00:49 -0700171 familyNameLocalized.fLanguage.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000172 }
173 }
174
175 size_t nameTableSize = typeface->getTableSize(nameTag);
176 if (0 == nameTableSize) {
177 continue;
178 }
179 SkAutoTMalloc<uint8_t> nameTableData(nameTableSize);
180 size_t copied = typeface->getTableData(nameTag, 0, nameTableSize, nameTableData.get());
181 if (copied != nameTableSize) {
182 continue;
183 }
184
185 SkOTTableName::Iterator::Record record;
Ben Wagnerad031f52018-08-20 13:45:57 -0400186 SkOTTableName::Iterator familyNameIter(nameTableData.get(), nameTableSize,
bungeman@google.coma9802692013-08-07 02:45:25 +0000187 SkOTTableName::Record::NameID::Predefined::FontFamilyName);
188 while (familyNameIter.next(record)) {
Brian Salomon1c80e992018-01-29 09:50:47 -0500189 REPORTER_ASSERT(
190 reporter,
191 SkOTTableName::Record::NameID::Predefined::FontFamilyName == record.type,
192 "Requested family name, got something else.");
bungeman@google.coma9802692013-08-07 02:45:25 +0000193 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000194 SkDebugf("{%s} <%s>\n", record.name.c_str(), record.language.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000195 }
196 }
197
Ben Wagnerad031f52018-08-20 13:45:57 -0400198 SkOTTableName::Iterator styleNameIter(nameTableData.get(), nameTableSize,
bungeman@google.coma9802692013-08-07 02:45:25 +0000199 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName);
200 while (styleNameIter.next(record)) {
Brian Salomon1c80e992018-01-29 09:50:47 -0500201 REPORTER_ASSERT(
202 reporter,
203 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName == record.type,
204 "Requested subfamily name, got something else.");
bungeman@google.coma9802692013-08-07 02:45:25 +0000205 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000206 SkDebugf("{{%s}} <%s>\n", record.name.c_str(), record.language.c_str());
bungeman@google.coma9802692013-08-07 02:45:25 +0000207 }
208 }
209
210 if (verbose) {
bungeman@google.comfab44db2013-10-11 18:50:45 +0000211 SkDebugf("\n");
bungeman@google.coma9802692013-08-07 02:45:25 +0000212 }
213 }
214 }
215}
216
Ben Wagnerad031f52018-08-20 13:45:57 -0400217} // namespace
218
bungeman@google.coma9802692013-08-07 02:45:25 +0000219DEFINE_bool(verboseFontNames, false, "verbose FontNames test.");
220
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000221DEF_TEST(FontNames, reporter) {
bungeman@google.coma9802692013-08-07 02:45:25 +0000222 test_synthetic(reporter, FLAGS_verboseFontNames);
223 test_systemfonts(reporter, FLAGS_verboseFontNames);
224}