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

Side by Side Diff: content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc

Issue 2204603002: Implement support for loading font files from outside system directory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2785
Patch Set: Created 4 years, 4 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 unified diff | Download patch
OLDNEW
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/child/dwrite_font_proxy/dwrite_font_proxy_win.h" 5 #include "content/child/dwrite_font_proxy/dwrite_font_proxy_win.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/debug/crash_logging.h" 12 #include "base/debug/crash_logging.h"
13 #include "base/feature_list.h" 13 #include "base/feature_list.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "base/win/scoped_handle.h" 17 #include "base/win/scoped_handle.h"
18 #include "content/child/dwrite_font_proxy/dwrite_localized_strings_win.h" 18 #include "content/child/dwrite_font_proxy/dwrite_localized_strings_win.h"
19 #include "content/common/dwrite_font_proxy_messages.h" 19 #include "content/common/dwrite_font_proxy_messages.h"
20 #include "content/public/child/child_thread.h" 20 #include "content/public/child/child_thread.h"
21 #include "ipc/ipc_platform_file.h"
21 #include "ipc/ipc_sender.h" 22 #include "ipc/ipc_sender.h"
22 23
23 namespace mswr = Microsoft::WRL; 24 namespace mswr = Microsoft::WRL;
24 25
25 namespace content { 26 namespace content {
26 27
27 namespace { 28 namespace {
28 29
29 // This enum is used to define the buckets for an enumerated UMA histogram. 30 // This enum is used to define the buckets for an enumerated UMA histogram.
30 // Hence, 31 // Hence,
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 reinterpret_cast<const uint32_t*>(collection_key); 156 reinterpret_cast<const uint32_t*>(collection_key);
156 157
157 if (*family_index >= GetFontFamilyCount()) { 158 if (*family_index >= GetFontFamilyCount()) {
158 return E_INVALIDARG; 159 return E_INVALIDARG;
159 } 160 }
160 161
161 // If we already loaded the family we should reuse the existing collection. 162 // If we already loaded the family we should reuse the existing collection.
162 DCHECK(!families_[*family_index]->IsLoaded()); 163 DCHECK(!families_[*family_index]->IsLoaded());
163 164
164 std::vector<base::string16> file_names; 165 std::vector<base::string16> file_names;
165 if (!GetSender()->Send( 166 std::vector<IPC::PlatformFileForTransit> file_handles;
166 new DWriteFontProxyMsg_GetFontFiles(*family_index, &file_names))) { 167 if (!GetSender()->Send(new DWriteFontProxyMsg_GetFontFiles(
168 *family_index, &file_names, &file_handles))) {
167 return E_FAIL; 169 return E_FAIL;
168 } 170 }
169 171
172 std::vector<HANDLE> handles;
173 file_handles.reserve(file_names.size() + file_handles.size());
174 for (const base::string16& file_name : file_names) {
175 // This leaks the handles, since they are used as the reference key to
176 // CreateStreamFromKey, and DirectWrite requires the reference keys to
177 // remain valid for the lifetime of the loader. The loader is the font
178 // collection proxy, which remains alive for the lifetime of the renderer.
179 HANDLE handle =
180 CreateFile(file_name.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
181 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
182 if (handle != INVALID_HANDLE_VALUE)
183 handles.push_back(handle);
184 }
185 for (const IPC::PlatformFileForTransit& file_handle : file_handles) {
186 handles.push_back(IPC::PlatformFileForTransitToPlatformFile(file_handle));
187 }
188
170 HRESULT hr = mswr::MakeAndInitialize<FontFileEnumerator>( 189 HRESULT hr = mswr::MakeAndInitialize<FontFileEnumerator>(
171 font_file_enumerator, factory, this, &file_names); 190 font_file_enumerator, factory, this, &handles);
172 191
173 if (!SUCCEEDED(hr)) { 192 if (!SUCCEEDED(hr)) {
174 DCHECK(false); 193 DCHECK(false);
175 return E_FAIL; 194 return E_FAIL;
176 } 195 }
177 196
178 return S_OK; 197 return S_OK;
179 } 198 }
180 199
181 HRESULT DWriteFontCollectionProxy::CreateStreamFromKey( 200 HRESULT DWriteFontCollectionProxy::CreateStreamFromKey(
182 const void* font_file_reference_key, 201 const void* font_file_reference_key,
183 UINT32 font_file_reference_key_size, 202 UINT32 font_file_reference_key_size,
184 IDWriteFontFileStream** font_file_stream) { 203 IDWriteFontFileStream** font_file_stream) {
185 if (!font_file_reference_key) { 204 if (font_file_reference_key_size != sizeof(HANDLE)) {
186 return E_FAIL;
187 }
188
189 const base::char16* file_name =
190 reinterpret_cast<const base::char16*>(font_file_reference_key);
191 DCHECK_EQ(font_file_reference_key_size % sizeof(base::char16), 0u);
192 size_t file_name_size =
193 static_cast<size_t>(font_file_reference_key_size) / sizeof(base::char16);
194
195 if (file_name_size == 0 || file_name[file_name_size - 1] != L'\0') {
196 return E_FAIL; 205 return E_FAIL;
197 } 206 }
198 207
199 TRACE_EVENT0("dwrite", "FontFileEnumerator::CreateStreamFromKey"); 208 TRACE_EVENT0("dwrite", "FontFileEnumerator::CreateStreamFromKey");
200 209
201 mswr::ComPtr<IDWriteFontFileStream> stream; 210 HANDLE file_handle =
202 if (!SUCCEEDED(mswr::MakeAndInitialize<FontFileStream>(&stream, file_name))) { 211 *reinterpret_cast<const HANDLE*>(font_file_reference_key);
212
213 if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) {
203 DCHECK(false); 214 DCHECK(false);
204 return E_FAIL; 215 return E_FAIL;
205 } 216 }
217
218 mswr::ComPtr<FontFileStream> stream;
219 if (!SUCCEEDED(
220 mswr::MakeAndInitialize<FontFileStream>(&stream, file_handle))) {
221 DCHECK(false);
222 return E_FAIL;
223 }
206 *font_file_stream = stream.Detach(); 224 *font_file_stream = stream.Detach();
207 return S_OK; 225 return S_OK;
208 } 226 }
209 227
210 HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize( 228 HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize(
211 IDWriteFactory* factory, 229 IDWriteFactory* factory,
212 IPC::Sender* sender_override) { 230 IPC::Sender* sender_override) {
213 DCHECK(factory); 231 DCHECK(factory);
214 232
215 factory_ = factory; 233 factory_ = factory;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 491
474 return SUCCEEDED(hr); 492 return SUCCEEDED(hr);
475 } 493 }
476 494
477 FontFileEnumerator::FontFileEnumerator() = default; 495 FontFileEnumerator::FontFileEnumerator() = default;
478 496
479 FontFileEnumerator::~FontFileEnumerator() = default; 497 FontFileEnumerator::~FontFileEnumerator() = default;
480 498
481 HRESULT FontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** file) { 499 HRESULT FontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** file) {
482 DCHECK(file); 500 DCHECK(file);
483 if (current_file_ >= file_names_.size()) { 501 if (current_file_ >= files_.size()) {
484 return E_FAIL; 502 return E_FAIL;
485 } 503 }
486 504
487 TRACE_EVENT0("dwrite", "FontFileEnumerator::GetCurrentFontFile"); 505 TRACE_EVENT0("dwrite", "FontFileEnumerator::GetCurrentFontFile");
506
488 // CreateCustomFontFileReference ends up calling 507 // CreateCustomFontFileReference ends up calling
489 // DWriteFontCollectionProxy::CreateStreamFromKey. 508 // DWriteFontCollectionProxy::CreateStreamFromKey.
490 HRESULT hr = factory_->CreateCustomFontFileReference( 509 HRESULT hr = factory_->CreateCustomFontFileReference(
491 reinterpret_cast<const void*>(file_names_[current_file_].c_str()), 510 reinterpret_cast<const void*>(&files_[current_file_]),
492 (file_names_[current_file_].length() + 1) * sizeof(base::char16), 511 sizeof(files_[current_file_]), loader_.Get() /*IDWriteFontFileLoader*/,
493 loader_.Get() /*IDWriteFontFileLoader*/, file); 512 file);
494 DCHECK(SUCCEEDED(hr)); 513 DCHECK(SUCCEEDED(hr));
495 return hr; 514 return hr;
496 } 515 }
497 516
498 HRESULT FontFileEnumerator::MoveNext(BOOL* has_current_file) { 517 HRESULT FontFileEnumerator::MoveNext(BOOL* has_current_file) {
499 DCHECK(has_current_file); 518 DCHECK(has_current_file);
500 519
501 TRACE_EVENT0("dwrite", "FontFileEnumerator::MoveNext"); 520 TRACE_EVENT0("dwrite", "FontFileEnumerator::MoveNext");
502 if (next_file_ >= file_names_.size()) { 521 if (next_file_ >= files_.size()) {
503 *has_current_file = FALSE; 522 *has_current_file = FALSE;
504 current_file_ = UINT_MAX; 523 current_file_ = UINT_MAX;
505 return S_OK; 524 return S_OK;
506 } 525 }
507 526
508 current_file_ = next_file_; 527 current_file_ = next_file_;
509 ++next_file_; 528 ++next_file_;
510 *has_current_file = TRUE; 529 *has_current_file = TRUE;
511 return S_OK; 530 return S_OK;
512 } 531 }
513 532
514 HRESULT FontFileEnumerator::RuntimeClassInitialize( 533 HRESULT FontFileEnumerator::RuntimeClassInitialize(
515 IDWriteFactory* factory, 534 IDWriteFactory* factory,
516 IDWriteFontFileLoader* loader, 535 IDWriteFontFileLoader* loader,
517 std::vector<base::string16>* file_names) { 536 std::vector<HANDLE>* files) {
518 factory_ = factory; 537 factory_ = factory;
519 loader_ = loader; 538 loader_ = loader;
520 file_names_.swap(*file_names); 539 files_.swap(*files);
521 file_streams_.resize(file_names_.size());
522 return S_OK; 540 return S_OK;
523 } 541 }
524 542
525 FontFileStream::FontFileStream() = default; 543 FontFileStream::FontFileStream() = default;
526 544
527 FontFileStream::~FontFileStream() = default; 545 FontFileStream::~FontFileStream() = default;
528 546
529 HRESULT FontFileStream::GetFileSize(UINT64* file_size) { 547 HRESULT FontFileStream::GetFileSize(UINT64* file_size) {
530 *file_size = data_.length(); 548 *file_size = data_.length();
531 return S_OK; 549 return S_OK;
(...skipping 10 matching lines...) Expand all
542 void** fragment_context) { 560 void** fragment_context) {
543 if (fragment_offset + fragment_size < fragment_offset) 561 if (fragment_offset + fragment_size < fragment_offset)
544 return E_FAIL; 562 return E_FAIL;
545 if (fragment_offset + fragment_size > data_.length()) 563 if (fragment_offset + fragment_size > data_.length())
546 return E_FAIL; 564 return E_FAIL;
547 *fragment_start = data_.data() + fragment_offset; 565 *fragment_start = data_.data() + fragment_offset;
548 *fragment_context = nullptr; 566 *fragment_context = nullptr;
549 return S_OK; 567 return S_OK;
550 } 568 }
551 569
552 HRESULT FontFileStream::RuntimeClassInitialize( 570 HRESULT FontFileStream::RuntimeClassInitialize(HANDLE handle) {
553 const base::string16& file_name) { 571 // Duplicate the original handle so we can reopen the file after the memory
554 data_.Initialize(base::FilePath(file_name)); 572 // mapped section closes it.
555 if (!data_.IsValid()) 573 HANDLE duplicate_handle;
574 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
575 &duplicate_handle, 0 /* dwDesiredAccess */,
576 false /* bInheritHandle */, DUPLICATE_SAME_ACCESS)) {
577 return E_FAIL;
578 }
579
580 data_.Initialize(base::File(duplicate_handle));
581 if (!data_.IsValid()) {
556 return E_FAIL; 582 return E_FAIL;
557 return S_OK; 583 return S_OK;
558 } 584 }
559 585
560 } // namespace content 586 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698