Index: content/child/dwrite_font_proxy/font_fallback_win.cc |
diff --git a/content/child/dwrite_font_proxy/font_fallback_win.cc b/content/child/dwrite_font_proxy/font_fallback_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..46588c7066a5c89efb61887c0eff125bd4e97b02 |
--- /dev/null |
+++ b/content/child/dwrite_font_proxy/font_fallback_win.cc |
@@ -0,0 +1,108 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/child/dwrite_font_proxy/font_fallback_win.h" |
+ |
+#include "base/strings/string16.h" |
+ |
+#include "content/child/dwrite_font_proxy/dwrite_font_proxy_win.h" |
+#include "content/common/dwrite_font_proxy_messages.h" |
+#include "content/public/child/child_thread.h" |
+#include "ipc/ipc_sender.h" |
+ |
+namespace mswr = Microsoft::WRL; |
+ |
+namespace content { |
+ |
+FontFallback::FontFallback() = default; |
+FontFallback::~FontFallback() = default; |
+ |
+HRESULT FontFallback::MapCharacters(IDWriteTextAnalysisSource* source, |
+ UINT32 text_position, |
+ UINT32 text_length, |
+ IDWriteFontCollection* base_font_collection, |
+ const wchar_t* base_family_name, |
+ DWRITE_FONT_WEIGHT base_weight, |
+ DWRITE_FONT_STYLE base_style, |
+ DWRITE_FONT_STRETCH base_stretch, |
+ UINT32* mapped_length, |
+ IDWriteFont** mapped_font, |
+ FLOAT* scale) { |
+ *mapped_font = nullptr; |
+ *mapped_length = 1; |
+ *scale = 1.0; |
+ |
+ const WCHAR* text = nullptr; |
+ UINT32 chunk_length = 0; |
+ if (FAILED(source->GetTextAtPosition(text_position, &text, &chunk_length))) { |
+ DCHECK(false); |
+ return E_FAIL; |
+ } |
+ base::string16 text_chunk(text, chunk_length); |
+ |
+ const WCHAR* locale = nullptr; |
+ // |locale_text_length| is actually the length of text with the locale, not |
+ // the length of the locale string itself. |
+ UINT32 locale_text_length = 0; |
+ source->GetLocaleName(text_position /*textPosition*/, &locale_text_length, |
+ &locale); |
+ |
+ if (locale == nullptr) |
+ locale = L""; |
+ |
+ DWriteFontStyle style; |
+ style.font_weight = base_weight; |
+ style.font_slant = base_style; |
+ style.font_stretch = base_stretch; |
+ |
+ MapCharactersResult result; |
+ |
+ IPC::Sender* sender = |
+ sender_override_ ? sender_override_ : ChildThread::Get(); |
+ if (!sender->Send(new DWriteFontProxyMsg_MapCharacters( |
+ text_chunk, style, locale, source->GetParagraphReadingDirection(), |
+ base_family_name ? base_family_name : L"", &result))) |
+ return E_FAIL; |
+ |
+ *mapped_length = result.mapped_length; |
+ *scale = result.scale; |
+ |
+ if (result.family_index == UINT32_MAX) |
+ return S_OK; |
+ |
+ mswr::ComPtr<IDWriteFontFamily> family; |
+ // It would be nice to find a way to determine at runtime if |collection_| is |
+ // a proxy collection, or just a generic IDWriteFontCollection. Unfortunately |
+ // I can't find a way to get QueryInterface to return the actual class when |
+ // using mswr::RuntimeClass. If we could use QI, we can fallback on |
+ // FindFontFamily if the proxy is not available. |
+ if (!collection_->GetFontFamily(result.family_index, result.family_name, |
+ &family)) { |
+ DCHECK(false); |
+ return E_FAIL; |
+ } |
+ |
+ if (FAILED(family->GetFirstMatchingFont( |
+ static_cast<DWRITE_FONT_WEIGHT>(result.font_style.font_weight), |
+ static_cast<DWRITE_FONT_STRETCH>(result.font_style.font_stretch), |
+ static_cast<DWRITE_FONT_STYLE>(result.font_style.font_slant), |
+ mapped_font))) { |
+ DCHECK(false); |
+ return E_FAIL; |
+ } |
+ |
+ DCHECK(*mapped_font); |
+ |
+ return S_OK; |
+} |
+ |
+HRESULT STDMETHODCALLTYPE |
+FontFallback::RuntimeClassInitialize(DWriteFontCollectionProxy* collection, |
+ IPC::Sender* sender_override) { |
+ sender_override_ = sender_override; |
+ collection_ = collection; |
+ return S_OK; |
+} |
+ |
+} // namespace content |