1 // Copyright 2019 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "public/fpdf_sysfontinfo.h"
6
7 #include "testing/embedder_test.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/base/stl_util.h"
10
11 namespace {
12
13 extern "C" {
14
FakeRelease(FPDF_SYSFONTINFO * pThis)15 void FakeRelease(FPDF_SYSFONTINFO* pThis) {}
FakeEnumFonts(FPDF_SYSFONTINFO * pThis,void * pMapper)16 void FakeEnumFonts(FPDF_SYSFONTINFO* pThis, void* pMapper) {}
17
FakeMapFont(FPDF_SYSFONTINFO * pThis,int weight,FPDF_BOOL bItalic,int charset,int pitch_family,const char * face,FPDF_BOOL * bExact)18 void* FakeMapFont(FPDF_SYSFONTINFO* pThis,
19 int weight,
20 FPDF_BOOL bItalic,
21 int charset,
22 int pitch_family,
23 const char* face,
24 FPDF_BOOL* bExact) {
25 // Any non-null return will do.
26 return pThis;
27 }
28
FakeGetFont(FPDF_SYSFONTINFO * pThis,const char * face)29 void* FakeGetFont(FPDF_SYSFONTINFO* pThis, const char* face) {
30 // Any non-null return will do.
31 return pThis;
32 }
33
FakeGetFontData(FPDF_SYSFONTINFO * pThis,void * hFont,unsigned int table,unsigned char * buffer,unsigned long buf_size)34 unsigned long FakeGetFontData(FPDF_SYSFONTINFO* pThis,
35 void* hFont,
36 unsigned int table,
37 unsigned char* buffer,
38 unsigned long buf_size) {
39 return 0;
40 }
41
FakeGetFaceName(FPDF_SYSFONTINFO * pThis,void * hFont,char * buffer,unsigned long buf_size)42 unsigned long FakeGetFaceName(FPDF_SYSFONTINFO* pThis,
43 void* hFont,
44 char* buffer,
45 unsigned long buf_size) {
46 return 0;
47 }
48
FakeGetFontCharset(FPDF_SYSFONTINFO * pThis,void * hFont)49 int FakeGetFontCharset(FPDF_SYSFONTINFO* pThis, void* hFont) {
50 return 1;
51 }
52
FakeDeleteFont(FPDF_SYSFONTINFO * pThis,void * hFont)53 void FakeDeleteFont(FPDF_SYSFONTINFO* pThis, void* hFont) {}
54
55 } // extern "C"
56
57 class FPDFUnavailableSysFontInfoEmbedderTest : public EmbedderTest {
58 public:
59 FPDFUnavailableSysFontInfoEmbedderTest() = default;
60 ~FPDFUnavailableSysFontInfoEmbedderTest() override = default;
61
SetUp()62 void SetUp() override {
63 EmbedderTest::SetUp();
64 font_info_.version = 1;
65 font_info_.Release = FakeRelease;
66 font_info_.EnumFonts = FakeEnumFonts;
67 font_info_.MapFont = FakeMapFont;
68 font_info_.GetFont = FakeGetFont;
69 font_info_.GetFontData = FakeGetFontData;
70 font_info_.GetFaceName = FakeGetFaceName;
71 font_info_.GetFontCharset = FakeGetFontCharset;
72 font_info_.DeleteFont = FakeDeleteFont;
73 FPDF_SetSystemFontInfo(&font_info_);
74 }
75
76 FPDF_SYSFONTINFO font_info_;
77 };
78
79 class FPDFSysFontInfoEmbedderTest : public EmbedderTest {
80 public:
81 FPDFSysFontInfoEmbedderTest() = default;
82 ~FPDFSysFontInfoEmbedderTest() override = default;
83
SetUp()84 void SetUp() override {
85 EmbedderTest::SetUp();
86 font_info_ = FPDF_GetDefaultSystemFontInfo();
87 ASSERT_TRUE(font_info_);
88 FPDF_SetSystemFontInfo(font_info_);
89 }
90
TearDown()91 void TearDown() override {
92 EmbedderTest::TearDown();
93 FPDF_FreeDefaultSystemFontInfo(font_info_);
94 }
95
96 FPDF_SYSFONTINFO* font_info_;
97 };
98
99 } // namespace
100
TEST_F(FPDFUnavailableSysFontInfoEmbedderTest,Bug_972518)101 TEST_F(FPDFUnavailableSysFontInfoEmbedderTest, Bug_972518) {
102 ASSERT_TRUE(OpenDocument("bug_972518.pdf"));
103 ASSERT_EQ(1, FPDF_GetPageCount(document()));
104
105 FPDF_PAGE page = LoadPage(0);
106 ASSERT_TRUE(page);
107 UnloadPage(page);
108 }
109
TEST_F(FPDFSysFontInfoEmbedderTest,DefaultSystemFontInfo)110 TEST_F(FPDFSysFontInfoEmbedderTest, DefaultSystemFontInfo) {
111 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
112 ASSERT_EQ(1, FPDF_GetPageCount(document()));
113
114 FPDF_PAGE page = LoadPage(0);
115 ASSERT_TRUE(page);
116
117 {
118 // Not checking the rendering because it will depend on the fonts installed.
119 ScopedFPDFBitmap bitmap = RenderPage(page);
120 ASSERT_EQ(200, FPDFBitmap_GetWidth(bitmap.get()));
121 ASSERT_EQ(200, FPDFBitmap_GetHeight(bitmap.get()));
122 }
123
124 UnloadPage(page);
125 }
126
TEST_F(FPDFSysFontInfoEmbedderTest,DefaultTTFMap)127 TEST_F(FPDFSysFontInfoEmbedderTest, DefaultTTFMap) {
128 static const int kAllowedCharsets[] = {
129 FXFONT_ANSI_CHARSET, FXFONT_DEFAULT_CHARSET,
130 FXFONT_SYMBOL_CHARSET, FXFONT_SHIFTJIS_CHARSET,
131 FXFONT_HANGEUL_CHARSET, FXFONT_GB2312_CHARSET,
132 FXFONT_CHINESEBIG5_CHARSET, FXFONT_ARABIC_CHARSET,
133 FXFONT_CYRILLIC_CHARSET, FXFONT_EASTERNEUROPEAN_CHARSET,
134 };
135 std::set<int> seen_charsets;
136
137 const FPDF_CharsetFontMap* cfmap = FPDF_GetDefaultTTFMap();
138 ASSERT_TRUE(cfmap);
139
140 // Stop at either end mark.
141 while (cfmap->charset != -1 && cfmap->fontname) {
142 // Only returns values described as legitimate in public header.
143 EXPECT_TRUE(pdfium::ContainsValue(kAllowedCharsets, cfmap->charset))
144 << " for " << cfmap->charset;
145
146 // Duplicates are not allowed.
147 EXPECT_TRUE(seen_charsets.insert(cfmap->charset).second)
148 << " for " << cfmap->charset;
149 ++cfmap;
150 }
151
152 // Confirm end marks only occur as a pair.
153 EXPECT_EQ(cfmap->charset, -1);
154 EXPECT_EQ(cfmap->fontname, nullptr);
155 }
156