/src/skia/tools/TestFontDataProvider.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2023 Google LLC |
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 | | |
8 | | #include "tools/TestFontDataProvider.h" |
9 | | |
10 | | #include "include/core/SkData.h" |
11 | | #include "include/private/base/SkDebug.h" |
12 | | #include "src/utils/SkOSPath.h" |
13 | | #include "tools/flags/CommandLineFlags.h" |
14 | | |
15 | | const char kTestDataJsonFilename[] = "raster_test.json"; |
16 | | const char kTestDataBasePath[] = "third_party/externals/googlefonts_testdata/data/"; |
17 | | |
18 | | std::atomic<const char*> gFontTestDataBasePath{kTestDataBasePath}; |
19 | | |
20 | | namespace skiatest { |
21 | | static DEFINE_string(fontTestDataPath, |
22 | | "", |
23 | | "Path to extracted data from googlefonts_testdata CIPD file."); |
24 | | |
25 | 0 | void SetFontTestDataDirectory() { |
26 | 0 | if (FLAGS_fontTestDataPath.isEmpty()) { |
27 | 0 | return; |
28 | 0 | } |
29 | 0 | if (strlen(FLAGS_fontTestDataPath[0])) { |
30 | 0 | gFontTestDataBasePath = FLAGS_fontTestDataPath[0]; |
31 | 0 | } |
32 | 0 | } |
33 | | } // namespace skiatest |
34 | | |
35 | | #if defined(SK_DEBUG) |
36 | | // Change size when rolling / changing googlefonts_testdata CIPD, see bin/fetch-fonts-testdata. |
37 | | constexpr size_t kExpectNumFonts = 51; |
38 | | #endif |
39 | | |
40 | | namespace { |
41 | 0 | SkString prefixWithTestDataPath(SkString suffix) { |
42 | 0 | return SkOSPath::Join(gFontTestDataBasePath, suffix.c_str()); |
43 | 0 | } |
44 | | |
45 | 0 | SkString prefixWithFontsPath(SkString suffix) { |
46 | 0 | SkString fontsPath = prefixWithTestDataPath(SkString("fonts")); |
47 | 0 | return SkOSPath::Join(fontsPath.c_str(), suffix.c_str()); |
48 | 0 | } |
49 | | |
50 | | } // namespace |
51 | | |
52 | | TestFontDataProvider::TestFontDataProvider(const std::string& fontFilterRegexp, |
53 | | const std::string& langFilterRegexp) |
54 | 0 | : fFontFilter(fontFilterRegexp), fLangFilter(langFilterRegexp) { |
55 | 0 | SkString testDataLocation = prefixWithTestDataPath(SkString(kTestDataJsonFilename)); |
56 | 0 | sk_sp<SkData> jsonTestData = SkData::MakeFromFileName(testDataLocation.c_str()); |
57 | 0 | SkASSERTF(jsonTestData && jsonTestData->size(), |
58 | 0 | "Unable to access font test metadata at location %s, check bin/fetch-fonts-testdata.", |
59 | 0 | testDataLocation.c_str()); |
60 | 0 | fJsonDom = std::make_unique<skjson::DOM>(reinterpret_cast<const char*>(jsonTestData->bytes()), |
61 | 0 | jsonTestData->size()); |
62 | 0 | const skjson::ObjectValue& root = fJsonDom->root().as<skjson::ObjectValue>(); |
63 | 0 | fFonts = root["fonts"]; |
64 | 0 | SkASSERT(fFonts); |
65 | 0 | SkASSERTF(fFonts->size() == kExpectNumFonts, |
66 | 0 | "Unable to access all %zu test fonts (only got %zu), check bin/fetch-fonts-testdata.", |
67 | 0 | kExpectNumFonts, |
68 | 0 | fFonts->size()); |
69 | 0 | fSamples = root["samples"]; |
70 | 0 | SkASSERT(fSamples); |
71 | 0 | } Unexecuted instantiation: TestFontDataProvider::TestFontDataProvider(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: TestFontDataProvider::TestFontDataProvider(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) |
72 | | |
73 | 0 | bool TestFontDataProvider::next(TestSet* testSet) { |
74 | 0 | while (testSet && fFontsIndex < fFonts->size()) { |
75 | 0 | const skjson::ObjectValue* fontsEntry = (*fFonts)[fFontsIndex++]; |
76 | 0 | SkASSERT(fontsEntry); |
77 | 0 | const skjson::StringValue* fontName = (*fontsEntry)["name"]; |
78 | 0 | SkASSERT(fontName); |
79 | 0 | std::smatch match; |
80 | 0 | std::string fontNameStr(fontName->str()); |
81 | 0 | if (std::regex_match(fontNameStr, match, fFontFilter)) { |
82 | 0 | testSet->fontName = SkString(fontNameStr); |
83 | 0 | const skjson::StringValue* fontFilename = (*fontsEntry)["path"]; |
84 | 0 | testSet->fontFilename = prefixWithFontsPath( |
85 | 0 | SkString(fontFilename->str().data(), fontFilename->str().size())); |
86 | 0 | testSet->langSamples = |
87 | 0 | getLanguageSamples((*fontsEntry)["languages"].as<skjson::ArrayValue>()); |
88 | 0 | return true; |
89 | 0 | } |
90 | 0 | } |
91 | 0 | return false; |
92 | 0 | } Unexecuted instantiation: TestFontDataProvider::next(TestFontDataProvider::TestSet*) Unexecuted instantiation: TestFontDataProvider::next(TestFontDataProvider::TestSet*) |
93 | | |
94 | 0 | void TestFontDataProvider::rewind() { fFontsIndex = 0; } |
95 | | |
96 | | std::vector<TestFontDataProvider::LangSample> TestFontDataProvider::getLanguageSamples( |
97 | 0 | const skjson::ArrayValue* languages) { |
98 | 0 | std::vector<LangSample> samples; |
99 | 0 | for (size_t i = 0; i < languages->size(); ++i) { |
100 | 0 | const skjson::StringValue* langTag = (*languages)[i]; |
101 | 0 | std::string langTagStr(langTag->str()); |
102 | 0 | std::smatch match; |
103 | 0 | if (std::regex_match(langTagStr, match, fLangFilter)) { |
104 | 0 | const skjson::ObjectValue* sample = (*fSamples)[langTagStr.c_str()]; |
105 | 0 | const skjson::StringValue* shortSample = (*sample)["short_sample"]; |
106 | 0 | const skjson::StringValue* longSample = (*sample)["long_sample"]; |
107 | 0 | SkString sampleShort(shortSample->str().data(), shortSample->str().size()); |
108 | 0 | SkString sampleLong(longSample->str().data(), longSample->str().size()); |
109 | 0 | samples.push_back({SkString(langTagStr), sampleShort, sampleLong}); |
110 | 0 | } |
111 | 0 | } |
112 | 0 | SkASSERT_RELEASE(samples.size()); |
113 | 0 | return samples; |
114 | 0 | } |