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

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

Issue 2153343002: Implement support for loading font files from outside system directory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switch command flags to use feature API instead Created 4 years, 5 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 13 matching lines...) Expand all
44 // Hence, 45 // Hence,
45 // (a) existing enumerated constants should never be deleted or reordered, and 46 // (a) existing enumerated constants should never be deleted or reordered, and
46 // (b) new constants should only be appended at the end of the enumeration. 47 // (b) new constants should only be appended at the end of the enumeration.
47 enum FontProxyError { 48 enum FontProxyError {
48 FIND_FAMILY_SEND_FAILED = 0, 49 FIND_FAMILY_SEND_FAILED = 0,
49 GET_FAMILY_COUNT_SEND_FAILED = 1, 50 GET_FAMILY_COUNT_SEND_FAILED = 1,
50 COLLECTION_KEY_INVALID = 2, 51 COLLECTION_KEY_INVALID = 2,
51 FAMILY_INDEX_OUT_OF_RANGE = 3, 52 FAMILY_INDEX_OUT_OF_RANGE = 3,
52 GET_FONT_FILES_SEND_FAILED = 4, 53 GET_FONT_FILES_SEND_FAILED = 4,
53 MAPPED_FILE_FAILED = 5, 54 MAPPED_FILE_FAILED = 5,
55 DUPLICATE_HANDLE_FAILED = 6,
54 56
55 FONT_PROXY_ERROR_MAX_VALUE 57 FONT_PROXY_ERROR_MAX_VALUE
56 }; 58 };
57 59
58 const char kFontKeyName[] = "font_key_name"; 60 const char kFontKeyName[] = "font_key_name";
59 61
60 void LogLoadFamilyResult(DirectWriteLoadFamilyResult result) { 62 void LogLoadFamilyResult(DirectWriteLoadFamilyResult result) {
61 UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoadFamilyResult", result, 63 UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoadFamilyResult", result,
62 LOAD_FAMILY_MAX_VALUE); 64 LOAD_FAMILY_MAX_VALUE);
63 } 65 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 187
186 if (*family_index >= GetFontFamilyCount()) { 188 if (*family_index >= GetFontFamilyCount()) {
187 LogFontProxyError(FAMILY_INDEX_OUT_OF_RANGE); 189 LogFontProxyError(FAMILY_INDEX_OUT_OF_RANGE);
188 return E_INVALIDARG; 190 return E_INVALIDARG;
189 } 191 }
190 192
191 // If we already loaded the family we should reuse the existing collection. 193 // If we already loaded the family we should reuse the existing collection.
192 DCHECK(!families_[*family_index]->IsLoaded()); 194 DCHECK(!families_[*family_index]->IsLoaded());
193 195
194 std::vector<base::string16> file_names; 196 std::vector<base::string16> file_names;
195 if (!GetSender()->Send( 197 std::vector<IPC::PlatformFileForTransit> file_handles;
196 new DWriteFontProxyMsg_GetFontFiles(*family_index, &file_names))) { 198 if (!GetSender()->Send(new DWriteFontProxyMsg_GetFontFiles(
199 *family_index, &file_names, &file_handles))) {
197 LogFontProxyError(GET_FONT_FILES_SEND_FAILED); 200 LogFontProxyError(GET_FONT_FILES_SEND_FAILED);
198 return E_FAIL; 201 return E_FAIL;
199 } 202 }
200 203
204 std::vector<HANDLE> handles;
205 file_handles.reserve(file_names.size() + file_handles.size());
206 for (const base::string16& file_name : file_names) {
207 // This leaks the handles, since they are used as the reference key to
208 // CreateFontFileStream, and DirectWrite requires the reference keys to
ananta 2016/07/25 22:21:39 How was this working previously. Comparing the old
Ilya Kulshin 2016/07/25 22:38:52 First, I should point out that we aren't leaking t
ananta 2016/07/25 23:08:20 Thanks. Please add some comments in the patchset a
209 // remain valid for the lifetime of the loader. The loader is the font
210 // collection proxy, which remains alive for the lifetime of the renderer.
211 HANDLE handle =
212 CreateFile(file_name.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
213 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
214 if (handle != INVALID_HANDLE_VALUE)
215 handles.push_back(handle);
216 }
217 for (const IPC::PlatformFileForTransit& file_handle : file_handles) {
218 handles.push_back(IPC::PlatformFileForTransitToPlatformFile(file_handle));
219 }
220
201 HRESULT hr = mswr::MakeAndInitialize<FontFileEnumerator>( 221 HRESULT hr = mswr::MakeAndInitialize<FontFileEnumerator>(
202 font_file_enumerator, factory, this, &file_names); 222 font_file_enumerator, factory, this, &handles);
203 223
204 if (!SUCCEEDED(hr)) { 224 if (!SUCCEEDED(hr)) {
205 DCHECK(false); 225 DCHECK(false);
206 return E_FAIL; 226 return E_FAIL;
207 } 227 }
208 228
209 return S_OK; 229 return S_OK;
210 } 230 }
211 231
212 HRESULT DWriteFontCollectionProxy::CreateStreamFromKey( 232 HRESULT DWriteFontCollectionProxy::CreateStreamFromKey(
213 const void* font_file_reference_key, 233 const void* font_file_reference_key,
214 UINT32 font_file_reference_key_size, 234 UINT32 font_file_reference_key_size,
215 IDWriteFontFileStream** font_file_stream) { 235 IDWriteFontFileStream** font_file_stream) {
216 if (!font_file_reference_key) { 236 if (font_file_reference_key_size != sizeof(HANDLE)) {
217 return E_FAIL;
218 }
219
220 const base::char16* file_name =
221 reinterpret_cast<const base::char16*>(font_file_reference_key);
222 DCHECK_EQ(font_file_reference_key_size % sizeof(base::char16), 0u);
223 size_t file_name_size =
224 static_cast<size_t>(font_file_reference_key_size) / sizeof(base::char16);
225
226 if (file_name_size == 0 || file_name[file_name_size - 1] != L'\0') {
227 return E_FAIL; 237 return E_FAIL;
228 } 238 }
229 239
230 TRACE_EVENT0("dwrite", "FontFileEnumerator::CreateStreamFromKey"); 240 TRACE_EVENT0("dwrite", "FontFileEnumerator::CreateStreamFromKey");
231 241
232 mswr::ComPtr<IDWriteFontFileStream> stream; 242 HANDLE file_handle =
233 if (!SUCCEEDED(mswr::MakeAndInitialize<FontFileStream>(&stream, file_name))) { 243 *reinterpret_cast<const HANDLE*>(font_file_reference_key);
244
245 if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) {
234 DCHECK(false); 246 DCHECK(false);
235 return E_FAIL; 247 return E_FAIL;
236 } 248 }
249
250 mswr::ComPtr<FontFileStream> stream;
251 if (!SUCCEEDED(
252 mswr::MakeAndInitialize<FontFileStream>(&stream, file_handle))) {
253 DCHECK(false);
254 return E_FAIL;
255 }
237 *font_file_stream = stream.Detach(); 256 *font_file_stream = stream.Detach();
238 return S_OK; 257 return S_OK;
239 } 258 }
240 259
241 HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize( 260 HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize(
242 IDWriteFactory* factory, 261 IDWriteFactory* factory,
243 IPC::Sender* sender_override) { 262 IPC::Sender* sender_override) {
244 DCHECK(factory); 263 DCHECK(factory);
245 264
246 factory_ = factory; 265 factory_ = factory;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 523
505 return SUCCEEDED(hr); 524 return SUCCEEDED(hr);
506 } 525 }
507 526
508 FontFileEnumerator::FontFileEnumerator() = default; 527 FontFileEnumerator::FontFileEnumerator() = default;
509 528
510 FontFileEnumerator::~FontFileEnumerator() = default; 529 FontFileEnumerator::~FontFileEnumerator() = default;
511 530
512 HRESULT FontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** file) { 531 HRESULT FontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** file) {
513 DCHECK(file); 532 DCHECK(file);
514 if (current_file_ >= file_names_.size()) { 533 if (current_file_ >= files_.size()) {
515 return E_FAIL; 534 return E_FAIL;
516 } 535 }
517 536
518 TRACE_EVENT0("dwrite", "FontFileEnumerator::GetCurrentFontFile"); 537 TRACE_EVENT0("dwrite", "FontFileEnumerator::GetCurrentFontFile");
538
519 // CreateCustomFontFileReference ends up calling 539 // CreateCustomFontFileReference ends up calling
520 // DWriteFontCollectionProxy::CreateStreamFromKey. 540 // DWriteFontCollectionProxy::CreateStreamFromKey.
521 HRESULT hr = factory_->CreateCustomFontFileReference( 541 HRESULT hr = factory_->CreateCustomFontFileReference(
522 reinterpret_cast<const void*>(file_names_[current_file_].c_str()), 542 reinterpret_cast<const void*>(&files_[current_file_]),
523 (file_names_[current_file_].length() + 1) * sizeof(base::char16), 543 sizeof(files_[current_file_]), loader_.Get() /*IDWriteFontFileLoader*/,
524 loader_.Get() /*IDWriteFontFileLoader*/, file); 544 file);
525 DCHECK(SUCCEEDED(hr)); 545 DCHECK(SUCCEEDED(hr));
526 return hr; 546 return hr;
527 } 547 }
528 548
529 HRESULT FontFileEnumerator::MoveNext(BOOL* has_current_file) { 549 HRESULT FontFileEnumerator::MoveNext(BOOL* has_current_file) {
530 DCHECK(has_current_file); 550 DCHECK(has_current_file);
531 551
532 TRACE_EVENT0("dwrite", "FontFileEnumerator::MoveNext"); 552 TRACE_EVENT0("dwrite", "FontFileEnumerator::MoveNext");
533 if (next_file_ >= file_names_.size()) { 553 if (next_file_ >= files_.size()) {
534 *has_current_file = FALSE; 554 *has_current_file = FALSE;
535 current_file_ = UINT_MAX; 555 current_file_ = UINT_MAX;
536 return S_OK; 556 return S_OK;
537 } 557 }
538 558
539 current_file_ = next_file_; 559 current_file_ = next_file_;
540 ++next_file_; 560 ++next_file_;
541 *has_current_file = TRUE; 561 *has_current_file = TRUE;
542 return S_OK; 562 return S_OK;
543 } 563 }
544 564
545 HRESULT FontFileEnumerator::RuntimeClassInitialize( 565 HRESULT FontFileEnumerator::RuntimeClassInitialize(
546 IDWriteFactory* factory, 566 IDWriteFactory* factory,
547 IDWriteFontFileLoader* loader, 567 IDWriteFontFileLoader* loader,
548 std::vector<base::string16>* file_names) { 568 std::vector<HANDLE>* files) {
549 factory_ = factory; 569 factory_ = factory;
550 loader_ = loader; 570 loader_ = loader;
551 file_names_.swap(*file_names); 571 files_.swap(*files);
552 file_streams_.resize(file_names_.size());
553 return S_OK; 572 return S_OK;
554 } 573 }
555 574
556 FontFileStream::FontFileStream() = default; 575 FontFileStream::FontFileStream() = default;
557 576
558 FontFileStream::~FontFileStream() = default; 577 FontFileStream::~FontFileStream() = default;
559 578
560 HRESULT FontFileStream::GetFileSize(UINT64* file_size) { 579 HRESULT FontFileStream::GetFileSize(UINT64* file_size) {
561 *file_size = data_.length(); 580 *file_size = data_.length();
562 return S_OK; 581 return S_OK;
(...skipping 10 matching lines...) Expand all
573 void** fragment_context) { 592 void** fragment_context) {
574 if (fragment_offset + fragment_size < fragment_offset) 593 if (fragment_offset + fragment_size < fragment_offset)
575 return E_FAIL; 594 return E_FAIL;
576 if (fragment_offset + fragment_size > data_.length()) 595 if (fragment_offset + fragment_size > data_.length())
577 return E_FAIL; 596 return E_FAIL;
578 *fragment_start = data_.data() + fragment_offset; 597 *fragment_start = data_.data() + fragment_offset;
579 *fragment_context = nullptr; 598 *fragment_context = nullptr;
580 return S_OK; 599 return S_OK;
581 } 600 }
582 601
583 HRESULT FontFileStream::RuntimeClassInitialize( 602 HRESULT FontFileStream::RuntimeClassInitialize(HANDLE handle) {
584 const base::string16& file_name) { 603 // Duplicate the original handle so we can reopen the file after the memory
585 data_.Initialize(base::FilePath(file_name)); 604 // mapped section closes it.
605 HANDLE duplicate_handle;
606 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
607 &duplicate_handle, 0 /* dwDesiredAccess */,
608 false /* bInheritHandle */, DUPLICATE_SAME_ACCESS)) {
609 LogFontProxyError(DUPLICATE_HANDLE_FAILED);
610 return E_FAIL;
611 }
612
613 data_.Initialize(base::File(duplicate_handle));
586 if (!data_.IsValid()) { 614 if (!data_.IsValid()) {
587 LogFontProxyError(MAPPED_FILE_FAILED); 615 LogFontProxyError(MAPPED_FILE_FAILED);
588 return E_FAIL; 616 return E_FAIL;
589 } 617 }
590 return S_OK; 618 return S_OK;
591 } 619 }
592 620
593 } // namespace content 621 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698