OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h" | 5 #include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h" |
6 | 6 |
7 #include <dwrite.h> | 7 #include <dwrite.h> |
8 #include <shlobj.h> | 8 #include <shlobj.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <stdint.h> | 10 #include <stdint.h> |
11 | 11 |
12 #include <set> | 12 #include <set> |
13 #include <utility> | 13 #include <utility> |
14 | 14 |
15 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
16 #include "base/i18n/case_conversion.h" | 16 #include "base/i18n/case_conversion.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
19 #include "base/strings/string16.h" | 19 #include "base/strings/string16.h" |
20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
22 #include "content/common/dwrite_font_proxy_messages.h" | 22 #include "content/common/dwrite_font_proxy_messages.h" |
| 23 #include "content/common/dwrite_text_analysis_source_win.h" |
23 #include "ipc/ipc_message_macros.h" | 24 #include "ipc/ipc_message_macros.h" |
24 #include "ui/gfx/win/direct_write.h" | 25 #include "ui/gfx/win/direct_write.h" |
25 | 26 |
26 namespace mswr = Microsoft::WRL; | 27 namespace mswr = Microsoft::WRL; |
27 | 28 |
28 namespace content { | 29 namespace content { |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
32 // This enum is used to define the buckets for an enumerated UMA histogram. | 33 // This enum is used to define the buckets for an enumerated UMA histogram. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 DWriteFontProxyMessageFilter::~DWriteFontProxyMessageFilter() = default; | 84 DWriteFontProxyMessageFilter::~DWriteFontProxyMessageFilter() = default; |
84 | 85 |
85 bool DWriteFontProxyMessageFilter::OnMessageReceived( | 86 bool DWriteFontProxyMessageFilter::OnMessageReceived( |
86 const IPC::Message& message) { | 87 const IPC::Message& message) { |
87 bool handled = true; | 88 bool handled = true; |
88 IPC_BEGIN_MESSAGE_MAP(DWriteFontProxyMessageFilter, message) | 89 IPC_BEGIN_MESSAGE_MAP(DWriteFontProxyMessageFilter, message) |
89 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_FindFamily, OnFindFamily) | 90 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_FindFamily, OnFindFamily) |
90 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyCount, OnGetFamilyCount) | 91 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyCount, OnGetFamilyCount) |
91 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyNames, OnGetFamilyNames) | 92 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyNames, OnGetFamilyNames) |
92 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFontFiles, OnGetFontFiles) | 93 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFontFiles, OnGetFontFiles) |
| 94 IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_MapCharacters, OnMapCharacters) |
93 IPC_MESSAGE_UNHANDLED(handled = false) | 95 IPC_MESSAGE_UNHANDLED(handled = false) |
94 IPC_END_MESSAGE_MAP() | 96 IPC_END_MESSAGE_MAP() |
95 return handled; | 97 return handled; |
96 } | 98 } |
97 | 99 |
98 void DWriteFontProxyMessageFilter::OverrideThreadForMessage( | 100 void DWriteFontProxyMessageFilter::OverrideThreadForMessage( |
99 const IPC::Message& message, | 101 const IPC::Message& message, |
100 content::BrowserThread::ID* thread) { | 102 content::BrowserThread::ID* thread) { |
101 if (IPC_MESSAGE_CLASS(message) == DWriteFontProxyMsgStart) | 103 if (IPC_MESSAGE_CLASS(message) == DWriteFontProxyMsgStart) |
102 *thread = BrowserThread::FILE; | 104 *thread = BrowserThread::FILE; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 InitializeDirectWrite(); | 137 InitializeDirectWrite(); |
136 TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyNames"); | 138 TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyNames"); |
137 DCHECK(collection_); | 139 DCHECK(collection_); |
138 if (!collection_) | 140 if (!collection_) |
139 return; | 141 return; |
140 | 142 |
141 TRACE_EVENT0("dwrite", "FontProxyHost::DoGetFamilyNames"); | 143 TRACE_EVENT0("dwrite", "FontProxyHost::DoGetFamilyNames"); |
142 | 144 |
143 mswr::ComPtr<IDWriteFontFamily> family; | 145 mswr::ComPtr<IDWriteFontFamily> family; |
144 HRESULT hr = collection_->GetFontFamily(family_index, &family); | 146 HRESULT hr = collection_->GetFontFamily(family_index, &family); |
145 if (!SUCCEEDED(hr)) { | 147 if (FAILED(hr)) { |
146 return; | 148 return; |
147 } | 149 } |
148 | 150 |
149 mswr::ComPtr<IDWriteLocalizedStrings> localized_names; | 151 mswr::ComPtr<IDWriteLocalizedStrings> localized_names; |
150 hr = family->GetFamilyNames(&localized_names); | 152 hr = family->GetFamilyNames(&localized_names); |
151 if (!SUCCEEDED(hr)) { | 153 if (FAILED(hr)) { |
152 return; | 154 return; |
153 } | 155 } |
154 | 156 |
155 size_t string_count = localized_names->GetCount(); | 157 size_t string_count = localized_names->GetCount(); |
156 | 158 |
157 std::vector<base::char16> locale; | 159 std::vector<base::char16> locale; |
158 std::vector<base::char16> name; | 160 std::vector<base::char16> name; |
159 for (size_t index = 0; index < string_count; ++index) { | 161 for (size_t index = 0; index < string_count; ++index) { |
160 UINT32 length = 0; | 162 UINT32 length = 0; |
161 hr = localized_names->GetLocaleNameLength(index, &length); | 163 hr = localized_names->GetLocaleNameLength(index, &length); |
162 if (!SUCCEEDED(hr)) { | 164 if (FAILED(hr)) { |
163 return; | 165 return; |
164 } | 166 } |
165 ++length; // Reserve space for the null terminator. | 167 ++length; // Reserve space for the null terminator. |
166 locale.resize(length); | 168 locale.resize(length); |
167 hr = localized_names->GetLocaleName(index, locale.data(), length); | 169 hr = localized_names->GetLocaleName(index, locale.data(), length); |
168 if (!SUCCEEDED(hr)) { | 170 if (FAILED(hr)) { |
169 return; | 171 return; |
170 } | 172 } |
171 CHECK_EQ(L'\0', locale[length - 1]); | 173 CHECK_EQ(L'\0', locale[length - 1]); |
172 | 174 |
173 length = 0; | 175 length = 0; |
174 hr = localized_names->GetStringLength(index, &length); | 176 hr = localized_names->GetStringLength(index, &length); |
175 if (!SUCCEEDED(hr)) { | 177 if (FAILED(hr)) { |
176 return; | 178 return; |
177 } | 179 } |
178 ++length; // Reserve space for the null terminator. | 180 ++length; // Reserve space for the null terminator. |
179 name.resize(length); | 181 name.resize(length); |
180 hr = localized_names->GetString(index, name.data(), length); | 182 hr = localized_names->GetString(index, name.data(), length); |
181 if (!SUCCEEDED(hr)) { | 183 if (FAILED(hr)) { |
182 return; | 184 return; |
183 } | 185 } |
184 CHECK_EQ(L'\0', name[length - 1]); | 186 CHECK_EQ(L'\0', name[length - 1]); |
185 | 187 |
186 // Would be great to use emplace_back instead. | 188 // Would be great to use emplace_back instead. |
187 family_names->push_back(std::pair<base::string16, base::string16>( | 189 family_names->push_back(std::pair<base::string16, base::string16>( |
188 base::string16(locale.data()), base::string16(name.data()))); | 190 base::string16(locale.data()), base::string16(name.data()))); |
189 } | 191 } |
190 } | 192 } |
191 | 193 |
192 void DWriteFontProxyMessageFilter::OnGetFontFiles( | 194 void DWriteFontProxyMessageFilter::OnGetFontFiles( |
193 uint32_t family_index, | 195 uint32_t family_index, |
194 std::vector<base::string16>* file_paths) { | 196 std::vector<base::string16>* file_paths) { |
195 InitializeDirectWrite(); | 197 InitializeDirectWrite(); |
196 TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFontFiles"); | 198 TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFontFiles"); |
197 DCHECK(collection_); | 199 DCHECK(collection_); |
198 if (!collection_) | 200 if (!collection_) |
199 return; | 201 return; |
200 | 202 |
201 mswr::ComPtr<IDWriteFontFamily> family; | 203 mswr::ComPtr<IDWriteFontFamily> family; |
202 HRESULT hr = collection_->GetFontFamily(family_index, &family); | 204 HRESULT hr = collection_->GetFontFamily(family_index, &family); |
203 if (!SUCCEEDED(hr)) { | 205 if (FAILED(hr)) { |
204 return; | 206 return; |
205 } | 207 } |
206 | 208 |
207 UINT32 font_count = family->GetFontCount(); | 209 UINT32 font_count = family->GetFontCount(); |
208 | 210 |
209 std::set<base::string16> path_set; | 211 std::set<base::string16> path_set; |
210 // Iterate through all the fonts in the family, and all the files for those | 212 // Iterate through all the fonts in the family, and all the files for those |
211 // fonts. If anything goes wrong, bail on the entire family to avoid having | 213 // fonts. If anything goes wrong, bail on the entire family to avoid having |
212 // a partially-loaded font family. | 214 // a partially-loaded font family. |
213 for (UINT32 font_index = 0; font_index < font_count; ++font_index) { | 215 for (UINT32 font_index = 0; font_index < font_count; ++font_index) { |
214 mswr::ComPtr<IDWriteFont> font; | 216 mswr::ComPtr<IDWriteFont> font; |
215 hr = family->GetFont(font_index, &font); | 217 hr = family->GetFont(font_index, &font); |
216 if (!SUCCEEDED(hr)) { | 218 if (FAILED(hr)) { |
217 return; | 219 return; |
218 } | 220 } |
219 | 221 |
220 AddFilesForFont(&path_set, font.Get()); | 222 AddFilesForFont(&path_set, font.Get()); |
221 } | 223 } |
222 | 224 |
223 file_paths->assign(path_set.begin(), path_set.end()); | 225 file_paths->assign(path_set.begin(), path_set.end()); |
224 } | 226 } |
225 | 227 |
| 228 void DWriteFontProxyMessageFilter::OnMapCharacters( |
| 229 const base::string16& text, |
| 230 const DWriteFontStyle& font_style, |
| 231 const base::string16& locale_name, |
| 232 uint32_t reading_direction, |
| 233 const base::string16& base_family_name, |
| 234 MapCharactersResult* result) { |
| 235 InitializeDirectWrite(); |
| 236 result->family_index = UINT32_MAX; |
| 237 result->mapped_length = text.length(); |
| 238 result->family_name.clear(); |
| 239 result->scale = 0.0; |
| 240 result->font_style.font_slant = DWRITE_FONT_STYLE_NORMAL; |
| 241 result->font_style.font_stretch = DWRITE_FONT_STRETCH_NORMAL; |
| 242 result->font_style.font_weight = DWRITE_FONT_WEIGHT_NORMAL; |
| 243 if (factory2_ == nullptr || collection_ == nullptr) |
| 244 return; |
| 245 if (font_fallback_ == nullptr) { |
| 246 if (FAILED(factory2_->GetSystemFontFallback(&font_fallback_))) |
| 247 return; |
| 248 } |
| 249 |
| 250 UINT32 length; |
| 251 mswr::ComPtr<IDWriteFont> mapped_font; |
| 252 |
| 253 mswr::ComPtr<IDWriteNumberSubstitution> number_substitution; |
| 254 if (FAILED(factory2_->CreateNumberSubstitution( |
| 255 DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, locale_name.c_str(), |
| 256 TRUE /* ignoreUserOverride */, &number_substitution))) { |
| 257 DCHECK(false); |
| 258 return; |
| 259 } |
| 260 mswr::ComPtr<IDWriteTextAnalysisSource> analysis_source; |
| 261 if (FAILED(mswr::MakeAndInitialize<TextAnalysisSource>( |
| 262 &analysis_source, text, locale_name, number_substitution.Get(), |
| 263 static_cast<DWRITE_READING_DIRECTION>(reading_direction)))) { |
| 264 DCHECK(false); |
| 265 return; |
| 266 } |
| 267 |
| 268 if (FAILED(font_fallback_->MapCharacters( |
| 269 analysis_source.Get(), 0, text.length(), collection_.Get(), |
| 270 base_family_name.c_str(), |
| 271 static_cast<DWRITE_FONT_WEIGHT>(font_style.font_weight), |
| 272 static_cast<DWRITE_FONT_STYLE>(font_style.font_slant), |
| 273 static_cast<DWRITE_FONT_STRETCH>(font_style.font_stretch), &length, |
| 274 &mapped_font, &result->scale))) { |
| 275 DCHECK(false); |
| 276 return; |
| 277 } |
| 278 |
| 279 result->mapped_length = length; |
| 280 if (mapped_font == nullptr) |
| 281 return; |
| 282 |
| 283 mswr::ComPtr<IDWriteFontFamily> mapped_family; |
| 284 if (FAILED(mapped_font->GetFontFamily(&mapped_family))) { |
| 285 DCHECK(false); |
| 286 return; |
| 287 } |
| 288 mswr::ComPtr<IDWriteLocalizedStrings> family_names; |
| 289 if (FAILED(mapped_family->GetFamilyNames(&family_names))) { |
| 290 DCHECK(false); |
| 291 return; |
| 292 } |
| 293 |
| 294 result->font_style.font_slant = mapped_font->GetStyle(); |
| 295 result->font_style.font_stretch = mapped_font->GetStretch(); |
| 296 result->font_style.font_weight = mapped_font->GetWeight(); |
| 297 |
| 298 std::vector<base::char16> name; |
| 299 size_t name_count = family_names->GetCount(); |
| 300 for (size_t name_index = 0; name_index < name_count; name_index++) { |
| 301 UINT32 name_length = 0; |
| 302 if (FAILED(family_names->GetStringLength(name_index, &name_length))) |
| 303 continue; // Keep trying other names |
| 304 |
| 305 ++name_length; // Reserve space for the null terminator. |
| 306 name.resize(name_length); |
| 307 if (FAILED(family_names->GetString(name_index, name.data(), name_length))) |
| 308 continue; |
| 309 UINT32 index = UINT32_MAX; |
| 310 BOOL exists = false; |
| 311 if (FAILED(collection_->FindFamilyName(name.data(), &index, &exists)) || |
| 312 !exists) |
| 313 continue; |
| 314 |
| 315 // Found a matching family! |
| 316 result->family_index = index; |
| 317 result->family_name = name.data(); |
| 318 return; |
| 319 } |
| 320 // Could not find a matching family |
| 321 // TODO(kulshin): log UMA that we matched a font, but could not locate the |
| 322 // family |
| 323 DCHECK_EQ(result->family_index, UINT32_MAX); |
| 324 DCHECK_GT(result->mapped_length, 0u); |
| 325 } |
| 326 |
226 void DWriteFontProxyMessageFilter::InitializeDirectWrite() { | 327 void DWriteFontProxyMessageFilter::InitializeDirectWrite() { |
227 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 328 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
228 if (direct_write_initialized_) | 329 if (direct_write_initialized_) |
229 return; | 330 return; |
230 direct_write_initialized_ = true; | 331 direct_write_initialized_ = true; |
231 | 332 |
232 mswr::ComPtr<IDWriteFactory> factory; | 333 mswr::ComPtr<IDWriteFactory> factory; |
233 gfx::win::CreateDWriteFactory(&factory); | 334 gfx::win::CreateDWriteFactory(&factory); |
234 if (factory == nullptr) { | 335 if (factory == nullptr) { |
235 // We won't be able to load fonts, but we should still return messages so | 336 // We won't be able to load fonts, but we should still return messages so |
236 // renderers don't hang if they for some reason send us a font message. | 337 // renderers don't hang if they for some reason send us a font message. |
237 return; | 338 return; |
238 } | 339 } |
239 | 340 |
| 341 // QueryInterface for IDWriteFactory2. It's ok for this to fail if we are |
| 342 // running an older version of DirectWrite (earlier than Win8.1). |
| 343 factory.As<IDWriteFactory2>(&factory2_); |
| 344 |
240 HRESULT hr = factory->GetSystemFontCollection(&collection_); | 345 HRESULT hr = factory->GetSystemFontCollection(&collection_); |
241 DCHECK(SUCCEEDED(hr)); | 346 DCHECK(SUCCEEDED(hr)); |
242 } | 347 } |
243 | 348 |
244 bool DWriteFontProxyMessageFilter::AddFilesForFont( | 349 bool DWriteFontProxyMessageFilter::AddFilesForFont( |
245 std::set<base::string16>* path_set, | 350 std::set<base::string16>* path_set, |
246 IDWriteFont* font) { | 351 IDWriteFont* font) { |
247 mswr::ComPtr<IDWriteFontFace> font_face; | 352 mswr::ComPtr<IDWriteFontFace> font_face; |
248 HRESULT hr; | 353 HRESULT hr; |
249 hr = font->CreateFontFace(&font_face); | 354 hr = font->CreateFontFace(&font_face); |
250 if (!SUCCEEDED(hr)) { | 355 if (FAILED(hr)) { |
251 return false; | 356 return false; |
252 } | 357 } |
253 | 358 |
254 UINT32 file_count; | 359 UINT32 file_count; |
255 hr = font_face->GetFiles(&file_count, nullptr); | 360 hr = font_face->GetFiles(&file_count, nullptr); |
256 if (!SUCCEEDED(hr)) { | 361 if (FAILED(hr)) { |
257 return false; | 362 return false; |
258 } | 363 } |
259 | 364 |
260 std::vector<mswr::ComPtr<IDWriteFontFile>> font_files; | 365 std::vector<mswr::ComPtr<IDWriteFontFile>> font_files; |
261 font_files.resize(file_count); | 366 font_files.resize(file_count); |
262 hr = font_face->GetFiles( | 367 hr = font_face->GetFiles( |
263 &file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data())); | 368 &file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data())); |
264 if (!SUCCEEDED(hr)) { | 369 if (FAILED(hr)) { |
265 return false; | 370 return false; |
266 } | 371 } |
267 | 372 |
268 for (unsigned int file_index = 0; file_index < file_count; ++file_index) { | 373 for (unsigned int file_index = 0; file_index < file_count; ++file_index) { |
269 mswr::ComPtr<IDWriteFontFileLoader> loader; | 374 mswr::ComPtr<IDWriteFontFileLoader> loader; |
270 hr = font_files[file_index]->GetLoader(&loader); | 375 hr = font_files[file_index]->GetLoader(&loader); |
271 if (!SUCCEEDED(hr)) { | 376 if (FAILED(hr)) { |
272 return false; | 377 return false; |
273 } | 378 } |
274 | 379 |
275 mswr::ComPtr<IDWriteLocalFontFileLoader> local_loader; | 380 mswr::ComPtr<IDWriteLocalFontFileLoader> local_loader; |
276 hr = loader.CopyTo(local_loader.GetAddressOf()); // QueryInterface. | 381 hr = loader.CopyTo(local_loader.GetAddressOf()); // QueryInterface. |
277 | 382 |
278 if (hr == E_NOINTERFACE) { | 383 if (hr == E_NOINTERFACE) { |
279 // We could get here if the system font collection contains fonts that | 384 // We could get here if the system font collection contains fonts that |
280 // are backed by something other than files in the system fonts folder. | 385 // are backed by something other than files in the system fonts folder. |
281 // I don't think that is actually possible, so for now we'll just | 386 // I don't think that is actually possible, so for now we'll just |
282 // ignore it (result will be that we'll be unable to match any styles | 387 // ignore it (result will be that we'll be unable to match any styles |
283 // for this font, forcing blink/skia to fall back to whatever font is | 388 // for this font, forcing blink/skia to fall back to whatever font is |
284 // next). If we get telemetry indicating that this case actually | 389 // next). If we get telemetry indicating that this case actually |
285 // happens, we can implement this by exposing the loader via ipc. That | 390 // happens, we can implement this by exposing the loader via ipc. That |
286 // will likely be by loading the font data into shared memory, although | 391 // will likely be by loading the font data into shared memory, although |
287 // we could proxy the stream reads directly instead. | 392 // we could proxy the stream reads directly instead. |
288 LogLoaderType(OTHER_LOADER); | 393 LogLoaderType(OTHER_LOADER); |
289 DCHECK(false); | 394 DCHECK(false); |
290 | 395 |
291 return false; | 396 return false; |
292 } else if (!SUCCEEDED(hr)) { | 397 } else if (FAILED(hr)) { |
293 return false; | 398 return false; |
294 } | 399 } |
295 | 400 |
296 if (!AddLocalFile(path_set, local_loader.Get(), | 401 if (!AddLocalFile(path_set, local_loader.Get(), |
297 font_files[file_index].Get())) { | 402 font_files[file_index].Get())) { |
298 return false; | 403 return false; |
299 } | 404 } |
300 } | 405 } |
301 return true; | 406 return true; |
302 } | 407 } |
303 | 408 |
304 bool DWriteFontProxyMessageFilter::AddLocalFile( | 409 bool DWriteFontProxyMessageFilter::AddLocalFile( |
305 std::set<base::string16>* path_set, | 410 std::set<base::string16>* path_set, |
306 IDWriteLocalFontFileLoader* local_loader, | 411 IDWriteLocalFontFileLoader* local_loader, |
307 IDWriteFontFile* font_file) { | 412 IDWriteFontFile* font_file) { |
308 HRESULT hr; | 413 HRESULT hr; |
309 const void* key; | 414 const void* key; |
310 UINT32 key_size; | 415 UINT32 key_size; |
311 hr = font_file->GetReferenceKey(&key, &key_size); | 416 hr = font_file->GetReferenceKey(&key, &key_size); |
312 if (!SUCCEEDED(hr)) { | 417 if (FAILED(hr)) { |
313 return false; | 418 return false; |
314 } | 419 } |
315 | 420 |
316 UINT32 path_length = 0; | 421 UINT32 path_length = 0; |
317 hr = local_loader->GetFilePathLengthFromKey(key, key_size, &path_length); | 422 hr = local_loader->GetFilePathLengthFromKey(key, key_size, &path_length); |
318 if (!SUCCEEDED(hr)) { | 423 if (FAILED(hr)) { |
319 return false; | 424 return false; |
320 } | 425 } |
321 ++path_length; // Reserve space for the null terminator. | 426 ++path_length; // Reserve space for the null terminator. |
322 std::vector<base::char16> file_path_chars; | 427 std::vector<base::char16> file_path_chars; |
323 file_path_chars.resize(path_length); | 428 file_path_chars.resize(path_length); |
324 hr = local_loader->GetFilePathFromKey(key, key_size, file_path_chars.data(), | 429 hr = local_loader->GetFilePathFromKey(key, key_size, file_path_chars.data(), |
325 path_length); | 430 path_length); |
326 if (!SUCCEEDED(hr)) { | 431 if (FAILED(hr)) { |
327 return false; | 432 return false; |
328 } | 433 } |
329 | 434 |
330 base::string16 file_path = base::i18n::FoldCase(file_path_chars.data()); | 435 base::string16 file_path = base::i18n::FoldCase(file_path_chars.data()); |
331 if (!base::StartsWith(file_path, windows_fonts_path_, | 436 if (!base::StartsWith(file_path, windows_fonts_path_, |
332 base::CompareCase::SENSITIVE)) { | 437 base::CompareCase::SENSITIVE)) { |
333 // Skip loading fonts from outside the system fonts directory, since | 438 // Skip loading fonts from outside the system fonts directory, since |
334 // these families will not be accessible to the renderer process. If | 439 // these families will not be accessible to the renderer process. If |
335 // this turns out to be a common case, we can either grant the renderer | 440 // this turns out to be a common case, we can either grant the renderer |
336 // access to these files (not sure if this is actually possible), or | 441 // access to these files (not sure if this is actually possible), or |
(...skipping 23 matching lines...) Expand all Loading... |
360 return true; | 465 return true; |
361 } | 466 } |
362 } | 467 } |
363 | 468 |
364 LogLoaderType(FILE_SYSTEM_FONT_DIR); | 469 LogLoaderType(FILE_SYSTEM_FONT_DIR); |
365 path_set->insert(file_path); | 470 path_set->insert(file_path); |
366 return true; | 471 return true; |
367 } | 472 } |
368 | 473 |
369 } // namespace content | 474 } // namespace content |
OLD | NEW |