Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: content/common/font_warmup_win_unittest.cc

Issue 1327673002: Added GDI font emulation support for Flash. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@warmup_direct_write
Patch Set: Implemented review changes. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium 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 "content/common/font_warmup_win.h"
6
7 #include <vector>
8
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/sys_byteorder.h"
13 #include "base/win/windows_version.h"
14 #include "skia/ext/refptr.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/skia/include/core/SkString.h"
17 #include "third_party/skia/include/core/SkTypeface.h"
18 #include "third_party/skia/include/ports/SkFontMgr.h"
19
20 namespace content {
21
22 namespace {
23
24 class TestSkTypeface : public SkTypeface {
25 public:
26 TestSkTypeface(const SkFontStyle& style,
27 const char* familyName,
28 SkFontTableTag tag,
29 const char* data,
30 size_t dataLength)
31 : SkTypeface(style, 0),
32 familyName_(familyName),
33 tag_(tag),
34 data_(data, data + dataLength) {}
35
36 protected:
37 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override {
38 ADD_FAILURE();
39 return nullptr;
40 }
41 void onFilterRec(SkScalerContextRec*) const override { ADD_FAILURE(); }
42 SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
43 PerGlyphInfo,
44 const uint32_t* glyphIDs,
45 uint32_t glyphIDsCount) const override {
46 ADD_FAILURE();
47 return nullptr;
48 }
49
50 SkStreamAsset* onOpenStream(int* ttcIndex) const override {
51 ADD_FAILURE();
52 return nullptr;
53 }
54
55 SkFontData* onCreateFontData() const override {
56 ADD_FAILURE();
57 return nullptr;
58 }
59
60 void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const override {
61 ADD_FAILURE();
62 }
63
64 int onCharsToGlyphs(const void* chars,
65 Encoding,
66 uint16_t glyphs[],
67 int glyphCount) const override {
68 ADD_FAILURE();
69 return 0;
70 }
71
72 int onCountGlyphs() const override {
73 ADD_FAILURE();
74 return 0;
75 }
76
77 int onGetUPEM() const override {
78 ADD_FAILURE();
79 return 0;
80 }
81 bool onGetKerningPairAdjustments(const uint16_t glyphs[],
82 int count,
83 int32_t adjustments[]) const override {
84 ADD_FAILURE();
85 return false;
86 }
87
88 void onGetFamilyName(SkString* familyName) const override {
89 *familyName = familyName_;
90 }
91
92 LocalizedStrings* onCreateFamilyNameIterator() const override {
93 ADD_FAILURE();
94 return nullptr;
95 }
96
97 int onGetTableTags(SkFontTableTag tags[]) const override {
98 ADD_FAILURE();
99 return 0;
100 }
101
102 size_t onGetTableData(SkFontTableTag tag,
103 size_t offset,
104 size_t length,
105 void* data) const override {
106 size_t retsize = 0;
107 if (tag == tag_) {
108 retsize = length > data_.size() ? data_.size() : length;
109 if (data)
110 memcpy(data, &data_[0], retsize);
111 }
112 return retsize;
113 }
114
115 bool onComputeBounds(SkRect*) const override {
116 ADD_FAILURE();
117 return false;
118 }
119
120 private:
121 SkString familyName_;
122 SkFontTableTag tag_;
123 std::vector<char> data_;
124 };
125
126 const char* kTestFontFamily = "GDITest";
127 const wchar_t* kTestFontFamilyW = L"GDITest";
128 const SkFontTableTag kTestFontTableTag = 0x11223344;
129 const char* kTestFontData = "GDITestGDITest";
130 const wchar_t* kTestFontFamilyInvalid = L"InvalidFont";
131
132 class TestSkFontMgr : public SkFontMgr {
133 public:
134 TestSkFontMgr() { content::SetPreSandboxWarmupFontMgr(this); }
135 ~TestSkFontMgr() { content::SetPreSandboxWarmupFontMgr(nullptr); }
136
137 protected:
138 // Implement the virtual methods
139 int onCountFamilies() const override { return 1; }
140
141 void onGetFamilyName(int index, SkString* familyName) const override {
142 if (index == 0)
143 *familyName = kTestFontFamily;
144 }
145
146 SkFontStyleSet* onCreateStyleSet(int index) const override {
147 ADD_FAILURE();
148 return nullptr;
149 }
150
151 /** May return nullptr if the name is not found. */
nasko 2015/09/21 15:58:20 Use // for comments.
forshaw 2015/09/21 22:06:20 Acknowledged.
152 SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
153 ADD_FAILURE();
154 return nullptr;
155 }
156
157 SkTypeface* onMatchFamilyStyle(const char familyName[],
158 const SkFontStyle&) const override {
159 if (strcmp(familyName, kTestFontFamily) == 0) {
nasko 2015/09/21 15:58:20 nit: no need for {} in one line if statements.
forshaw 2015/09/21 22:06:20 Acknowledged.
160 return createTypeface();
161 }
162 return nullptr;
163 }
164
165 SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
166 const SkFontStyle&,
167 const char* bcp47[],
168 int bcp47Count,
169 SkUnichar character) const override {
170 ADD_FAILURE();
171 return nullptr;
172 }
173
174 SkTypeface* onMatchFaceStyle(const SkTypeface*,
175 const SkFontStyle&) const override {
176 ADD_FAILURE();
177 return nullptr;
178 }
179
180 SkTypeface* onCreateFromData(SkData*, int ttcIndex) const override {
181 ADD_FAILURE();
182 return nullptr;
183 }
184
185 SkTypeface* onCreateFromStream(SkStreamAsset*, int ttcIndex) const override {
186 ADD_FAILURE();
187 return nullptr;
188 }
189
190 SkTypeface* onCreateFromFontData(SkFontData*) const override {
191 ADD_FAILURE();
192 return nullptr;
193 }
194
195 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
196 ADD_FAILURE();
197 return nullptr;
198 }
199
200 SkTypeface* onLegacyCreateTypeface(const char familyName[],
201 unsigned styleBits) const override {
202 ADD_FAILURE();
203 return nullptr;
204 }
205
206 private:
207 SkTypeface* createTypeface() const {
208 SkFontStyle style(400, 100, SkFontStyle::kUpright_Slant);
209
210 return new TestSkTypeface(style, kTestFontFamily,
211 base::ByteSwap(kTestFontTableTag), kTestFontData,
212 strlen(kTestFontData));
213 }
214 };
215
216 void InitLogFont(LOGFONTW* logfont, const wchar_t* fontname) {
217 size_t length = std::min(sizeof(logfont->lfFaceName),
218 (wcslen(fontname) + 1) * sizeof(wchar_t));
219 memcpy(logfont->lfFaceName, fontname, length);
220 }
221
222 content::GdiFontPatchData* SetupTest() {
223 HMODULE module_handle;
224 if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
225 reinterpret_cast<LPCWSTR>(SetupTest),
226 &module_handle)) {
227 WCHAR module_path[MAX_PATH];
228
229 if (GetModuleFileNameW(module_handle, module_path, MAX_PATH) > 0) {
230 base::FilePath path(module_path);
231 content::ResetEmulatedGdiHandles();
232 return content::PatchGdiFontEnumeration(path);
233 }
234 }
235 return nullptr;
236 }
237
238 int CALLBACK EnumFontCallbackTest(const LOGFONT* log_font,
239 const TEXTMETRIC* text_metric,
240 DWORD font_type,
241 LPARAM param) {
242 const NEWTEXTMETRICEX* new_text_metric =
243 reinterpret_cast<const NEWTEXTMETRICEX*>(text_metric);
244
245 return !(font_type & TRUETYPE_FONTTYPE) &&
246 !(new_text_metric->ntmTm.ntmFlags & NTM_PS_OPENTYPE);
247 }
248
249 } // namespace
250
251 TEST(GDIFontEmulationTest, CreateDeleteDCSuccess) {
252 if (base::win::GetVersion() < base::win::VERSION_WIN8)
253 return;
254 TestSkFontMgr fontmgr;
255 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
256 EXPECT_FALSE(!patch_data);
257
258 HDC hdc = CreateCompatibleDC(0);
259 EXPECT_NE(hdc, nullptr);
260 EXPECT_EQ(GetEmulatedGdiHandleCount(), 1);
261 EXPECT_TRUE(DeleteDC(hdc));
262 EXPECT_EQ(GetEmulatedGdiHandleCount(), 0);
263 }
264
265 TEST(GDIFontEmulationTest, CreateUniqueDCSuccess) {
266 if (base::win::GetVersion() < base::win::VERSION_WIN8)
267 return;
268 TestSkFontMgr fontmgr;
269 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
270 EXPECT_NE(patch_data, nullptr);
271
272 HDC hdc1 = CreateCompatibleDC(0);
273 EXPECT_NE(hdc1, nullptr);
274 HDC hdc2 = CreateCompatibleDC(0);
275 EXPECT_NE(hdc2, nullptr);
276 EXPECT_NE(hdc1, hdc2);
277 EXPECT_TRUE(DeleteDC(hdc2));
278 EXPECT_EQ(GetEmulatedGdiHandleCount(), 1);
279 EXPECT_TRUE(DeleteDC(hdc1));
280 EXPECT_EQ(GetEmulatedGdiHandleCount(), 0);
281 }
282
283 TEST(GDIFontEmulationTest, CreateFontSuccess) {
284 if (base::win::GetVersion() < base::win::VERSION_WIN8)
285 return;
286 TestSkFontMgr fontmgr;
287 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
288 EXPECT_NE(patch_data, nullptr);
289 LOGFONTW logfont = {0};
290 InitLogFont(&logfont, kTestFontFamilyW);
291 HFONT font = CreateFontIndirectW(&logfont);
292 EXPECT_NE(font, nullptr);
293 EXPECT_TRUE(DeleteObject(font));
294 EXPECT_EQ(GetEmulatedGdiHandleCount(), 0);
295 }
296
297 TEST(GDIFontEmulationTest, CreateFontFailure) {
298 if (base::win::GetVersion() < base::win::VERSION_WIN8)
299 return;
300 TestSkFontMgr fontmgr;
301 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
302 EXPECT_NE(patch_data, nullptr);
303 LOGFONTW logfont = {0};
304 InitLogFont(&logfont, kTestFontFamilyInvalid);
305 HFONT font = CreateFontIndirectW(&logfont);
306 EXPECT_EQ(font, nullptr);
307 }
308
309 TEST(GDIFontEmulationTest, EnumFontFamilySuccess) {
310 if (base::win::GetVersion() < base::win::VERSION_WIN8)
311 return;
312 TestSkFontMgr fontmgr;
313 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
314 EXPECT_NE(patch_data, nullptr);
315 HDC hdc = CreateCompatibleDC(0);
316 EXPECT_NE(hdc, nullptr);
317 LOGFONTW logfont = {0};
318 InitLogFont(&logfont, kTestFontFamilyW);
319 int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
320 EXPECT_FALSE(res);
321 EXPECT_TRUE(DeleteDC(hdc));
322 }
323
324 TEST(GDIFontEmulationTest, EnumFontFamilyFailure) {
325 if (base::win::GetVersion() < base::win::VERSION_WIN8)
326 return;
327 TestSkFontMgr fontmgr;
328 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
329 EXPECT_NE(patch_data, nullptr);
330 HDC hdc = CreateCompatibleDC(0);
331 EXPECT_NE(hdc, nullptr);
332 LOGFONTW logfont = {0};
333 InitLogFont(&logfont, kTestFontFamilyInvalid);
334 int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
335 EXPECT_TRUE(res);
336 EXPECT_TRUE(DeleteDC(hdc));
337 }
338
339 TEST(GDIFontEmulationTest, DeleteDCFailure) {
340 if (base::win::GetVersion() < base::win::VERSION_WIN8)
341 return;
342 TestSkFontMgr fontmgr;
343 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
344 EXPECT_NE(patch_data, nullptr);
345 HDC hdc = reinterpret_cast<HDC>(0x55667788);
346 EXPECT_FALSE(DeleteDC(hdc));
347 }
348
349 TEST(GDIFontEmulationTest, DeleteObjectFailure) {
350 if (base::win::GetVersion() < base::win::VERSION_WIN8)
351 return;
352 TestSkFontMgr fontmgr;
353 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
354 EXPECT_NE(patch_data, nullptr);
355 HFONT font = reinterpret_cast<HFONT>(0x88aabbcc);
356 EXPECT_FALSE(DeleteObject(font));
357 }
358
359 TEST(GDIFontEmulationTest, GetFontDataSizeSuccess) {
360 if (base::win::GetVersion() < base::win::VERSION_WIN8)
361 return;
362 TestSkFontMgr fontmgr;
363 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
364 EXPECT_NE(patch_data, nullptr);
365 HDC hdc = CreateCompatibleDC(0);
366 EXPECT_NE(hdc, nullptr);
367 LOGFONTW logfont = {0};
368 InitLogFont(&logfont, kTestFontFamilyW);
369 HFONT font = CreateFontIndirectW(&logfont);
370 EXPECT_NE(font, nullptr);
371 EXPECT_EQ(SelectObject(hdc, font), nullptr);
372 DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
373 DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
374 EXPECT_EQ(size, data_size);
375 EXPECT_TRUE(DeleteObject(font));
376 EXPECT_TRUE(DeleteDC(hdc));
377 }
378
379 TEST(GDIFontEmulationTest, GetFontDataInvalidTagSuccess) {
380 if (base::win::GetVersion() < base::win::VERSION_WIN8)
381 return;
382 TestSkFontMgr fontmgr;
383 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
384 EXPECT_NE(patch_data, nullptr);
385 HDC hdc = CreateCompatibleDC(0);
386 EXPECT_NE(hdc, nullptr);
387 LOGFONTW logfont = {0};
388 InitLogFont(&logfont, kTestFontFamilyW);
389 HFONT font = CreateFontIndirectW(&logfont);
390 EXPECT_NE(font, nullptr);
391 EXPECT_EQ(SelectObject(hdc, font), nullptr);
392 DWORD size = GetFontData(hdc, kTestFontTableTag + 1, 0, nullptr, 0);
393 EXPECT_EQ(size, GDI_ERROR);
394 EXPECT_TRUE(DeleteObject(font));
395 EXPECT_TRUE(DeleteDC(hdc));
396 }
397
398 TEST(GDIFontEmulationTest, GetFontDataInvalidFontSuccess) {
399 if (base::win::GetVersion() < base::win::VERSION_WIN8)
400 return;
401 TestSkFontMgr fontmgr;
402 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
403 EXPECT_NE(patch_data, nullptr);
404 HDC hdc = CreateCompatibleDC(0);
405 EXPECT_NE(hdc, nullptr);
406 DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
407 EXPECT_EQ(size, GDI_ERROR);
408 EXPECT_TRUE(DeleteDC(hdc));
409 }
410
411 TEST(GDIFontEmulationTest, GetFontDataDataSuccess) {
412 if (base::win::GetVersion() < base::win::VERSION_WIN8)
413 return;
414 TestSkFontMgr fontmgr;
415 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
416 EXPECT_NE(patch_data, nullptr);
417 HDC hdc = CreateCompatibleDC(0);
418 EXPECT_NE(hdc, nullptr);
419 LOGFONTW logfont = {0};
420 InitLogFont(&logfont, kTestFontFamilyW);
421 HFONT font = CreateFontIndirectW(&logfont);
422 EXPECT_NE(font, nullptr);
423 EXPECT_EQ(SelectObject(hdc, font), nullptr);
424 DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
425 std::vector<char> data(data_size);
426 DWORD size = GetFontData(hdc, kTestFontTableTag, 0, &data[0], data.size());
427 EXPECT_EQ(size, data_size);
428 EXPECT_EQ(memcmp(&data[0], kTestFontData, data.size()), 0);
429 EXPECT_TRUE(DeleteObject(font));
430 EXPECT_TRUE(DeleteDC(hdc));
431 }
432
433 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698