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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..5d346905877d82893f14f8711ebe2ed9d4e63aad 100644
--- a/content/common/font_list_win.cc
+++ b/content/common/font_list_win.cc
@@ -5,11 +5,13 @@
#include "content/common/font_list.h"
#include <windows.h>
+#include <dwrite.h>
#include <set>
#include "base/strings/string16.h"
#include "base/values.h"
+#include "content/common/sandbox_win.h"
namespace content {
@@ -29,7 +31,7 @@ static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font,
return 1;
}
-scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
+static void GetFontListInternal_GDI(scoped_ptr<base::ListValue>& font_list) {
scottmg 2014/06/26 22:45:27 no & here
std::set<base::string16> font_names;
LOGFONTW logfont;
@@ -41,7 +43,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 +50,96 @@ scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
font_item->Append(new base::StringValue(*iter));
font_list->Append(font_item);
}
+}
+
+static void AddLocalizedFontFamily(scoped_ptr<base::ListValue>& font_list,
scottmg 2014/06/26 22:45:27 no & here
+ IDWriteFontFamily* font_family,
+ wchar_t* user_locale) {
+ IDWriteLocalizedStrings* family_names = NULL;
+ 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
+ UINT32 index = 0;
+ BOOL exists = false;
+
+ // Try to get name of font in the users locale first, failing that fall back
+ // on US English and then the first name listed.
+ 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));
scottmg 2014/06/26 22:45:27 i assume 2x is correct since gdi does too, maybe a
+ font_item->Append(new base::StringValue(name));
+ font_list->Append(font_item);
+ }
+ delete[] name;
+ }
+ }
+ }
+ 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
+ family_names->Release();
+}
+
+static void CreateDirectWriteFactory(IDWriteFactory** factory) {
+ typedef decltype(DWriteCreateFactory) * DWriteCreateFactoryProc;
+ HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll");
+ if (dwrite_dll) {
+ DWriteCreateFactoryProc dwrite_create_factory_proc =
+ reinterpret_cast<DWriteCreateFactoryProc>(
+ GetProcAddress(dwrite_dll, "DWriteCreateFactory"));
+ if (dwrite_create_factory_proc) {
+ dwrite_create_factory_proc(DWRITE_FACTORY_TYPE_ISOLATED,
+ __uuidof(IDWriteFactory),
+ reinterpret_cast<IUnknown**>(factory));
+ }
+ }
+}
+
+static void GetFontListInternal_DirectWrite(
+ scoped_ptr<base::ListValue>& font_list) {
scottmg 2014/06/26 22:45:27 no & here
+ wchar_t user_locale[LOCALE_NAME_MAX_LENGTH];
+ GetUserDefaultLocaleName(user_locale, LOCALE_NAME_MAX_LENGTH);
+
+ IDWriteFactory* factory = NULL;
+ CreateDirectWriteFactory(&factory);
+
+ IDWriteFontCollection* font_collection = NULL;
+ 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
+ if (factory && 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);
+ if (font_family)
+ 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
+ }
+ }
+
+ if (font_collection)
scottmg 2014/06/26 22:45:27 can this move inside the GetSystemFontCollection b
+ font_collection->Release();
+ if (factory)
+ factory->Release();
+}
+
+scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
+ scoped_ptr<base::ListValue> font_list(new base::ListValue);
+
+ if (ShouldUseDirectWrite())
+ GetFontListInternal_DirectWrite(font_list);
+
+ // Fallback on GDI if DirectWrite isn't enabled or if it failed to populate
+ // the font list.
+ 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.
+ GetFontListInternal_GDI(font_list);
+
return font_list.Pass();
}
« 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