// Copyright 2021 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "testing/test_fonts.h" #include #include #include #include "core/fxge/cfx_fontmapper.h" #include "core/fxge/cfx_fontmgr.h" #include "core/fxge/cfx_gemodule.h" #include "core/fxge/systemfontinfo_iface.h" #include "testing/utils/path_service.h" namespace { ByteString RenameFontForTesting(const ByteString& face) { ByteString result; if (face.Contains("Arial") || face.Contains("Calibri") || face.Contains("Helvetica")) { // Sans result = "Arimo"; } else if (face.IsEmpty() || face.Contains("Times")) { // Serif result = "Tinos"; } else if (face.Contains("Courier")) { // Mono result = "Cousine"; } else { // Some tests expect the fallback font. return face; } if (face.Contains("Bold")) { result += " Bold"; } if (face.Contains("Italic") || face.Contains("Oblique")) { result += " Italic"; } return result; } // Intercepts font requests and renames font faces to those in test_fonts. class SystemFontInfoWrapper : public SystemFontInfoIface { public: explicit SystemFontInfoWrapper(std::unique_ptr impl) : impl_(std::move(impl)) {} ~SystemFontInfoWrapper() override { CHECK(active_fonts_.empty()); } void EnumFontList(CFX_FontMapper* pMapper) override { impl_->EnumFontList(pMapper); } void* MapFont(CFX_FontMapper* mapper, int weight, bool bItalic, FX_Charset charset, int pitch_family, const ByteString& face) override { void* font = impl_->MapFont(mapper, weight, bItalic, charset, pitch_family, RenameFontForTesting(face)); if (font) { bool inserted = active_fonts_.insert(font).second; CHECK(inserted); } return font; } void* GetFont(const ByteString& face) override { return impl_->GetFont(RenameFontForTesting(face)); } size_t GetFontData(void* hFont, uint32_t table, pdfium::span buffer) override { return impl_->GetFontData(hFont, table, buffer); } bool GetFaceName(void* hFont, ByteString* name) override { auto face = RenameFontForTesting(*name); return impl_->GetFaceName(hFont, &face); } bool GetFontCharset(void* hFont, FX_Charset* charset) override { return impl_->GetFontCharset(hFont, charset); } void DeleteFont(void* hFont) override { CHECK(active_fonts_.erase(hFont)); impl_->DeleteFont(hFont); } private: std::unique_ptr impl_; std::set active_fonts_; }; } // namespace TestFonts::TestFonts() { font_path_ = PathService::GetExecutableDir(); if (font_path_.empty()) { return; } font_path_.push_back(PATH_SEPARATOR); font_path_.append("test_fonts"); font_paths_.push_back(font_path_.c_str()); font_paths_.push_back(nullptr); } TestFonts::~TestFonts() = default; void TestFonts::InstallFontMapper() { auto* font_mapper = CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper(); font_mapper->SetSystemFontInfo(std::make_unique( font_mapper->TakeSystemFontInfo())); } std::optional> TestFonts::FontPathsSpan() const { if (font_path_.empty()) { return std::nullopt; } auto font_span = pdfium::span(font_paths_); if (font_span.empty()) { return font_span; } return font_span.first(font_span.size() - 1); } // static std::string TestFonts::RenameFont(const char* face) { ByteString renamed_face = RenameFontForTesting(face); return std::string(renamed_face.c_str()); }