Chromium Code Reviews| Index: content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc |
| diff --git a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc |
| index 6d16572b4fe3eda12e64a096b438e0f0bde20e2a..b3d93b745a1fb291a7b65c518fc5f7760ffe21be 100644 |
| --- a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc |
| +++ b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc |
| @@ -20,6 +20,7 @@ |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "content/common/dwrite_font_proxy_messages.h" |
| +#include "content/common/dwrite_text_analysis_source_win.h" |
| #include "ipc/ipc_message_macros.h" |
| #include "ui/gfx/win/direct_write.h" |
| @@ -90,6 +91,7 @@ bool DWriteFontProxyMessageFilter::OnMessageReceived( |
| IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyCount, OnGetFamilyCount) |
| IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyNames, OnGetFamilyNames) |
| IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFontFiles, OnGetFontFiles) |
| + IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_MapCharacters, OnMapCharacters) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| @@ -223,6 +225,97 @@ void DWriteFontProxyMessageFilter::OnGetFontFiles( |
| file_paths->assign(path_set.begin(), path_set.end()); |
| } |
| +void DWriteFontProxyMessageFilter::OnMapCharacters( |
| + const base::string16& text, |
| + const DWriteFontStyle& font_style, |
| + const base::string16& locale_name, |
| + uint32_t reading_direction, |
| + const base::string16& base_family_name, |
| + MapCharactersResult* result) { |
| + InitializeDirectWrite(); |
| + result->family_index = UINT32_MAX; |
| + result->mapped_length = text.length(); |
| + if (factory2_ == nullptr || collection_ == nullptr) |
| + return; |
| + if (font_fallback_ == nullptr) { |
| + if (!SUCCEEDED(factory2_->GetSystemFontFallback(&font_fallback_))) |
|
ananta
2016/04/12 23:44:39
Please change to if (FAILED here and everywhere in
Ilya Kulshin
2016/04/13 01:33:28
Done.
|
| + return; |
| + } |
| + |
| + UINT32 length; |
| + mswr::ComPtr<IDWriteFont> mapped_font; |
| + |
| + mswr::ComPtr<IDWriteNumberSubstitution> number_substitution; |
| + if (!SUCCEEDED(factory2_->CreateNumberSubstitution( |
| + DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, locale_name.c_str(), |
| + TRUE /* ignoreUserOverride */, &number_substitution))) { |
| + DCHECK(false); |
| + return; |
| + } |
| + mswr::ComPtr<IDWriteTextAnalysisSource> analysis_source; |
| + if (!SUCCEEDED(mswr::MakeAndInitialize<TextAnalysisSource>( |
| + &analysis_source, text, locale_name, number_substitution.Get(), |
| + static_cast<DWRITE_READING_DIRECTION>(reading_direction)))) { |
| + DCHECK(false); |
| + return; |
| + } |
| + |
| + if (!SUCCEEDED(font_fallback_->MapCharacters( |
| + analysis_source.Get(), 0, text.length(), collection_.Get(), |
| + base_family_name.c_str(), |
| + static_cast<DWRITE_FONT_WEIGHT>(font_style.font_weight), |
| + static_cast<DWRITE_FONT_STYLE>(font_style.font_slant), |
| + static_cast<DWRITE_FONT_STRETCH>(font_style.font_stretch), &length, |
| + &mapped_font, &result->scale))) { |
| + DCHECK(false); |
| + return; |
| + } |
| + |
| + result->mapped_length = length; |
| + if (mapped_font == nullptr) |
| + return; |
| + |
| + mswr::ComPtr<IDWriteFontFamily> mapped_family; |
| + if (!SUCCEEDED(mapped_font->GetFontFamily(&mapped_family))) { |
| + DCHECK(false); |
| + return; |
| + } |
| + mswr::ComPtr<IDWriteLocalizedStrings> family_names; |
| + if (!SUCCEEDED(mapped_family->GetFamilyNames(&family_names))) { |
| + DCHECK(false); |
| + return; |
| + } |
| + |
| + std::vector<base::char16> name; |
| + size_t name_count = family_names->GetCount(); |
| + for (size_t name_index = 0; name_index < name_count; name_index++) { |
| + UINT32 name_length = 0; |
| + if (!SUCCEEDED(family_names->GetStringLength(name_index, &name_length))) |
| + continue; // Keep trying other names |
| + |
| + ++name_length; // Reserve space for the null terminator. |
| + name.resize(name_length); |
| + if (!SUCCEEDED( |
| + family_names->GetString(name_index, name.data(), name_length))) |
| + continue; |
| + UINT32 index = UINT32_MAX; |
| + BOOL exists = false; |
| + if (!SUCCEEDED(collection_->FindFamilyName(name.data(), &index, &exists)) || |
| + !exists) |
| + continue; |
| + |
| + // Found a matching family! |
| + result->family_index = index; |
| + result->family_name = name.data(); |
| + return; |
| + } |
| + // Could not find a matching family |
| + // TODO(kulshin): log UMA that we matched a font, but could not locate the |
| + // family |
| + DCHECK_EQ(result->family_index, UINT32_MAX); |
| + DCHECK_GT(result->mapped_length, 0u); |
| +} |
| + |
| void DWriteFontProxyMessageFilter::InitializeDirectWrite() { |
| DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| if (direct_write_initialized_) |
| @@ -237,6 +330,10 @@ void DWriteFontProxyMessageFilter::InitializeDirectWrite() { |
| return; |
| } |
| + // QueryInterface for IDWriteFactory2. It's ok for this to fail if we are |
| + // running an older version of DirectWrite (earlier than Win8.1). |
| + factory.As<IDWriteFactory2>(&factory2_); |
| + |
| HRESULT hr = factory->GetSystemFontCollection(&collection_); |
| DCHECK(SUCCEEDED(hr)); |
| } |