84836b799a
Like any normal variable, flags can be made file-scoped static, and like any normal variable, mostly they should be if they can. This CL converts most flags to be static, if only so that the ones that do cross files stand out more clearly, and so that there's more examples of static flags through the codebase for people to ape. Change-Id: Ibb5ddd7aa09fce073d0996ac3ef0487b078b7d79 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/202800 Commit-Queue: Mike Klein <mtklein@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: Mike Klein <mtklein@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
225 lines
7.7 KiB
C++
225 lines
7.7 KiB
C++
/*
|
|
* Copyright 2013 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "CommandLineFlags.h"
|
|
#include "SkFontMgr.h"
|
|
#include "SkOTTable_name.h"
|
|
#include "SkTypeface.h"
|
|
#include "Test.h"
|
|
|
|
#include <stddef.h>
|
|
|
|
namespace {
|
|
|
|
template <size_t R, size_t D> struct Format0NameTable {
|
|
SkOTTableName header;
|
|
SkOTTableName::Record nameRecord[R];
|
|
char data[D];
|
|
};
|
|
|
|
template <size_t R, size_t L, size_t D> struct Format1NameTable {
|
|
SkOTTableName header;
|
|
SkOTTableName::Record nameRecord[R];
|
|
struct {
|
|
SkOTTableName::Format1Ext header;
|
|
SkOTTableName::Format1Ext::LangTagRecord langTagRecord[L];
|
|
} format1ext;
|
|
char data[D];
|
|
};
|
|
|
|
typedef Format0NameTable<1, 9> SimpleFormat0NameTable;
|
|
constexpr SimpleFormat0NameTable simpleFormat0NameTable = {
|
|
/*header*/ {
|
|
/*format*/ SkOTTableName::format_0,
|
|
/*count*/ SkTEndianSwap16<1>::value,
|
|
/*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat0NameTable, data)>::value,
|
|
},
|
|
/*nameRecord[]*/ {
|
|
/*Record*/ {
|
|
/*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
|
|
/*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
|
|
/*languageID*/ { SkOTTableName::Record::LanguageID::Windows::English_UnitedStates },
|
|
/*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
|
|
/*length*/ SkTEndianSwap16<8>::value,
|
|
/*offset*/ SkTEndianSwap16<0>::value,
|
|
}
|
|
},
|
|
/*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t",
|
|
};
|
|
|
|
typedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable;
|
|
constexpr SimpleFormat1NameTable simpleFormat1NameTable = {
|
|
/*header*/ {
|
|
/*format*/ SkOTTableName::format_1,
|
|
/*count*/ SkTEndianSwap16<1>::value,
|
|
/*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat1NameTable, data)>::value,
|
|
},
|
|
/*nameRecord[]*/ {
|
|
/*Record*/ {
|
|
/*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
|
|
/*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
|
|
/*languageID*/ { SkTEndianSwap16<0x8000 + 0>::value },
|
|
/*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
|
|
/*length*/ SkTEndianSwap16<8>::value,
|
|
/*offset*/ SkTEndianSwap16<0>::value,
|
|
}
|
|
},
|
|
/*format1ext*/ {
|
|
/*header*/ {
|
|
/*langTagCount*/ SkTEndianSwap16<1>::value,
|
|
},
|
|
/*langTagRecord[]*/ {
|
|
/*LangTagRecord*/ {
|
|
/*length*/ SkTEndianSwap16<10>::value,
|
|
/*offset*/ SkTEndianSwap16<8>::value,
|
|
},
|
|
},
|
|
},
|
|
/*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t"
|
|
"\x0" "e" "\x0" "n" "\x0" "-" "\x0" "U" "\x0" "S",
|
|
};
|
|
|
|
struct FontNamesTest {
|
|
const uint8_t* data;
|
|
size_t size;
|
|
SkOTTableName::Record::NameID nameID;
|
|
size_t nameCount;
|
|
struct {
|
|
const char* name;
|
|
const char* language;
|
|
} names[10];
|
|
|
|
} tests[] = {
|
|
{
|
|
reinterpret_cast<const uint8_t*>(&simpleFormat0NameTable),
|
|
sizeof(simpleFormat0NameTable),
|
|
{ SkOTTableName::Record::NameID::Predefined::FontFamilyName },
|
|
1,
|
|
{
|
|
{ "Test", "en-US" },
|
|
},
|
|
},
|
|
{
|
|
reinterpret_cast<const uint8_t*>(&simpleFormat1NameTable),
|
|
sizeof(simpleFormat1NameTable),
|
|
{ SkOTTableName::Record::NameID::Predefined::FontFamilyName },
|
|
1,
|
|
{
|
|
{ "Test", "en-US" },
|
|
},
|
|
},
|
|
};
|
|
|
|
static void test_synthetic(skiatest::Reporter* reporter, bool verbose) {
|
|
for (const auto& test : tests) {
|
|
SkOTTableName::Iterator iter(test.data, test.size, test.nameID.predefined.value);
|
|
SkOTTableName::Iterator::Record record;
|
|
size_t nameIndex = 0;
|
|
while (nameIndex < test.nameCount && iter.next(record)) {
|
|
REPORTER_ASSERT(reporter,
|
|
strcmp(test.names[nameIndex].name, record.name.c_str()) == 0,
|
|
"Name did not match.");
|
|
|
|
REPORTER_ASSERT(reporter,
|
|
strcmp(test.names[nameIndex].language, record.language.c_str()) == 0,
|
|
"Language did not match.");
|
|
|
|
if (verbose) {
|
|
SkDebugf("%s <%s>\n", record.name.c_str(), record.language.c_str());
|
|
}
|
|
|
|
++nameIndex;
|
|
}
|
|
|
|
REPORTER_ASSERT(reporter, nameIndex == test.nameCount, "Fewer names than expected.");
|
|
|
|
REPORTER_ASSERT(reporter, !iter.next(record), "More names than expected.");
|
|
}
|
|
}
|
|
|
|
#define MAX_FAMILIES 1000
|
|
static void test_systemfonts(skiatest::Reporter* reporter, bool verbose) {
|
|
static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e');
|
|
|
|
sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
|
|
int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
|
|
for (int i = 0; i < count; ++i) {
|
|
sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
|
|
for (int j = 0; j < set->count(); ++j) {
|
|
SkString sname;
|
|
SkFontStyle fs;
|
|
set->getStyle(j, &fs, &sname);
|
|
|
|
sk_sp<SkTypeface> typeface(set->createTypeface(j));
|
|
|
|
SkString familyName;
|
|
typeface->getFamilyName(&familyName);
|
|
if (verbose) {
|
|
SkDebugf("[%s]\n", familyName.c_str());
|
|
}
|
|
|
|
sk_sp<SkTypeface::LocalizedStrings> familyNamesIter(
|
|
typeface->createFamilyNameIterator());
|
|
SkTypeface::LocalizedString familyNameLocalized;
|
|
while (familyNamesIter->next(&familyNameLocalized)) {
|
|
if (verbose) {
|
|
SkDebugf("(%s) <%s>\n", familyNameLocalized.fString.c_str(),
|
|
familyNameLocalized.fLanguage.c_str());
|
|
}
|
|
}
|
|
|
|
size_t nameTableSize = typeface->getTableSize(nameTag);
|
|
if (0 == nameTableSize) {
|
|
continue;
|
|
}
|
|
SkAutoTMalloc<uint8_t> nameTableData(nameTableSize);
|
|
size_t copied = typeface->getTableData(nameTag, 0, nameTableSize, nameTableData.get());
|
|
if (copied != nameTableSize) {
|
|
continue;
|
|
}
|
|
|
|
SkOTTableName::Iterator::Record record;
|
|
SkOTTableName::Iterator familyNameIter(nameTableData.get(), nameTableSize,
|
|
SkOTTableName::Record::NameID::Predefined::FontFamilyName);
|
|
while (familyNameIter.next(record)) {
|
|
REPORTER_ASSERT(
|
|
reporter,
|
|
SkOTTableName::Record::NameID::Predefined::FontFamilyName == record.type,
|
|
"Requested family name, got something else.");
|
|
if (verbose) {
|
|
SkDebugf("{%s} <%s>\n", record.name.c_str(), record.language.c_str());
|
|
}
|
|
}
|
|
|
|
SkOTTableName::Iterator styleNameIter(nameTableData.get(), nameTableSize,
|
|
SkOTTableName::Record::NameID::Predefined::FontSubfamilyName);
|
|
while (styleNameIter.next(record)) {
|
|
REPORTER_ASSERT(
|
|
reporter,
|
|
SkOTTableName::Record::NameID::Predefined::FontSubfamilyName == record.type,
|
|
"Requested subfamily name, got something else.");
|
|
if (verbose) {
|
|
SkDebugf("{{%s}} <%s>\n", record.name.c_str(), record.language.c_str());
|
|
}
|
|
}
|
|
|
|
if (verbose) {
|
|
SkDebugf("\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
static DEFINE_bool(verboseFontNames, false, "verbose FontNames test.");
|
|
|
|
DEF_TEST(FontNames, reporter) {
|
|
test_synthetic(reporter, FLAGS_verboseFontNames);
|
|
test_systemfonts(reporter, FLAGS_verboseFontNames);
|
|
}
|