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

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

Issue 354023007: Use DirectWrite to populate list of avalible fonts (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/font_list.h" 5 #include "content/common/font_list.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <dwrite.h>
8 9
9 #include <set> 10 #include <set>
10 11
11 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
12 #include "base/values.h" 13 #include "base/values.h"
14 #include "content/common/sandbox_win.h"
13 15
14 namespace content { 16 namespace content {
15 17
16 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font, 18 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font,
17 NEWTEXTMETRICEXW* physical_font, 19 NEWTEXTMETRICEXW* physical_font,
18 DWORD font_type, 20 DWORD font_type,
19 LPARAM lparam) { 21 LPARAM lparam) {
20 std::set<base::string16>* font_names = 22 std::set<base::string16>* font_names =
21 reinterpret_cast<std::set<base::string16>*>(lparam); 23 reinterpret_cast<std::set<base::string16>*>(lparam);
22 if (font_names) { 24 if (font_names) {
23 const LOGFONTW& lf = logical_font->elfLogFont; 25 const LOGFONTW& lf = logical_font->elfLogFont;
24 if (lf.lfFaceName[0] && lf.lfFaceName[0] != '@') { 26 if (lf.lfFaceName[0] && lf.lfFaceName[0] != '@') {
25 base::string16 face_name(lf.lfFaceName); 27 base::string16 face_name(lf.lfFaceName);
26 font_names->insert(face_name); 28 font_names->insert(face_name);
27 } 29 }
28 } 30 }
29 return 1; 31 return 1;
30 } 32 }
31 33
32 scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { 34 static void GetFontListInternal_GDI(base::ListValue* font_list) {
33 std::set<base::string16> font_names; 35 std::set<base::string16> font_names;
34 36
35 LOGFONTW logfont; 37 LOGFONTW logfont;
36 memset(&logfont, 0, sizeof(logfont)); 38 memset(&logfont, 0, sizeof(logfont));
37 logfont.lfCharSet = DEFAULT_CHARSET; 39 logfont.lfCharSet = DEFAULT_CHARSET;
38 40
39 HDC hdc = ::GetDC(NULL); 41 HDC hdc = ::GetDC(NULL);
40 ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontFamExProc, 42 ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontFamExProc,
41 (LPARAM)&font_names, 0); 43 (LPARAM)&font_names, 0);
42 ::ReleaseDC(NULL, hdc); 44 ::ReleaseDC(NULL, hdc);
43 45
44 scoped_ptr<base::ListValue> font_list(new base::ListValue);
45 std::set<base::string16>::iterator iter; 46 std::set<base::string16>::iterator iter;
46 for (iter = font_names.begin(); iter != font_names.end(); ++iter) { 47 for (iter = font_names.begin(); iter != font_names.end(); ++iter) {
47 base::ListValue* font_item = new base::ListValue(); 48 base::ListValue* font_item = new base::ListValue();
48 font_item->Append(new base::StringValue(*iter)); 49 font_item->Append(new base::StringValue(*iter));
49 font_item->Append(new base::StringValue(*iter)); 50 font_item->Append(new base::StringValue(*iter));
50 font_list->Append(font_item); 51 font_list->Append(font_item);
51 } 52 }
53 }
54
55 static void AddLocalizedFontFamily(base::ListValue* font_list,
56 IDWriteFontFamily* font_family,
57 wchar_t* user_locale) {
58 IDWriteLocalizedStrings* family_names = NULL;
59 if (SUCCEEDED(font_family->GetFamilyNames(&family_names))) {
60 UINT32 index = 0;
61 BOOL exists = false;
62
63 // Try to get name of font in the users locale first, failing that fall back
64 // on US English and then the first name listed.
65 family_names->FindLocaleName(user_locale, &index, &exists);
66 if (!exists)
67 family_names->FindLocaleName(L"en-us", &index, &exists);
68 if (!exists)
69 index = 0;
70
71 UINT32 len = 0;
72 if (SUCCEEDED(family_names->GetStringLength(index, &len))) {
73 wchar_t* name = new wchar_t[len + 1];
74 if (name) {
75 if (SUCCEEDED(family_names->GetString(index, name, len + 1)) &&
76 name[0] != '@') {
77 base::ListValue* font_item = new base::ListValue();
78 // First field is the name displayed to the user, second is the name
79 // used internally and passed to the font system. For fonts the
80 // localized name is used for both.
81 font_item->Append(new base::StringValue(name));
82 font_item->Append(new base::StringValue(name));
83 font_list->Append(font_item);
84 }
85 delete[] name;
86 }
87 }
88 }
89 if (family_names)
90 family_names->Release();
91 }
92
93 static void CreateDirectWriteFactory(IDWriteFactory** factory) {
94 typedef decltype(DWriteCreateFactory) * DWriteCreateFactoryProc;
95 HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll");
96 if (dwrite_dll) {
97 DWriteCreateFactoryProc dwrite_create_factory_proc =
98 reinterpret_cast<DWriteCreateFactoryProc>(
99 GetProcAddress(dwrite_dll, "DWriteCreateFactory"));
100 if (dwrite_create_factory_proc) {
101 dwrite_create_factory_proc(DWRITE_FACTORY_TYPE_ISOLATED,
102 __uuidof(IDWriteFactory),
103 reinterpret_cast<IUnknown**>(factory));
104 }
105 }
106 }
107
108 static void GetFontListInternal_DirectWrite(base::ListValue* font_list) {
109 wchar_t user_locale[LOCALE_NAME_MAX_LENGTH];
110 GetUserDefaultLocaleName(user_locale, LOCALE_NAME_MAX_LENGTH);
111
112 IDWriteFactory* factory = NULL;
cpu_(ooo_6.6-7.5) 2014/06/27 01:11:28 factory and font_collection should be ScopedComPtr
eae 2014/06/27 02:14:59 Didn't know we had ScopedComPtr. Seems like a perf
113 CreateDirectWriteFactory(&factory);
114
115 IDWriteFontCollection* font_collection = NULL;
116 BOOL check_for_updates = false;
117 if (factory && SUCCEEDED(factory->GetSystemFontCollection(
118 &font_collection, check_for_updates))) {
119 UINT32 family_count = font_collection->GetFontFamilyCount();
120 for (UINT32 i = 0; i < family_count; i++) {
121 IDWriteFontFamily* font_family = NULL;
122 if (SUCCEEDED(font_collection->GetFontFamily(i, &font_family)))
123 AddLocalizedFontFamily(font_list, font_family, user_locale);
124 if (font_family)
125 font_family->Release();
126 }
127 }
128
129 if (font_collection)
130 font_collection->Release();
131 if (factory)
132 factory->Release();
133 }
134
135 scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
136 scoped_ptr<base::ListValue> font_list(new base::ListValue);
137
138 if (ShouldUseDirectWrite())
139 GetFontListInternal_DirectWrite(font_list.get());
140
141 // Fallback on GDI if DirectWrite isn't enabled or if it failed to populate
142 // the font list.
143 if (font_list->GetSize() == 0)
144 GetFontListInternal_GDI(font_list.get());
145
52 return font_list.Pass(); 146 return font_list.Pass();
53 } 147 }
54 148
55 } // namespace content 149 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698