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

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, 6 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(scoped_ptr<base::ListValue>& font_list) {
scottmg 2014/06/26 22:45:27 no & here
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(scoped_ptr<base::ListValue>& font_list,
scottmg 2014/06/26 22:45:27 no & here
56 IDWriteFontFamily* font_family,
57 wchar_t* user_locale) {
58 IDWriteLocalizedStrings* family_names = NULL;
59 if (SUCCEEDED(font_family->GetFamilyNames(&family_names))) {
scottmg 2014/06/26 22:45:27 gdi skips fonts starting with @ (vertical orientat
eae 2014/06/26 23:14:57 We go out of our way to check for the @ prefix in
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 base::ListValue* font_item = new base::ListValue();
77 font_item->Append(new base::StringValue(name));
scottmg 2014/06/26 22:45:27 i assume 2x is correct since gdi does too, maybe a
78 font_item->Append(new base::StringValue(name));
79 font_list->Append(font_item);
80 }
81 delete[] name;
82 }
83 }
84 }
85 if (family_names)
scottmg 2014/06/26 22:45:27 could this just not go inside the if (SUCCEEDED(Ge
eae 2014/06/26 23:14:57 The documentation for GetFamilyNames is unclear on
86 family_names->Release();
87 }
88
89 static void CreateDirectWriteFactory(IDWriteFactory** factory) {
90 typedef decltype(DWriteCreateFactory) * DWriteCreateFactoryProc;
91 HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll");
92 if (dwrite_dll) {
93 DWriteCreateFactoryProc dwrite_create_factory_proc =
94 reinterpret_cast<DWriteCreateFactoryProc>(
95 GetProcAddress(dwrite_dll, "DWriteCreateFactory"));
96 if (dwrite_create_factory_proc) {
97 dwrite_create_factory_proc(DWRITE_FACTORY_TYPE_ISOLATED,
98 __uuidof(IDWriteFactory),
99 reinterpret_cast<IUnknown**>(factory));
100 }
101 }
102 }
103
104 static void GetFontListInternal_DirectWrite(
105 scoped_ptr<base::ListValue>& font_list) {
scottmg 2014/06/26 22:45:27 no & here
106 wchar_t user_locale[LOCALE_NAME_MAX_LENGTH];
107 GetUserDefaultLocaleName(user_locale, LOCALE_NAME_MAX_LENGTH);
108
109 IDWriteFactory* factory = NULL;
110 CreateDirectWriteFactory(&factory);
111
112 IDWriteFontCollection* font_collection = NULL;
113 BOOL checkForUpdates = false;
scottmg 2014/06/26 22:45:27 checkForUpdates -> check_for_updates
eae 2014/06/26 23:14:57 Thanks, haven't written chromium style code in awh
114 if (factory && SUCCEEDED(factory->GetSystemFontCollection(&font_collection,
115 checkForUpdates))) {
116 UINT32 family_count = font_collection->GetFontFamilyCount();
117 for (UINT32 i = 0; i < family_count; i++) {
118 IDWriteFontFamily* font_family = NULL;
119 if (SUCCEEDED(font_collection->GetFontFamily(i, &font_family)))
120 AddLocalizedFontFamily(font_list, font_family, user_locale);
121 if (font_family)
122 font_family->Release();
scottmg 2014/06/26 22:45:27 move inside if (SUCCEEDED())?
eae 2014/06/26 23:14:57 Again, it is unclear whether it is guaranteed not
123 }
124 }
125
126 if (font_collection)
scottmg 2014/06/26 22:45:27 can this move inside the GetSystemFontCollection b
127 font_collection->Release();
128 if (factory)
129 factory->Release();
130 }
131
132 scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
133 scoped_ptr<base::ListValue> font_list(new base::ListValue);
134
135 if (ShouldUseDirectWrite())
136 GetFontListInternal_DirectWrite(font_list);
137
138 // Fallback on GDI if DirectWrite isn't enabled or if it failed to populate
139 // the font list.
140 if (font_list->GetSize() < 1)
scottmg 2014/06/26 22:45:27 nit (optional); == 0 seems clearer than < 1 to me
eae 2014/06/26 23:14:57 I agree.
141 GetFontListInternal_GDI(font_list);
142
52 return font_list.Pass(); 143 return font_list.Pass();
53 } 144 }
54 145
55 } // namespace content 146 } // 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