Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfx_fontmapper_unittest.cpp
Go to the documentation of this file.
1// Copyright 2019 The PDFium Authors
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 "core/fxge/cfx_fontmapper.h"
6
7#include <memory>
8#include <numeric>
9#include <utility>
10
11#include "core/fxcrt/fx_codepage.h"
12#include "core/fxge/cfx_gemodule.h"
13#include "core/fxge/systemfontinfo_iface.h"
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17using testing::_;
18using testing::DoAll;
19using testing::ElementsAre;
20using testing::InSequence;
21using testing::Invoke;
22using testing::Return;
23using testing::WithArg;
24
26 public:
27 MockSystemFontInfo() = default;
28 ~MockSystemFontInfo() override = default;
29
30 // SystemFontInfoIface:
31 MOCK_METHOD(bool, EnumFontList, (CFX_FontMapper*), (override));
33 MapFont,
34 (int, bool, FX_Charset, int, const ByteString&),
35 (override));
36 MOCK_METHOD(void*, GetFont, (const ByteString&), (override));
39 (void*, uint32_t, pdfium::span<uint8_t>),
40 (override));
41 MOCK_METHOD(bool, GetFaceName, (void*, ByteString*), (override));
42 MOCK_METHOD(bool, GetFontCharset, (void*, FX_Charset*), (override));
43 MOCK_METHOD(void, DeleteFont, (void*), (override));
44};
45
46// Class that exposes private CFX_FontMapper methods.
48 public:
50
51 RetainPtr<CFX_Face> GetCachedTTCFace(void* font_handle,
52 size_t ttc_size,
53 size_t data_size) {
54 return CFX_FontMapper::GetCachedTTCFace(font_handle, ttc_size, data_size);
55 }
56
57 RetainPtr<CFX_Face> GetCachedFace(void* font_handle,
58 ByteString subst_name,
59 int weight,
60 bool is_italic,
61 size_t data_size) {
62 return CFX_FontMapper::GetCachedFace(font_handle, subst_name, weight,
63 is_italic, data_size);
64 }
65};
66
68 protected:
71
72 void SetUp() override {
73 font_mapper_ = std::make_unique<TestFontMapper>();
74 auto system_font_info = std::make_unique<MockSystemFontInfo>();
75 system_font_info_ = system_font_info.get();
76 font_mapper_->SetSystemFontInfo(std::move(system_font_info));
77 font_mapper_->AddInstalledFont("dummy", FX_Charset::kANSI);
78 }
79
80 TestFontMapper& font_mapper() { return *font_mapper_; }
81 MockSystemFontInfo& system_font_info() { return *system_font_info_; }
82
83 private:
84 // Must outlive `system_font_info_`.
85 std::unique_ptr<TestFontMapper> font_mapper_;
86 UnownedPtr<MockSystemFontInfo> system_font_info_;
87};
88
89// Deliberately give this global variable external linkage.
90char g_maybe_changes = '\xff';
91
93 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Courier"));
94 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Courier-Bold"));
95 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Courier-BoldOblique"));
96 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Courier-Oblique"));
97 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Helvetica"));
98 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Helvetica-Bold"));
99 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Helvetica-BoldOblique"));
100 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Helvetica-Oblique"));
101 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Times-Roman"));
102 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Times-Bold"));
103 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Times-BoldItalic"));
104 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Times-Italic"));
105 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("Symbol"));
106 EXPECT_TRUE(CFX_FontMapper::IsStandardFontName("ZapfDingbats"));
107
108 EXPECT_FALSE(CFX_FontMapper::IsStandardFontName("Courie"));
109 EXPECT_FALSE(CFX_FontMapper::IsStandardFontName("Courier-"));
110 EXPECT_FALSE(CFX_FontMapper::IsStandardFontName("Helvetica+Bold"));
111 EXPECT_FALSE(CFX_FontMapper::IsStandardFontName("YapfDingbats"));
112}
113
115 EXPECT_EQ(0x61626364u, CFX_FontMapper::MakeTag('a', 'b', 'c', 'd'));
116 EXPECT_EQ(0x00000000u, CFX_FontMapper::MakeTag('\0', '\0', '\0', '\0'));
117 EXPECT_EQ(0xfffe0a08u, CFX_FontMapper::MakeTag('\xff', '\xfe', '\n', '\b'));
118 EXPECT_EQ(0xffffffffu,
119 CFX_FontMapper::MakeTag('\xff', '\xff', '\xff', '\xff'));
120 EXPECT_EQ(0xffffffffu,
122 EXPECT_EQ(0x6e616d65u, CFX_FontMapper::MakeTag('n', 'a', 'm', 'e'));
123 EXPECT_EQ(0x4f532f32u, CFX_FontMapper::MakeTag('O', 'S', '/', '2'));
124 EXPECT_EQ(FT_MAKE_TAG('G', 'S', 'U', 'B'),
125 CFX_FontMapper::MakeTag('G', 'S', 'U', 'B'));
126}
127
129 const char kFontName[] = "dummy";
130 CFX_FontMapper font_mapper(nullptr);
131 font_mapper.SetSystemFontInfo(std::make_unique<MockSystemFontInfo>());
132
133 font_mapper.AddInstalledFont(kFontName, FX_Charset::kANSI);
134 EXPECT_EQ(1u, font_mapper.GetFaceSize());
135 EXPECT_EQ(kFontName, font_mapper.GetFaceName(0));
136}
137
138#ifdef PDF_ENABLE_XFA
139TEST_F(CFXFontMapperSystemFontInfoTest, RawBytesForIndex) {
140 {
141 void* const kFontHandle = reinterpret_cast<void*>(12345);
142
143 InSequence s;
144 EXPECT_CALL(system_font_info(), MapFont).WillOnce(Return(kFontHandle));
145 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, 0, _))
146 .WillOnce(Return(2));
147 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, 0, _))
148 .WillOnce(DoAll(WithArg<2>(Invoke([](pdfium::span<uint8_t> buffer) {
149 buffer[0] = '0';
150 buffer[1] = '1';
151 })),
152 Return(2)));
153 EXPECT_CALL(system_font_info(), DeleteFont(kFontHandle));
154 }
155
156 FixedSizeDataVector<uint8_t> data = font_mapper().RawBytesForIndex(0);
157 EXPECT_THAT(data.span(), ElementsAre('0', '1'));
158}
159
160TEST_F(CFXFontMapperSystemFontInfoTest, RawBytesForIndexFailToMap) {
161 EXPECT_CALL(system_font_info(), MapFont).WillOnce(Return(nullptr));
162
163 FixedSizeDataVector<uint8_t> data = font_mapper().RawBytesForIndex(0);
164 EXPECT_TRUE(data.empty());
165}
166
167TEST_F(CFXFontMapperSystemFontInfoTest, RawBytesForIndexFailToGetDataSize) {
168 {
169 void* const kFontHandle = reinterpret_cast<void*>(12345);
170
171 InSequence s;
172 EXPECT_CALL(system_font_info(), MapFont).WillOnce(Return(kFontHandle));
173 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, 0, _))
174 .WillOnce(Return(0));
175 EXPECT_CALL(system_font_info(), DeleteFont(kFontHandle));
176 }
177
178 FixedSizeDataVector<uint8_t> data = font_mapper().RawBytesForIndex(0);
179 EXPECT_TRUE(data.empty());
180}
181
182TEST_F(CFXFontMapperSystemFontInfoTest, RawBytesForIndexFailToGetData) {
183 {
184 void* const kFontHandle = reinterpret_cast<void*>(12345);
185
186 InSequence s;
187 EXPECT_CALL(system_font_info(), MapFont).WillOnce(Return(kFontHandle));
188 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, 0, _))
189 .WillOnce(Return(2));
190 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, 0, _))
191 .WillOnce(Return(0));
192 EXPECT_CALL(system_font_info(), DeleteFont(kFontHandle));
193 }
194
195 FixedSizeDataVector<uint8_t> data = font_mapper().RawBytesForIndex(0);
196 EXPECT_TRUE(data.empty());
197}
198#endif // PDF_ENABLE_XFA
199
200// Regression test for crbug.com/1372234 - should not crash.
202 void* const kFontHandle = reinterpret_cast<void*>(12345);
203 constexpr size_t kTtcSize = 1024;
204 constexpr size_t kDataSize = 2;
205
206 {
207 InSequence s;
208 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, kTableTTCF, _))
209 .WillOnce(DoAll(WithArg<2>(Invoke([&](pdfium::span<uint8_t> buffer) {
210 EXPECT_EQ(kTtcSize, buffer.size());
211 std::iota(buffer.begin(), buffer.end(), 0);
212 })),
213 Return(kTtcSize)));
214 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, kTableTTCF, _))
215 .WillOnce(Return(0));
216 }
217
218 EXPECT_FALSE(
219 font_mapper().GetCachedTTCFace(kFontHandle, kTtcSize, kDataSize));
220}
221
222// Regression test for crbug.com/1372234 - should not crash.
224 void* const kFontHandle = reinterpret_cast<void*>(12345);
225 constexpr char kSubstName[] = "dummy_font";
226 constexpr int kWeight = 400;
227 constexpr bool kItalic = false;
228 constexpr size_t kDataSize = 2;
229
230 EXPECT_CALL(system_font_info(), GetFontData(kFontHandle, 0, _))
231 .WillOnce(Return(0));
232
233 EXPECT_FALSE(font_mapper().GetCachedFace(kFontHandle, kSubstName, kWeight,
234 kItalic, kDataSize));
235}
char g_maybe_changes
TEST(CFX_FontMapper, IsStandardFontName)
TEST_F(CFXFontMapperSystemFontInfoTest, GetCachedTTCFaceFailToGetData)
~CFXFontMapperSystemFontInfoTest() override=default
void AddInstalledFont(const ByteString &name, FX_Charset charset)
static constexpr uint32_t MakeTag(char c1, char c2, char c3, char c4)
CFX_FontMapper(CFX_FontMgr *mgr)
static bool IsStandardFontName(const ByteString &name)
static CFX_GEModule * Get()
CFX_FontMgr * GetFontMgr() const
MOCK_METHOD(void *, GetFont,(const ByteString &),(override))
~MockSystemFontInfo() override=default
MOCK_METHOD(bool, GetFaceName,(void *, ByteString *),(override))
MOCK_METHOD(size_t, GetFontData,(void *, uint32_t, pdfium::span< uint8_t >),(override))
MOCK_METHOD(bool, EnumFontList,(CFX_FontMapper *),(override))
MOCK_METHOD(void, DeleteFont,(void *),(override))
MOCK_METHOD(bool, GetFontCharset,(void *, FX_Charset *),(override))
MOCK_METHOD(void *, MapFont,(int, bool, FX_Charset, int, const ByteString &),(override))
MockSystemFontInfo()=default
RetainPtr< CFX_Face > GetCachedFace(void *font_handle, ByteString subst_name, int weight, bool is_italic, size_t data_size)
RetainPtr< CFX_Face > GetCachedTTCFace(void *font_handle, size_t ttc_size, size_t data_size)
FX_Charset
Definition fx_codepage.h:70