blob: c86951e78d24424c976de164926ad25be50ed01d [file] [log] [blame]
/*
* 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;
}