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

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

Powered by Google App Engine
This is Rietveld 408576698