| // 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<int> 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); | |
| } |