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

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: Fixed from review. 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::SetPreSandboxWarmupFontMgrForTesting(this); }
135 ~TestSkFontMgr() { content::SetPreSandboxWarmupFontMgrForTesting(nullptr); }
136
137 protected:
138 int onCountFamilies() const override { return 1; }
139
140 void onGetFamilyName(int index, SkString* familyName) const override {
141 if (index == 0)
142 *familyName = kTestFontFamily;
143 }
144
145 SkFontStyleSet* onCreateStyleSet(int index) const override {
146 ADD_FAILURE();
147 return nullptr;
148 }
149
150 SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
151 ADD_FAILURE();
152 return nullptr;
153 }
154
155 SkTypeface* onMatchFamilyStyle(const char familyName[],
156 const SkFontStyle&) const override {
157 if (strcmp(familyName, kTestFontFamily) == 0)
158 return createTypeface();
159 return nullptr;
160 }
161
162 SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
163 const SkFontStyle&,
164 const char* bcp47[],
165 int bcp47Count,
166 SkUnichar character) const override {
167 ADD_FAILURE();
168 return nullptr;
169 }
170
171 SkTypeface* onMatchFaceStyle(const SkTypeface*,
172 const SkFontStyle&) const override {
173 ADD_FAILURE();
174 return nullptr;
175 }
176
177 SkTypeface* onCreateFromData(SkData*, int ttcIndex) const override {
178 ADD_FAILURE();
179 return nullptr;
180 }
181
182 SkTypeface* onCreateFromStream(SkStreamAsset*, int ttcIndex) const override {
183 ADD_FAILURE();
184 return nullptr;
185 }
186
187 SkTypeface* onCreateFromFontData(SkFontData*) const override {
188 ADD_FAILURE();
189 return nullptr;
190 }
191
192 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
193 ADD_FAILURE();
194 return nullptr;
195 }
196
197 SkTypeface* onLegacyCreateTypeface(const char familyName[],
198 unsigned styleBits) const override {
199 ADD_FAILURE();
200 return nullptr;
201 }
202
203 private:
204 SkTypeface* createTypeface() const {
205 SkFontStyle style(400, 100, SkFontStyle::kUpright_Slant);
206
207 return new TestSkTypeface(style, kTestFontFamily,
208 base::ByteSwap(kTestFontTableTag), kTestFontData,
209 strlen(kTestFontData));
210 }
211 };
212
213 void InitLogFont(LOGFONTW* logfont, const wchar_t* fontname) {
214 size_t length = std::min(sizeof(logfont->lfFaceName),
215 (wcslen(fontname) + 1) * sizeof(wchar_t));
216 memcpy(logfont->lfFaceName, fontname, length);
217 }
218
219 content::GdiFontPatchData* SetupTest() {
220 HMODULE module_handle;
221 if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
222 reinterpret_cast<LPCWSTR>(SetupTest),
223 &module_handle)) {
224 WCHAR module_path[MAX_PATH];
225
226 if (GetModuleFileNameW(module_handle, module_path, MAX_PATH) > 0) {
227 base::FilePath path(module_path);
228 content::ResetEmulatedGdiHandlesForTesting();
229 return content::PatchGdiFontEnumeration(path);
230 }
231 }
232 return nullptr;
233 }
234
235 int CALLBACK EnumFontCallbackTest(const LOGFONT* log_font,
236 const TEXTMETRIC* text_metric,
237 DWORD font_type,
238 LPARAM param) {
239 const NEWTEXTMETRICEX* new_text_metric =
240 reinterpret_cast<const NEWTEXTMETRICEX*>(text_metric);
241
242 return !(font_type & TRUETYPE_FONTTYPE) &&
243 !(new_text_metric->ntmTm.ntmFlags & NTM_PS_OPENTYPE);
244 }
245
246 } // namespace
247
248 TEST(GDIFontEmulationTest, CreateDeleteDCSuccess) {
249 if (base::win::GetVersion() < base::win::VERSION_WIN8)
250 return;
251 TestSkFontMgr fontmgr;
252 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
253 EXPECT_FALSE(!patch_data);
254
255 HDC hdc = CreateCompatibleDC(0);
256 EXPECT_NE(hdc, nullptr);
257 EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 1);
258 EXPECT_TRUE(DeleteDC(hdc));
259 EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 0);
260 }
261
262 TEST(GDIFontEmulationTest, CreateUniqueDCSuccess) {
263 if (base::win::GetVersion() < base::win::VERSION_WIN8)
264 return;
265 TestSkFontMgr fontmgr;
266 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
267 EXPECT_NE(patch_data, nullptr);
268
269 HDC hdc1 = CreateCompatibleDC(0);
270 EXPECT_NE(hdc1, nullptr);
271 HDC hdc2 = CreateCompatibleDC(0);
272 EXPECT_NE(hdc2, nullptr);
273 EXPECT_NE(hdc1, hdc2);
274 EXPECT_TRUE(DeleteDC(hdc2));
275 EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 1);
276 EXPECT_TRUE(DeleteDC(hdc1));
277 EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 0);
278 }
279
280 TEST(GDIFontEmulationTest, CreateFontSuccess) {
281 if (base::win::GetVersion() < base::win::VERSION_WIN8)
282 return;
283 TestSkFontMgr fontmgr;
284 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
285 EXPECT_NE(patch_data, nullptr);
286 LOGFONTW logfont = {0};
287 InitLogFont(&logfont, kTestFontFamilyW);
288 HFONT font = CreateFontIndirectW(&logfont);
289 EXPECT_NE(font, nullptr);
290 EXPECT_TRUE(DeleteObject(font));
291 EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 0);
292 }
293
294 TEST(GDIFontEmulationTest, CreateFontFailure) {
295 if (base::win::GetVersion() < base::win::VERSION_WIN8)
296 return;
297 TestSkFontMgr fontmgr;
298 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
299 EXPECT_NE(patch_data, nullptr);
300 LOGFONTW logfont = {0};
301 InitLogFont(&logfont, kTestFontFamilyInvalid);
302 HFONT font = CreateFontIndirectW(&logfont);
303 EXPECT_EQ(font, nullptr);
304 }
305
306 TEST(GDIFontEmulationTest, EnumFontFamilySuccess) {
307 if (base::win::GetVersion() < base::win::VERSION_WIN8)
308 return;
309 TestSkFontMgr fontmgr;
310 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
311 EXPECT_NE(patch_data, nullptr);
312 HDC hdc = CreateCompatibleDC(0);
313 EXPECT_NE(hdc, nullptr);
314 LOGFONTW logfont = {0};
315 InitLogFont(&logfont, kTestFontFamilyW);
316 int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
317 EXPECT_FALSE(res);
318 EXPECT_TRUE(DeleteDC(hdc));
319 }
320
321 TEST(GDIFontEmulationTest, EnumFontFamilyFailure) {
322 if (base::win::GetVersion() < base::win::VERSION_WIN8)
323 return;
324 TestSkFontMgr fontmgr;
325 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
326 EXPECT_NE(patch_data, nullptr);
327 HDC hdc = CreateCompatibleDC(0);
328 EXPECT_NE(hdc, nullptr);
329 LOGFONTW logfont = {0};
330 InitLogFont(&logfont, kTestFontFamilyInvalid);
331 int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
332 EXPECT_TRUE(res);
333 EXPECT_TRUE(DeleteDC(hdc));
334 }
335
336 TEST(GDIFontEmulationTest, DeleteDCFailure) {
337 if (base::win::GetVersion() < base::win::VERSION_WIN8)
338 return;
339 TestSkFontMgr fontmgr;
340 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
341 EXPECT_NE(patch_data, nullptr);
342 HDC hdc = reinterpret_cast<HDC>(0x55667788);
343 EXPECT_FALSE(DeleteDC(hdc));
344 }
345
346 TEST(GDIFontEmulationTest, DeleteObjectFailure) {
347 if (base::win::GetVersion() < base::win::VERSION_WIN8)
348 return;
349 TestSkFontMgr fontmgr;
350 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
351 EXPECT_NE(patch_data, nullptr);
352 HFONT font = reinterpret_cast<HFONT>(0x88aabbcc);
353 EXPECT_FALSE(DeleteObject(font));
354 }
355
356 TEST(GDIFontEmulationTest, GetFontDataSizeSuccess) {
357 if (base::win::GetVersion() < base::win::VERSION_WIN8)
358 return;
359 TestSkFontMgr fontmgr;
360 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
361 EXPECT_NE(patch_data, nullptr);
362 HDC hdc = CreateCompatibleDC(0);
363 EXPECT_NE(hdc, nullptr);
364 LOGFONTW logfont = {0};
365 InitLogFont(&logfont, kTestFontFamilyW);
366 HFONT font = CreateFontIndirectW(&logfont);
367 EXPECT_NE(font, nullptr);
368 EXPECT_EQ(SelectObject(hdc, font), nullptr);
369 DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
370 DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
371 EXPECT_EQ(size, data_size);
372 EXPECT_TRUE(DeleteObject(font));
373 EXPECT_TRUE(DeleteDC(hdc));
374 }
375
376 TEST(GDIFontEmulationTest, GetFontDataInvalidTagSuccess) {
377 if (base::win::GetVersion() < base::win::VERSION_WIN8)
378 return;
379 TestSkFontMgr fontmgr;
380 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
381 EXPECT_NE(patch_data, nullptr);
382 HDC hdc = CreateCompatibleDC(0);
383 EXPECT_NE(hdc, nullptr);
384 LOGFONTW logfont = {0};
385 InitLogFont(&logfont, kTestFontFamilyW);
386 HFONT font = CreateFontIndirectW(&logfont);
387 EXPECT_NE(font, nullptr);
388 EXPECT_EQ(SelectObject(hdc, font), nullptr);
389 DWORD size = GetFontData(hdc, kTestFontTableTag + 1, 0, nullptr, 0);
390 EXPECT_EQ(size, GDI_ERROR);
391 EXPECT_TRUE(DeleteObject(font));
392 EXPECT_TRUE(DeleteDC(hdc));
393 }
394
395 TEST(GDIFontEmulationTest, GetFontDataInvalidFontSuccess) {
396 if (base::win::GetVersion() < base::win::VERSION_WIN8)
397 return;
398 TestSkFontMgr fontmgr;
399 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
400 EXPECT_NE(patch_data, nullptr);
401 HDC hdc = CreateCompatibleDC(0);
402 EXPECT_NE(hdc, nullptr);
403 DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
404 EXPECT_EQ(size, GDI_ERROR);
405 EXPECT_TRUE(DeleteDC(hdc));
406 }
407
408 TEST(GDIFontEmulationTest, GetFontDataDataSuccess) {
409 if (base::win::GetVersion() < base::win::VERSION_WIN8)
410 return;
411 TestSkFontMgr fontmgr;
412 scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
413 EXPECT_NE(patch_data, nullptr);
414 HDC hdc = CreateCompatibleDC(0);
415 EXPECT_NE(hdc, nullptr);
416 LOGFONTW logfont = {0};
417 InitLogFont(&logfont, kTestFontFamilyW);
418 HFONT font = CreateFontIndirectW(&logfont);
419 EXPECT_NE(font, nullptr);
420 EXPECT_EQ(SelectObject(hdc, font), nullptr);
421 DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
422 std::vector<char> data(data_size);
423 DWORD size = GetFontData(hdc, kTestFontTableTag, 0, &data[0], data.size());
424 EXPECT_EQ(size, data_size);
425 EXPECT_EQ(memcmp(&data[0], kTestFontData, data.size()), 0);
426 EXPECT_TRUE(DeleteObject(font));
427 EXPECT_TRUE(DeleteDC(hdc));
428 }
429
430 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698