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

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: w/ScopedComPtr 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 "base/win/scoped_comptr.h"
15 #include "content/common/sandbox_win.h"
13 16
14 namespace content { 17 namespace content {
15 18
16 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font, 19 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font,
17 NEWTEXTMETRICEXW* physical_font, 20 NEWTEXTMETRICEXW* physical_font,
18 DWORD font_type, 21 DWORD font_type,
19 LPARAM lparam) { 22 LPARAM lparam) {
20 std::set<base::string16>* font_names = 23 std::set<base::string16>* font_names =
21 reinterpret_cast<std::set<base::string16>*>(lparam); 24 reinterpret_cast<std::set<base::string16>*>(lparam);
22 if (font_names) { 25 if (font_names) {
23 const LOGFONTW& lf = logical_font->elfLogFont; 26 const LOGFONTW& lf = logical_font->elfLogFont;
24 if (lf.lfFaceName[0] && lf.lfFaceName[0] != '@') { 27 if (lf.lfFaceName[0] && lf.lfFaceName[0] != '@') {
25 base::string16 face_name(lf.lfFaceName); 28 base::string16 face_name(lf.lfFaceName);
26 font_names->insert(face_name); 29 font_names->insert(face_name);
27 } 30 }
28 } 31 }
29 return 1; 32 return 1;
30 } 33 }
31 34
32 scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { 35 static void GetFontListInternal_GDI(base::ListValue* font_list) {
33 std::set<base::string16> font_names; 36 std::set<base::string16> font_names;
34 37
35 LOGFONTW logfont; 38 LOGFONTW logfont;
36 memset(&logfont, 0, sizeof(logfont)); 39 memset(&logfont, 0, sizeof(logfont));
37 logfont.lfCharSet = DEFAULT_CHARSET; 40 logfont.lfCharSet = DEFAULT_CHARSET;
38 41
39 HDC hdc = ::GetDC(NULL); 42 HDC hdc = ::GetDC(NULL);
40 ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontFamExProc, 43 ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontFamExProc,
41 (LPARAM)&font_names, 0); 44 (LPARAM)&font_names, 0);
42 ::ReleaseDC(NULL, hdc); 45 ::ReleaseDC(NULL, hdc);
43 46
44 scoped_ptr<base::ListValue> font_list(new base::ListValue);
45 std::set<base::string16>::iterator iter; 47 std::set<base::string16>::iterator iter;
46 for (iter = font_names.begin(); iter != font_names.end(); ++iter) { 48 for (iter = font_names.begin(); iter != font_names.end(); ++iter) {
47 base::ListValue* font_item = new base::ListValue(); 49 base::ListValue* font_item = new base::ListValue();
48 font_item->Append(new base::StringValue(*iter)); 50 font_item->Append(new base::StringValue(*iter));
49 font_item->Append(new base::StringValue(*iter)); 51 font_item->Append(new base::StringValue(*iter));
50 font_list->Append(font_item); 52 font_list->Append(font_item);
51 } 53 }
54 }
55
56 static void AddLocalizedFontFamily(base::ListValue* font_list,
57 IDWriteFontFamily* font_family,
58 wchar_t* user_locale) {
59 base::win::ScopedComPtr<IDWriteLocalizedStrings> family_names;
60 if (SUCCEEDED(font_family->GetFamilyNames(family_names.Receive()))) {
61 UINT32 index = 0;
62 BOOL exists = false;
63
64 // Try to get name of font in the users locale first, failing that fall back
65 // on US English and then the first name listed.
66 family_names->FindLocaleName(user_locale, &index, &exists);
67 if (!exists)
68 family_names->FindLocaleName(L"en-us", &index, &exists);
69 if (!exists)
70 index = 0;
71
72 UINT32 len = 0;
73 if (SUCCEEDED(family_names->GetStringLength(index, &len))) {
74 wchar_t* name = new wchar_t[len + 1];
75 if (name) {
76 if (SUCCEEDED(family_names->GetString(index, name, len + 1)) &&
77 name[0] != '@') {
78 base::ListValue* font_item = new base::ListValue();
79 // First field is the name displayed to the user, second is the name
80 // used internally and passed to the font system. For fonts the
81 // localized name is used for both.
82 font_item->Append(new base::StringValue(name));
83 font_item->Append(new base::StringValue(name));
84 font_list->Append(font_item);
85 }
86 delete[] name;
87 }
88 }
89 }
90 }
91
92 static base::win::ScopedComPtr<IDWriteFactory> CreateDirectWriteFactory() {
93 base::win::ScopedComPtr<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(
102 DWRITE_FACTORY_TYPE_ISOLATED,
103 __uuidof(IDWriteFactory),
104 reinterpret_cast<IUnknown**>(factory.Receive()));
105 }
106 }
107 return factory;
108 }
109
110 static void GetFontListInternal_DirectWrite(base::ListValue* font_list) {
111 wchar_t user_locale[LOCALE_NAME_MAX_LENGTH];
112 GetUserDefaultLocaleName(user_locale, LOCALE_NAME_MAX_LENGTH);
113
114 base::win::ScopedComPtr<IDWriteFactory> factory = CreateDirectWriteFactory();
115
116 base::win::ScopedComPtr<IDWriteFontCollection> font_collection;
117 BOOL check_for_updates = false;
118 if (factory && SUCCEEDED(factory->GetSystemFontCollection(
119 font_collection.Receive(), check_for_updates))) {
120 UINT32 family_count = font_collection->GetFontFamilyCount();
121 for (UINT32 i = 0; i < family_count; i++) {
122 base::win::ScopedComPtr<IDWriteFontFamily> font_family;
123 if (SUCCEEDED(font_collection->GetFontFamily(i, font_family.Receive())))
124 AddLocalizedFontFamily(font_list, font_family, user_locale);
125 }
126 }
127 }
128
129 scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
130 scoped_ptr<base::ListValue> font_list(new base::ListValue);
131
132 if (ShouldUseDirectWrite())
133 GetFontListInternal_DirectWrite(font_list.get());
134
135 // Fallback on GDI if DirectWrite isn't enabled or if it failed to populate
136 // the font list.
137 if (font_list->GetSize() == 0)
138 GetFontListInternal_GDI(font_list.get());
139
52 return font_list.Pass(); 140 return font_list.Pass();
53 } 141 }
54 142
55 } // namespace content 143 } // 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