Index: content/common/font_list_win.cc |
diff --git a/content/common/font_list_win.cc b/content/common/font_list_win.cc |
index bc6c1dcd1ed296bc5f336dce9b4c7b9f8d17121b..50ef13c9a32374d8a544f8fa371e3cee7f4d7c78 100644 |
--- a/content/common/font_list_win.cc |
+++ b/content/common/font_list_win.cc |
@@ -5,11 +5,16 @@ |
#include "content/common/font_list.h" |
#include <windows.h> |
+#include <dwrite.h> |
#include <set> |
+#include "base/debug/alias.h" |
+#include "base/logging.h" |
#include "base/strings/string16.h" |
#include "base/values.h" |
+#include "content/common/sandbox_win.h" |
+#include "content/public/renderer/render_font_warmup_win.h" |
namespace content { |
@@ -29,7 +34,8 @@ static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font, |
return 1; |
} |
-scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { |
+static inline void GetFontListInternal_GDI( |
+ scoped_ptr<base::ListValue>& font_list) { |
std::set<base::string16> font_names; |
LOGFONTW logfont; |
@@ -41,7 +47,6 @@ scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { |
(LPARAM)&font_names, 0); |
::ReleaseDC(NULL, hdc); |
- scoped_ptr<base::ListValue> font_list(new base::ListValue); |
std::set<base::string16>::iterator iter; |
for (iter = font_names.begin(); iter != font_names.end(); ++iter) { |
base::ListValue* font_item = new base::ListValue(); |
@@ -49,6 +54,83 @@ scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { |
font_item->Append(new base::StringValue(*iter)); |
font_list->Append(font_item); |
} |
+} |
+ |
+static inline void AddLocalizedFontFamily( |
scottmg
2014/06/26 20:13:38
nit; no 'inline's necessary
|
+ scoped_ptr<base::ListValue>& font_list, |
+ IDWriteFontFamily* font_family, |
+ wchar_t* user_locale) { |
+ IDWriteLocalizedStrings* family_names = NULL; |
+ if (SUCCEEDED(font_family->GetFamilyNames(&family_names))) { |
+ UINT32 index = 0; |
+ BOOL exists = false; |
+ |
+ family_names->FindLocaleName(user_locale, &index, &exists); |
+ if (!exists) { |
+ family_names->FindLocaleName(L"en-us", &index, &exists); |
+ } |
+ if (!exists) { |
+ index = 0; |
+ } |
+ |
+ UINT32 len = 0; |
+ if (SUCCEEDED(family_names->GetStringLength(index, &len))) { |
+ wchar_t* name = new wchar_t[len + 1]; |
+ if (name) { |
+ if (SUCCEEDED(family_names->GetString(index, name, len + 1))) { |
+ base::ListValue* font_item = new base::ListValue(); |
+ font_item->Append(new base::StringValue(name)); |
+ font_item->Append(new base::StringValue(name)); |
+ font_list->Append(font_item); |
+ } |
+ delete[] name; |
+ } |
+ } |
+ } |
+ if (family_names) { |
+ family_names->Release(); |
+ } |
+} |
+ |
+static inline void GetFontListInternal_DirectWrite( |
+ scoped_ptr<base::ListValue>& font_list) { |
+ wchar_t user_locale[LOCALE_NAME_MAX_LENGTH]; |
+ GetUserDefaultLocaleName(user_locale, LOCALE_NAME_MAX_LENGTH); |
+ |
+ IDWriteFactory* factory = NULL; |
+ CreateDirectWriteFactory(&factory); |
+ |
+ IDWriteFontCollection* font_collection; |
+ BOOL checkForUpdates = false; |
+ if (SUCCEEDED(factory->GetSystemFontCollection(&font_collection, |
+ checkForUpdates))) { |
+ UINT32 family_count = font_collection->GetFontFamilyCount(); |
+ for (UINT32 i = 0; i < family_count; i++) { |
+ IDWriteFontFamily* font_family = NULL; |
+ if (SUCCEEDED(font_collection->GetFontFamily(i, &font_family))) { |
+ AddLocalizedFontFamily(font_list, font_family, user_locale); |
scottmg
2014/06/26 20:13:38
I'm not sure how this changes the actual names ret
eae
2014/06/26 20:58:24
For fonts with multiple names (e.x. SimSun which i
scottmg
2014/06/26 21:05:17
OK, I just noticed e.g. in https://src.chromium.or
|
+ } |
+ if (font_family) { |
+ font_family->Release(); |
+ } |
+ } |
+ } |
+ if (font_collection) { |
+ font_collection->Release(); |
+ } |
+ if (factory) { |
+ factory->Release(); |
+ } |
+} |
+ |
+scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { |
scottmg
2014/06/26 20:13:38
I'm a little unclear on where this happens. If it'
eae
2014/06/26 20:58:24
Yeah, the way I get the factory from the sandbox c
|
+ scoped_ptr<base::ListValue> font_list(new base::ListValue); |
+ if (ShouldUseDirectWrite()) { |
+ GetFontListInternal_DirectWrite(font_list); |
+ } |
+ if (font_list->GetSize() < 1) { |
+ GetFontListInternal_GDI(font_list); |
+ } |
return font_list.Pass(); |
} |