/* * 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 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 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(reinterpret_cast(jsonTestData->bytes()), jsonTestData->size()); const skjson::ObjectValue& root = fJsonDom->root().as(); 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()); return true; } } return false; } void TestFontDataProvider::rewind() { fFontsIndex = 0; } std::vector TestFontDataProvider::getLanguageSamples( const skjson::ArrayValue* languages) { std::vector 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; }