| /* |
| * Copyright 2023 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "tools/TestFontDataProvider.h" |
| |
| #include "include/core/SkData.h" |
| #include "include/private/base/SkDebug.h" |
| #include "src/utils/SkOSPath.h" |
| #include "tools/flags/CommandLineFlags.h" |
| |
| const char kTestDataJsonFilename[] = "raster_test.json"; |
| const char kTestDataBasePath[] = "third_party/externals/googlefonts_testdata/data/"; |
| |
| std::atomic<const char*> gFontTestDataBasePath{kTestDataBasePath}; |
| |
| namespace skiatest { |
| static DEFINE_string(fontTestDataPath, |
| "", |
| "Path to extracted data from googlefonts_testdata CIPD file."); |
| |
| void SetFontTestDataDirectory() { |
| if (FLAGS_fontTestDataPath.isEmpty()) { |
| return; |
| } |
| if (strlen(FLAGS_fontTestDataPath[0])) { |
| gFontTestDataBasePath = FLAGS_fontTestDataPath[0]; |
| } |
| } |
| } // namespace skiatest |
| |
| #if defined(SK_DEBUG) |
| // Change size when rolling / changing googlefonts_testdata CIPD, see bin/fetch-fonts-testdata. |
| constexpr size_t kExpectNumFonts = 51; |
| #endif |
| |
| namespace { |
| SkString prefixWithTestDataPath(SkString suffix) { |
| return SkOSPath::Join(gFontTestDataBasePath, suffix.c_str()); |
| } |
| |
| SkString prefixWithFontsPath(SkString suffix) { |
| SkString fontsPath = prefixWithTestDataPath(SkString("fonts")); |
| return SkOSPath::Join(fontsPath.c_str(), suffix.c_str()); |
| } |
| |
| } // namespace |
| |
| TestFontDataProvider::TestFontDataProvider(const std::string& fontFilterRegexp, |
| const std::string& langFilterRegexp) |
| : fFontFilter(fontFilterRegexp), fLangFilter(langFilterRegexp) { |
| SkString testDataLocation = prefixWithTestDataPath(SkString(kTestDataJsonFilename)); |
| sk_sp<SkData> jsonTestData = SkData::MakeFromFileName(testDataLocation.c_str()); |
| SkASSERTF(jsonTestData && jsonTestData->size(), |
| "Unable to access font test metadata at location %s, check bin/fetch-fonts-testdata.", |
| testDataLocation.c_str()); |
| fJsonDom = std::make_unique<skjson::DOM>(reinterpret_cast<const char*>(jsonTestData->bytes()), |
| jsonTestData->size()); |
| const skjson::ObjectValue& root = fJsonDom->root().as<skjson::ObjectValue>(); |
| fFonts = root["fonts"]; |
| SkASSERT(fFonts); |
| SkASSERTF(fFonts->size() == kExpectNumFonts, |
| "Unable to access all %zu test fonts (only got %zu), check bin/fetch-fonts-testdata.", |
| kExpectNumFonts, |
| fFonts->size()); |
| fSamples = root["samples"]; |
| SkASSERT(fSamples); |
| } |
| |
| bool TestFontDataProvider::next(TestSet* testSet) { |
| while (testSet && fFontsIndex < fFonts->size()) { |
| const skjson::ObjectValue* fontsEntry = (*fFonts)[fFontsIndex++]; |
| SkASSERT(fontsEntry); |
| const skjson::StringValue* fontName = (*fontsEntry)["name"]; |
| SkASSERT(fontName); |
| std::smatch match; |
| std::string fontNameStr(fontName->str()); |
| if (std::regex_match(fontNameStr, match, fFontFilter)) { |
| testSet->fontName = SkString(fontNameStr); |
| const skjson::StringValue* fontFilename = (*fontsEntry)["path"]; |
| testSet->fontFilename = prefixWithFontsPath( |
| SkString(fontFilename->str().data(), fontFilename->str().size())); |
| testSet->langSamples = |
| getLanguageSamples((*fontsEntry)["languages"].as<skjson::ArrayValue>()); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void TestFontDataProvider::rewind() { fFontsIndex = 0; } |
| |
| std::vector<TestFontDataProvider::LangSample> TestFontDataProvider::getLanguageSamples( |
| const skjson::ArrayValue* languages) { |
| std::vector<LangSample> samples; |
| for (size_t i = 0; i < languages->size(); ++i) { |
| const skjson::StringValue* langTag = (*languages)[i]; |
| std::string langTagStr(langTag->str()); |
| std::smatch match; |
| if (std::regex_match(langTagStr, match, fLangFilter)) { |
| const skjson::ObjectValue* sample = (*fSamples)[langTagStr.c_str()]; |
| const skjson::StringValue* shortSample = (*sample)["short_sample"]; |
| const skjson::StringValue* longSample = (*sample)["long_sample"]; |
| SkString sampleShort(shortSample->str().data(), shortSample->str().size()); |
| SkString sampleLong(longSample->str().data(), longSample->str().size()); |
| samples.push_back({SkString(langTagStr), sampleShort, sampleLong}); |
| } |
| } |
| SkASSERT_RELEASE(samples.size()); |
| return samples; |
| } |