// Copyright 2019 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "public/fpdf_sysfontinfo.h" #include "testing/embedder_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/base/stl_util.h" namespace { extern "C" { void FakeRelease(FPDF_SYSFONTINFO* pThis) {} void FakeEnumFonts(FPDF_SYSFONTINFO* pThis, void* pMapper) {} void* FakeMapFont(FPDF_SYSFONTINFO* pThis, int weight, FPDF_BOOL bItalic, int charset, int pitch_family, const char* face, FPDF_BOOL* bExact) { // Any non-null return will do. return pThis; } void* FakeGetFont(FPDF_SYSFONTINFO* pThis, const char* face) { // Any non-null return will do. return pThis; } unsigned long FakeGetFontData(FPDF_SYSFONTINFO* pThis, void* hFont, unsigned int table, unsigned char* buffer, unsigned long buf_size) { return 0; } unsigned long FakeGetFaceName(FPDF_SYSFONTINFO* pThis, void* hFont, char* buffer, unsigned long buf_size) { return 0; } int FakeGetFontCharset(FPDF_SYSFONTINFO* pThis, void* hFont) { return 1; } void FakeDeleteFont(FPDF_SYSFONTINFO* pThis, void* hFont) {} } // extern "C" class FPDFUnavailableSysFontInfoEmbedderTest : public EmbedderTest { public: FPDFUnavailableSysFontInfoEmbedderTest() = default; ~FPDFUnavailableSysFontInfoEmbedderTest() override = default; void SetUp() override { EmbedderTest::SetUp(); font_info_.version = 1; font_info_.Release = FakeRelease; font_info_.EnumFonts = FakeEnumFonts; font_info_.MapFont = FakeMapFont; font_info_.GetFont = FakeGetFont; font_info_.GetFontData = FakeGetFontData; font_info_.GetFaceName = FakeGetFaceName; font_info_.GetFontCharset = FakeGetFontCharset; font_info_.DeleteFont = FakeDeleteFont; FPDF_SetSystemFontInfo(&font_info_); } FPDF_SYSFONTINFO font_info_; }; class FPDFSysFontInfoEmbedderTest : public EmbedderTest { public: FPDFSysFontInfoEmbedderTest() = default; ~FPDFSysFontInfoEmbedderTest() override = default; void SetUp() override { EmbedderTest::SetUp(); font_info_ = FPDF_GetDefaultSystemFontInfo(); ASSERT_TRUE(font_info_); FPDF_SetSystemFontInfo(font_info_); } void TearDown() override { EmbedderTest::TearDown(); FPDF_FreeDefaultSystemFontInfo(font_info_); } FPDF_SYSFONTINFO* font_info_; }; } // namespace TEST_F(FPDFUnavailableSysFontInfoEmbedderTest, Bug_972518) { ASSERT_TRUE(OpenDocument("bug_972518.pdf")); ASSERT_EQ(1, FPDF_GetPageCount(document())); FPDF_PAGE page = LoadPage(0); ASSERT_TRUE(page); UnloadPage(page); } TEST_F(FPDFSysFontInfoEmbedderTest, DefaultSystemFontInfo) { ASSERT_TRUE(OpenDocument("hello_world.pdf")); ASSERT_EQ(1, FPDF_GetPageCount(document())); FPDF_PAGE page = LoadPage(0); ASSERT_TRUE(page); { // Not checking the rendering because it will depend on the fonts installed. ScopedFPDFBitmap bitmap = RenderPage(page); ASSERT_EQ(200, FPDFBitmap_GetWidth(bitmap.get())); ASSERT_EQ(200, FPDFBitmap_GetHeight(bitmap.get())); } UnloadPage(page); } TEST_F(FPDFSysFontInfoEmbedderTest, DefaultTTFMap) { static const int kAllowedCharsets[] = { FXFONT_ANSI_CHARSET, FXFONT_DEFAULT_CHARSET, FXFONT_SYMBOL_CHARSET, FXFONT_SHIFTJIS_CHARSET, FXFONT_HANGEUL_CHARSET, FXFONT_GB2312_CHARSET, FXFONT_CHINESEBIG5_CHARSET, FXFONT_ARABIC_CHARSET, FXFONT_CYRILLIC_CHARSET, FXFONT_EASTERNEUROPEAN_CHARSET, }; std::set seen_charsets; const FPDF_CharsetFontMap* cfmap = FPDF_GetDefaultTTFMap(); ASSERT_TRUE(cfmap); // Stop at either end mark. while (cfmap->charset != -1 && cfmap->fontname) { // Only returns values described as legitimate in public header. EXPECT_TRUE(pdfium::ContainsValue(kAllowedCharsets, cfmap->charset)) << " for " << cfmap->charset; // Duplicates are not allowed. EXPECT_TRUE(seen_charsets.insert(cfmap->charset).second) << " for " << cfmap->charset; ++cfmap; } // Confirm end marks only occur as a pair. EXPECT_EQ(cfmap->charset, -1); EXPECT_EQ(cfmap->fontname, nullptr); }