// 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 "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() { CHECK(active_fonts_.empty()); } bool EnumFontList(CFX_FontMapper* pMapper) override { return impl_->EnumFontList(pMapper); } void* MapFont(int weight, bool bItalic, FX_Charset charset, int pitch_family, const ByteString& face) override { void* font = impl_->MapFont(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() { if (!PathService::GetExecutableDir(&font_path_)) return; font_path_.push_back(PATH_SEPARATOR); font_path_.append("test_fonts"); font_paths_ = std::make_unique(2); font_paths_[0] = font_path_.c_str(); font_paths_[1] = nullptr; } TestFonts::~TestFonts() = default; void TestFonts::InstallFontMapper() { auto* font_mapper = CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper(); font_mapper->SetSystemFontInfo(std::make_unique( font_mapper->TakeSystemFontInfo())); } // static std::string TestFonts::RenameFont(const char* face) { ByteString renamed_face = RenameFontForTesting(face); return std::string(renamed_face.c_str()); }