OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/child/dwrite_font_proxy/font_fallback_win.h" |
| 6 |
| 7 #include "base/strings/string16.h" |
| 8 |
| 9 #include "content/child/dwrite_font_proxy/dwrite_font_proxy_win.h" |
| 10 #include "content/common/dwrite_font_proxy_messages.h" |
| 11 #include "content/public/child/child_thread.h" |
| 12 #include "ipc/ipc_sender.h" |
| 13 |
| 14 namespace mswr = Microsoft::WRL; |
| 15 |
| 16 namespace content { |
| 17 |
| 18 FontFallback::FontFallback() = default; |
| 19 FontFallback::~FontFallback() = default; |
| 20 |
| 21 HRESULT FontFallback::MapCharacters(IDWriteTextAnalysisSource* source, |
| 22 UINT32 text_position, |
| 23 UINT32 text_length, |
| 24 IDWriteFontCollection* base_font_collection, |
| 25 const wchar_t* base_family_name, |
| 26 DWRITE_FONT_WEIGHT base_weight, |
| 27 DWRITE_FONT_STYLE base_style, |
| 28 DWRITE_FONT_STRETCH base_stretch, |
| 29 UINT32* mapped_length, |
| 30 IDWriteFont** mapped_font, |
| 31 FLOAT* scale) { |
| 32 *mapped_font = nullptr; |
| 33 *mapped_length = 1; |
| 34 *scale = 1.0; |
| 35 |
| 36 const WCHAR* text = nullptr; |
| 37 UINT32 chunk_length = 0; |
| 38 if (FAILED(source->GetTextAtPosition(text_position, &text, &chunk_length))) { |
| 39 DCHECK(false); |
| 40 return E_FAIL; |
| 41 } |
| 42 base::string16 text_chunk(text, chunk_length); |
| 43 |
| 44 const WCHAR* locale = nullptr; |
| 45 // |locale_text_length| is actually the length of text with the locale, not |
| 46 // the length of the locale string itself. |
| 47 UINT32 locale_text_length = 0; |
| 48 source->GetLocaleName(text_position /*textPosition*/, &locale_text_length, |
| 49 &locale); |
| 50 |
| 51 if (locale == nullptr) |
| 52 locale = L""; |
| 53 |
| 54 DWriteFontStyle style; |
| 55 style.font_weight = base_weight; |
| 56 style.font_slant = base_style; |
| 57 style.font_stretch = base_stretch; |
| 58 |
| 59 MapCharactersResult result; |
| 60 |
| 61 IPC::Sender* sender = |
| 62 sender_override_ ? sender_override_ : ChildThread::Get(); |
| 63 if (!sender->Send(new DWriteFontProxyMsg_MapCharacters( |
| 64 text_chunk, style, locale, source->GetParagraphReadingDirection(), |
| 65 base_family_name ? base_family_name : L"", &result))) |
| 66 return E_FAIL; |
| 67 |
| 68 *mapped_length = result.mapped_length; |
| 69 *scale = result.scale; |
| 70 |
| 71 if (result.family_index == UINT32_MAX) |
| 72 return S_OK; |
| 73 |
| 74 mswr::ComPtr<IDWriteFontFamily> family; |
| 75 // It would be nice to find a way to determine at runtime if |collection_| is |
| 76 // a proxy collection, or just a generic IDWriteFontCollection. Unfortunately |
| 77 // I can't find a way to get QueryInterface to return the actual class when |
| 78 // using mswr::RuntimeClass. If we could use QI, we can fallback on |
| 79 // FindFontFamily if the proxy is not available. |
| 80 if (!collection_->GetFontFamily(result.family_index, result.family_name, |
| 81 &family)) { |
| 82 DCHECK(false); |
| 83 return E_FAIL; |
| 84 } |
| 85 |
| 86 if (FAILED(family->GetFirstMatchingFont( |
| 87 static_cast<DWRITE_FONT_WEIGHT>(result.font_style.font_weight), |
| 88 static_cast<DWRITE_FONT_STRETCH>(result.font_style.font_stretch), |
| 89 static_cast<DWRITE_FONT_STYLE>(result.font_style.font_slant), |
| 90 mapped_font))) { |
| 91 DCHECK(false); |
| 92 return E_FAIL; |
| 93 } |
| 94 |
| 95 DCHECK(*mapped_font); |
| 96 |
| 97 return S_OK; |
| 98 } |
| 99 |
| 100 HRESULT STDMETHODCALLTYPE |
| 101 FontFallback::RuntimeClassInitialize(DWriteFontCollectionProxy* collection, |
| 102 IPC::Sender* sender_override) { |
| 103 sender_override_ = sender_override; |
| 104 collection_ = collection; |
| 105 return S_OK; |
| 106 } |
| 107 |
| 108 } // namespace content |
OLD | NEW |