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

Unified 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: More fixes for 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/font_warmup_win.cc ('k') | content/content_tests.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/font_warmup_win_unittest.cc
diff --git a/content/common/font_warmup_win_unittest.cc b/content/common/font_warmup_win_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..44bb96a5698fb511716add60b98e1ac2e6d54d06
--- /dev/null
+++ b/content/common/font_warmup_win_unittest.cc
@@ -0,0 +1,430 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/font_warmup_win.h"
+
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/sys_byteorder.h"
+#include "base/win/windows_version.h"
+#include "skia/ext/refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkString.h"
+#include "third_party/skia/include/core/SkTypeface.h"
+#include "third_party/skia/include/ports/SkFontMgr.h"
+
+namespace content {
+
+namespace {
+
+class TestSkTypeface : public SkTypeface {
+ public:
+ TestSkTypeface(const SkFontStyle& style,
+ const char* familyName,
+ SkFontTableTag tag,
+ const char* data,
+ size_t dataLength)
+ : SkTypeface(style, 0),
+ familyName_(familyName),
+ tag_(tag),
+ data_(data, data + dataLength) {}
+
+ protected:
+ SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+ void onFilterRec(SkScalerContextRec*) const override { ADD_FAILURE(); }
+ SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
+ PerGlyphInfo,
+ const uint32_t* glyphIDs,
+ uint32_t glyphIDsCount) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkStreamAsset* onOpenStream(int* ttcIndex) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkFontData* onCreateFontData() const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const override {
+ ADD_FAILURE();
+ }
+
+ int onCharsToGlyphs(const void* chars,
+ Encoding,
+ uint16_t glyphs[],
+ int glyphCount) const override {
+ ADD_FAILURE();
+ return 0;
+ }
+
+ int onCountGlyphs() const override {
+ ADD_FAILURE();
+ return 0;
+ }
+
+ int onGetUPEM() const override {
+ ADD_FAILURE();
+ return 0;
+ }
+ bool onGetKerningPairAdjustments(const uint16_t glyphs[],
+ int count,
+ int32_t adjustments[]) const override {
+ ADD_FAILURE();
+ return false;
+ }
+
+ void onGetFamilyName(SkString* familyName) const override {
+ *familyName = familyName_;
+ }
+
+ LocalizedStrings* onCreateFamilyNameIterator() const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ int onGetTableTags(SkFontTableTag tags[]) const override {
+ ADD_FAILURE();
+ return 0;
+ }
+
+ size_t onGetTableData(SkFontTableTag tag,
+ size_t offset,
+ size_t length,
+ void* data) const override {
+ size_t retsize = 0;
+ if (tag == tag_) {
+ retsize = length > data_.size() ? data_.size() : length;
+ if (data)
+ memcpy(data, &data_[0], retsize);
+ }
+ return retsize;
+ }
+
+ bool onComputeBounds(SkRect*) const override {
+ ADD_FAILURE();
+ return false;
+ }
+
+ private:
+ SkString familyName_;
+ SkFontTableTag tag_;
+ std::vector<char> data_;
+};
+
+const char* kTestFontFamily = "GDITest";
+const wchar_t* kTestFontFamilyW = L"GDITest";
+const SkFontTableTag kTestFontTableTag = 0x11223344;
+const char* kTestFontData = "GDITestGDITest";
+const wchar_t* kTestFontFamilyInvalid = L"InvalidFont";
+
+class TestSkFontMgr : public SkFontMgr {
+ public:
+ TestSkFontMgr() { content::SetPreSandboxWarmupFontMgrForTesting(this); }
+ ~TestSkFontMgr() { content::SetPreSandboxWarmupFontMgrForTesting(nullptr); }
+
+ protected:
+ int onCountFamilies() const override { return 1; }
+
+ void onGetFamilyName(int index, SkString* familyName) const override {
+ if (index == 0)
+ *familyName = kTestFontFamily;
+ }
+
+ SkFontStyleSet* onCreateStyleSet(int index) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onMatchFamilyStyle(const char familyName[],
+ const SkFontStyle&) const override {
+ if (strcmp(familyName, kTestFontFamily) == 0)
+ return createTypeface();
+ return nullptr;
+ }
+
+ SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle&,
+ const char* bcp47[],
+ int bcp47Count,
+ SkUnichar character) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onMatchFaceStyle(const SkTypeface*,
+ const SkFontStyle&) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onCreateFromData(SkData*, int ttcIndex) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onCreateFromStream(SkStreamAsset*, int ttcIndex) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onCreateFromFontData(SkFontData*) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) const override {
+ ADD_FAILURE();
+ return nullptr;
+ }
+
+ private:
+ SkTypeface* createTypeface() const {
+ SkFontStyle style(400, 100, SkFontStyle::kUpright_Slant);
+
+ return new TestSkTypeface(style, kTestFontFamily,
+ base::ByteSwap(kTestFontTableTag), kTestFontData,
+ strlen(kTestFontData));
+ }
+};
+
+void InitLogFont(LOGFONTW* logfont, const wchar_t* fontname) {
+ size_t length = std::min(sizeof(logfont->lfFaceName),
+ (wcslen(fontname) + 1) * sizeof(wchar_t));
+ memcpy(logfont->lfFaceName, fontname, length);
+}
+
+content::GdiFontPatchData* SetupTest() {
+ HMODULE module_handle;
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ reinterpret_cast<LPCWSTR>(SetupTest),
+ &module_handle)) {
+ WCHAR module_path[MAX_PATH];
+
+ if (GetModuleFileNameW(module_handle, module_path, MAX_PATH) > 0) {
+ base::FilePath path(module_path);
+ content::ResetEmulatedGdiHandlesForTesting();
+ return content::PatchGdiFontEnumeration(path);
+ }
+ }
+ return nullptr;
+}
+
+int CALLBACK EnumFontCallbackTest(const LOGFONT* log_font,
+ const TEXTMETRIC* text_metric,
+ DWORD font_type,
+ LPARAM param) {
+ const NEWTEXTMETRICEX* new_text_metric =
+ reinterpret_cast<const NEWTEXTMETRICEX*>(text_metric);
+
+ return !(font_type & TRUETYPE_FONTTYPE) &&
+ !(new_text_metric->ntmTm.ntmFlags & NTM_PS_OPENTYPE);
+}
+
+} // namespace
+
+TEST(GDIFontEmulationTest, CreateDeleteDCSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_FALSE(!patch_data);
+
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 1);
+ EXPECT_TRUE(DeleteDC(hdc));
+ EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 0);
+}
+
+TEST(GDIFontEmulationTest, CreateUniqueDCSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+
+ HDC hdc1 = CreateCompatibleDC(0);
+ EXPECT_NE(hdc1, nullptr);
+ HDC hdc2 = CreateCompatibleDC(0);
+ EXPECT_NE(hdc2, nullptr);
+ EXPECT_NE(hdc1, hdc2);
+ EXPECT_TRUE(DeleteDC(hdc2));
+ EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 1);
+ EXPECT_TRUE(DeleteDC(hdc1));
+ EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 0);
+}
+
+TEST(GDIFontEmulationTest, CreateFontSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyW);
+ HFONT font = CreateFontIndirectW(&logfont);
+ EXPECT_NE(font, nullptr);
+ EXPECT_TRUE(DeleteObject(font));
+ EXPECT_EQ(GetEmulatedGdiHandleCountForTesting(), 0);
+}
+
+TEST(GDIFontEmulationTest, CreateFontFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyInvalid);
+ HFONT font = CreateFontIndirectW(&logfont);
+ EXPECT_EQ(font, nullptr);
+}
+
+TEST(GDIFontEmulationTest, EnumFontFamilySuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyW);
+ int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
+ EXPECT_FALSE(res);
+ EXPECT_TRUE(DeleteDC(hdc));
+}
+
+TEST(GDIFontEmulationTest, EnumFontFamilyFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyInvalid);
+ int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
+ EXPECT_TRUE(res);
+ EXPECT_TRUE(DeleteDC(hdc));
+}
+
+TEST(GDIFontEmulationTest, DeleteDCFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = reinterpret_cast<HDC>(0x55667788);
+ EXPECT_FALSE(DeleteDC(hdc));
+}
+
+TEST(GDIFontEmulationTest, DeleteObjectFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HFONT font = reinterpret_cast<HFONT>(0x88aabbcc);
+ EXPECT_FALSE(DeleteObject(font));
+}
+
+TEST(GDIFontEmulationTest, GetFontDataSizeSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyW);
+ HFONT font = CreateFontIndirectW(&logfont);
+ EXPECT_NE(font, nullptr);
+ EXPECT_EQ(SelectObject(hdc, font), nullptr);
+ DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
+ DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
+ EXPECT_EQ(size, data_size);
+ EXPECT_TRUE(DeleteObject(font));
+ EXPECT_TRUE(DeleteDC(hdc));
+}
+
+TEST(GDIFontEmulationTest, GetFontDataInvalidTagSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyW);
+ HFONT font = CreateFontIndirectW(&logfont);
+ EXPECT_NE(font, nullptr);
+ EXPECT_EQ(SelectObject(hdc, font), nullptr);
+ DWORD size = GetFontData(hdc, kTestFontTableTag + 1, 0, nullptr, 0);
+ EXPECT_EQ(size, GDI_ERROR);
+ EXPECT_TRUE(DeleteObject(font));
+ EXPECT_TRUE(DeleteDC(hdc));
+}
+
+TEST(GDIFontEmulationTest, GetFontDataInvalidFontSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
+ EXPECT_EQ(size, GDI_ERROR);
+ EXPECT_TRUE(DeleteDC(hdc));
+}
+
+TEST(GDIFontEmulationTest, GetFontDataDataSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+ TestSkFontMgr fontmgr;
+ scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
+ EXPECT_NE(patch_data, nullptr);
+ HDC hdc = CreateCompatibleDC(0);
+ EXPECT_NE(hdc, nullptr);
+ LOGFONTW logfont = {0};
+ InitLogFont(&logfont, kTestFontFamilyW);
+ HFONT font = CreateFontIndirectW(&logfont);
+ EXPECT_NE(font, nullptr);
+ EXPECT_EQ(SelectObject(hdc, font), nullptr);
+ DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
+ std::vector<char> data(data_size);
+ DWORD size = GetFontData(hdc, kTestFontTableTag, 0, &data[0], data.size());
+ EXPECT_EQ(size, data_size);
+ EXPECT_EQ(memcmp(&data[0], kTestFontData, data.size()), 0);
+ EXPECT_TRUE(DeleteObject(font));
+ EXPECT_TRUE(DeleteDC(hdc));
+}
+
+} // namespace content
« no previous file with comments | « content/common/font_warmup_win.cc ('k') | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698