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

Side by Side Diff: chrome/browser/printing/pdf_to_emf_converter.cc

Issue 2477283002: Convert printing IPCs to Mojo
Patch Set: Fix more Windows compile errors Created 3 years, 11 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/printing/pdf_to_emf_converter.h" 5 #include "chrome/browser/printing/pdf_to_emf_converter.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <windows.h> 8 #include <windows.h>
9 9
10 #include <memory> 10 #include <memory>
11 #include <queue> 11 #include <queue>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/callback_helpers.h"
15 #include "base/files/file.h" 16 #include "base/files/file.h"
16 #include "base/files/file_util.h" 17 #include "base/files/file_util.h"
17 #include "base/files/scoped_temp_dir.h" 18 #include "base/files/scoped_temp_dir.h"
18 #include "base/logging.h" 19 #include "base/logging.h"
19 #include "base/macros.h" 20 #include "base/macros.h"
20 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
21 #include "base/threading/thread_task_runner_handle.h" 22 #include "base/threading/thread_task_runner_handle.h"
22 #include "chrome/common/chrome_utility_messages.h" 23 #include "chrome/common/chrome_utility_messages.h"
23 #include "chrome/common/chrome_utility_printing_messages.h"
24 #include "chrome/grit/generated_resources.h" 24 #include "chrome/grit/generated_resources.h"
25 #include "components/printing/common/printing.mojom.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/child_process_data.h" 27 #include "content/public/browser/child_process_data.h"
27 #include "content/public/browser/utility_process_host.h" 28 #include "content/public/browser/utility_process_mojo_client.h"
28 #include "content/public/browser/utility_process_host_client.h" 29 #include "mojo/public/cpp/bindings/strong_binding.h"
29 #include "printing/emf_win.h" 30 #include "printing/emf_win.h"
30 #include "printing/pdf_render_settings.h" 31 #include "printing/pdf_render_settings.h"
32 #include "services/service_manager/public/cpp/interface_provider.h"
31 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
32 34
33 namespace printing { 35 namespace printing {
34 36
35 namespace { 37 namespace {
36 38
37 using content::BrowserThread; 39 using content::BrowserThread;
38 40
39 class PdfToEmfConverterImpl; 41 class PdfToEmfConverterImpl;
40 42
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 void Close() const; 84 void Close() const;
83 bool LoadEmf(Emf* emf) const; 85 bool LoadEmf(Emf* emf) const;
84 86
85 mutable scoped_refptr<RefCountedTempDir> temp_dir_; 87 mutable scoped_refptr<RefCountedTempDir> temp_dir_;
86 mutable ScopedTempFile file_; // Mutable because of consts in base class. 88 mutable ScopedTempFile file_; // Mutable because of consts in base class.
87 89
88 DISALLOW_COPY_AND_ASSIGN(LazyEmf); 90 DISALLOW_COPY_AND_ASSIGN(LazyEmf);
89 }; 91 };
90 92
91 // Converts PDF into EMF. 93 // Converts PDF into EMF.
92 // Class uses 3 threads: UI, IO and FILE. 94 // Class uses 2 threads: UI and FILE.
93 // Internal workflow is following: 95 // Internal workflow is following:
94 // 1. Create instance on the UI thread. (files_, settings_,) 96 // 1. Create instance on the UI thread. (files_, settings_,)
95 // 2. Create pdf file on the FILE thread. 97 // 2. Create pdf file on the FILE thread.
96 // 3. Start utility process and start conversion on the IO thread. 98 // 3. Start utility process and start conversion on the UI thread.
97 // 4. Utility process returns page count. 99 // 4. Utility process returns page count.
98 // 5. For each page: 100 // 5. For each page:
99 // 1. Clients requests page with file handle to a temp file. 101 // 1. Clients requests page with file handle to a temp file.
100 // 2. Utility converts the page, save it to the file and reply. 102 // 2. Utility converts the page, save it to the file and reply.
101 // 103 //
102 // All these steps work sequentially, so no data should be accessed 104 // All these steps work sequentially, so no data should be accessed
103 // simultaneously by several threads. 105 // simultaneously by several threads.
104 class PdfToEmfUtilityProcessHostClient 106 class PdfToEmfUtilityProcessHostClient
105 : public content::UtilityProcessHostClient { 107 : public base::RefCountedThreadSafe<PdfToEmfUtilityProcessHostClient> {
106 public: 108 public:
107 PdfToEmfUtilityProcessHostClient( 109 PdfToEmfUtilityProcessHostClient(
108 base::WeakPtr<PdfToEmfConverterImpl> converter, 110 base::WeakPtr<PdfToEmfConverterImpl> converter,
109 const PdfRenderSettings& settings); 111 const PdfRenderSettings& settings);
110 112
111 void Start(const scoped_refptr<base::RefCountedMemory>& data, 113 void Start(const scoped_refptr<base::RefCountedMemory>& data,
112 bool print_text_with_gdi, 114 bool print_text_with_gdi,
113 const PdfToEmfConverter::StartCallback& start_callback); 115 const PdfToEmfConverter::StartCallback& start_callback);
114 116
115 void GetPage(int page_number, 117 void GetPage(int page_number,
116 const PdfToEmfConverter::GetPageCallback& get_page_callback); 118 const PdfToEmfConverter::GetPageCallback& get_page_callback);
117 119
118 void Stop(); 120 void Stop();
119 121
120 // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
121 // sync message replies.
122 bool Send(IPC::Message* msg);
123
124 // UtilityProcessHostClient implementation.
125 void OnProcessCrashed(int exit_code) override;
126 void OnProcessLaunchFailed(int exit_code) override;
127 bool OnMessageReceived(const IPC::Message& message) override;
128
129 private: 122 private:
130 class GetPageCallbackData { 123 class GetPageCallbackData {
131 public: 124 public:
132 GetPageCallbackData(int page_number, 125 GetPageCallbackData(int page_number,
133 PdfToEmfConverter::GetPageCallback callback) 126 PdfToEmfConverter::GetPageCallback callback)
134 : page_number_(page_number), callback_(callback) {} 127 : page_number_(page_number), callback_(callback) {}
135 128
136 GetPageCallbackData(GetPageCallbackData&& other) { 129 GetPageCallbackData(GetPageCallbackData&& other) {
137 *this = std::move(other); 130 *this = std::move(other);
138 } 131 }
(...skipping 13 matching lines...) Expand all
152 void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); } 145 void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); }
153 146
154 private: 147 private:
155 int page_number_; 148 int page_number_;
156 PdfToEmfConverter::GetPageCallback callback_; 149 PdfToEmfConverter::GetPageCallback callback_;
157 ScopedTempFile emf_; 150 ScopedTempFile emf_;
158 151
159 DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); 152 DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData);
160 }; 153 };
161 154
162 ~PdfToEmfUtilityProcessHostClient() override; 155 friend class base::RefCountedThreadSafe<PdfToEmfUtilityProcessHostClient>;
156 ~PdfToEmfUtilityProcessHostClient();
163 157
164 // Message handlers. 158 // Message handlers.
165 void OnPageCount(int page_count); 159 void OnPageCount(int page_count);
166 void OnPageDone(bool success, float scale_factor); 160 void OnPageDone(bool success, float scale_factor);
167 void OnPreCacheFontCharacters(const LOGFONT& log_font,
168 const base::string16& characters);
169 161
170 void OnFailed(); 162 void OnFailed();
171 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); 163 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
172 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); 164 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
173 165
174 scoped_refptr<RefCountedTempDir> temp_dir_; 166 scoped_refptr<RefCountedTempDir> temp_dir_;
175 167
176 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. 168 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
177 base::WeakPtr<PdfToEmfConverterImpl> converter_; 169 base::WeakPtr<PdfToEmfConverterImpl> converter_;
178 PdfRenderSettings settings_; 170 PdfRenderSettings settings_;
179 171
180 // Document loaded callback. 172 // Document loaded callback.
181 PdfToEmfConverter::StartCallback start_callback_; 173 PdfToEmfConverter::StartCallback start_callback_;
182 174
183 // Process host for IPC. 175 std::unique_ptr<content::UtilityProcessMojoClient<mojom::PrintingFactory>>
184 base::WeakPtr<content::UtilityProcessHost> utility_process_host_; 176 utility_client_;
185 177
186 // Queue of callbacks for GetPage() requests. Utility process should reply 178 // Queue of callbacks for GetPage() requests. Utility process should reply
187 // with PageDone in the same order as requests were received. 179 // with PageDone in the same order as requests were received.
188 // Use containers that keeps element pointers valid after push() and pop(). 180 // Use containers that keeps element pointers valid after push() and pop().
189 typedef std::queue<GetPageCallbackData> GetPageCallbacks; 181 typedef std::queue<GetPageCallbackData> GetPageCallbacks;
190 GetPageCallbacks get_page_callbacks_; 182 GetPageCallbacks get_page_callbacks_;
191 183
184 // Bound and used on the UI thread.
185 mojom::PrintingPtr printing_;
186
192 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); 187 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
193 }; 188 };
194 189
195 class PdfToEmfConverterImpl : public PdfToEmfConverter { 190 class PdfToEmfConverterImpl : public PdfToEmfConverter {
196 public: 191 public:
197 PdfToEmfConverterImpl(); 192 PdfToEmfConverterImpl();
198 193
199 ~PdfToEmfConverterImpl() override; 194 ~PdfToEmfConverterImpl() override;
200 195
201 void Start(const scoped_refptr<base::RefCountedMemory>& data, 196 void Start(const scoped_refptr<base::RefCountedMemory>& data,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 return false; 285 return false;
291 std::vector<char> data(size); 286 std::vector<char> data(size);
292 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) 287 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size)
293 return false; 288 return false;
294 return emf->InitFromData(data.data(), data.size()); 289 return emf->InitFromData(data.data(), data.size());
295 } 290 }
296 291
297 PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( 292 PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient(
298 base::WeakPtr<PdfToEmfConverterImpl> converter, 293 base::WeakPtr<PdfToEmfConverterImpl> converter,
299 const PdfRenderSettings& settings) 294 const PdfRenderSettings& settings)
300 : converter_(converter), settings_(settings) { 295 : converter_(converter), settings_(settings) {}
296
297 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
301 } 298 }
302 299
303 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { 300 class FontPreCachingImpl : public mojom::FontPreCaching {
301 public:
302 FontPreCachingImpl() = default;
303 ~FontPreCachingImpl() override = default;
304
305 static void Create(mojom::FontPreCachingRequest request);
306
307 // mojom::FontPreCaching:
308 void PreCacheFontCharacters(
309 const LOGFONT& log_font,
310 const base::string16& characters,
311 const PreCacheFontCharactersCallback& callback) override;
312
313 private:
314 DISALLOW_COPY_AND_ASSIGN(FontPreCachingImpl);
315 };
316
317 void FontPreCachingImpl::Create(mojom::FontPreCachingRequest request) {
318 mojo::MakeStrongBinding(base::MakeUnique<FontPreCachingImpl>(),
319 std::move(request));
320 }
321
322 void FontPreCachingImpl::PreCacheFontCharacters(
323 const LOGFONT& font,
324 const base::string16& str,
325 const PreCacheFontCharactersCallback& callback) {
326 DCHECK_CURRENTLY_ON(BrowserThread::IO);
327
328 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
329 // GDI fonts (http://crbug.com/383227), even when using DirectWrite.
330 // Eventually this shouldn't be added and should be moved to
331 // FontCacheDispatcher too. http://crbug.com/356346.
332
333 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
334 // Except that for True Type fonts,
335 // GetTextMetrics will not load the font in memory.
336 // The only way windows seem to load properly, it is to create a similar
337 // device (like the one in which we print), then do an ExtTextOut,
338 // as we do in the printing thread, which is sandboxed.
339 HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
340 HFONT font_handle = CreateFontIndirect(&font);
341 DCHECK(font_handle != nullptr);
342
343 HGDIOBJ old_font = SelectObject(hdc, font_handle);
344 DCHECK(old_font != nullptr);
345
346 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr);
347
348 SelectObject(hdc, old_font);
349 DeleteObject(font_handle);
350
351 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
352
353 if (metafile)
354 DeleteEnhMetaFile(metafile);
355 callback.Run();
304 } 356 }
305 357
306 void PdfToEmfUtilityProcessHostClient::Start( 358 void PdfToEmfUtilityProcessHostClient::Start(
307 const scoped_refptr<base::RefCountedMemory>& data, 359 const scoped_refptr<base::RefCountedMemory>& data,
308 bool print_text_with_gdi, 360 bool print_text_with_gdi,
309 const PdfToEmfConverter::StartCallback& start_callback) { 361 const PdfToEmfConverter::StartCallback& start_callback) {
310 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 362 DCHECK_CURRENTLY_ON(BrowserThread::UI);
311 BrowserThread::PostTask(
312 BrowserThread::IO, FROM_HERE,
313 base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data,
314 print_text_with_gdi, start_callback));
315 return;
316 }
317 363
318 // Store callback before any OnFailed() call to make it called on failure. 364 // Store callback before any OnFailed() call to make it called on failure.
319 start_callback_ = start_callback; 365 start_callback_ = start_callback;
320 366
321 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load 367 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load
322 // gdiplus.dll, change how rendering happens, and not be able to correctly 368 // gdiplus.dll, change how rendering happens, and not be able to correctly
323 // generate when sent to a metafile DC. 369 // generate when sent to a metafile DC.
324 utility_process_host_ = content::UtilityProcessHost::Create( 370 utility_client_ = base::MakeUnique<
325 this, base::ThreadTaskRunnerHandle::Get()) 371 content::UtilityProcessMojoClient<mojom::PrintingFactory>>(
326 ->AsWeakPtr(); 372 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME));
327 utility_process_host_->SetName(l10n_util::GetStringUTF16( 373 utility_client_->set_error_callback(
328 IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME)); 374 base::Bind(&PdfToEmfUtilityProcessHostClient::OnFailed, this));
375 utility_client_->Start();
376 mojom::FontPreCachingPtr font_precaching;
377 BrowserThread::PostTask(
378 BrowserThread::IO, FROM_HERE,
379 base::Bind(&FontPreCachingImpl::Create,
380 base::Passed(mojo::MakeRequest(&font_precaching))));
381 utility_client_->service()->MakePrinting(mojo::MakeRequest(&printing_),
382 std::move(font_precaching));
329 383
330 BrowserThread::PostTaskAndReplyWithResult( 384 BrowserThread::PostTaskAndReplyWithResult(
331 BrowserThread::FILE, FROM_HERE, 385 BrowserThread::FILE, FROM_HERE,
332 base::Bind(&CreateTempPdfFile, data, &temp_dir_), 386 base::Bind(&CreateTempPdfFile, data, &temp_dir_),
333 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, 387 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this,
334 print_text_with_gdi)); 388 print_text_with_gdi));
335 } 389 }
336 390
337 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, 391 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi,
338 ScopedTempFile pdf) { 392 ScopedTempFile pdf) {
339 DCHECK_CURRENTLY_ON(BrowserThread::IO); 393 DCHECK_CURRENTLY_ON(BrowserThread::UI);
340 if (!utility_process_host_ || !pdf) 394 if (!utility_client_ || !pdf)
341 return OnFailed(); 395 return OnFailed();
342 // Should reply with OnPageCount(). 396 printing_->RenderPDFPagesToMetafiles(
343 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( 397 pdf->Duplicate(), settings_, print_text_with_gdi,
344 IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, 398 base::Bind(&PdfToEmfUtilityProcessHostClient::OnPageCount, this));
345 print_text_with_gdi));
346 } 399 }
347 400
348 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { 401 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO); 402 DCHECK_CURRENTLY_ON(BrowserThread::UI);
350 if (start_callback_.is_null()) 403 if (start_callback_.is_null())
351 return OnFailed(); 404 return OnFailed();
352 BrowserThread::PostTask(BrowserThread::UI, 405 base::ResetAndReturn(&start_callback_).Run(page_count);
353 FROM_HERE,
354 base::Bind(&PdfToEmfConverterImpl::RunCallback,
355 converter_,
356 base::Bind(start_callback_, page_count)));
357 start_callback_.Reset();
358 } 406 }
359 407
360 void PdfToEmfUtilityProcessHostClient::GetPage( 408 void PdfToEmfUtilityProcessHostClient::GetPage(
361 int page_number, 409 int page_number,
362 const PdfToEmfConverter::GetPageCallback& get_page_callback) { 410 const PdfToEmfConverter::GetPageCallback& get_page_callback) {
363 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 411 DCHECK_CURRENTLY_ON(BrowserThread::UI);
364 BrowserThread::PostTask(
365 BrowserThread::IO,
366 FROM_HERE,
367 base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage,
368 this,
369 page_number,
370 get_page_callback));
371 return;
372 }
373 412
374 // Store callback before any OnFailed() call to make it called on failure. 413 // Store callback before any OnFailed() call to make it called on failure.
375 get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback)); 414 get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback));
376 415
377 if (!utility_process_host_) 416 if (!utility_client_)
378 return OnFailed(); 417 return OnFailed();
379 418
380 BrowserThread::PostTaskAndReplyWithResult( 419 BrowserThread::PostTaskAndReplyWithResult(
381 BrowserThread::FILE, 420 BrowserThread::FILE,
382 FROM_HERE, 421 FROM_HERE,
383 base::Bind(&CreateTempFile, &temp_dir_), 422 base::Bind(&CreateTempFile, &temp_dir_),
384 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady, 423 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady,
385 this, 424 this,
386 &get_page_callbacks_.back())); 425 &get_page_callbacks_.back()));
387 } 426 }
388 427
389 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( 428 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady(
390 GetPageCallbackData* callback_data, 429 GetPageCallbackData* callback_data,
391 ScopedTempFile emf) { 430 ScopedTempFile emf) {
392 DCHECK_CURRENTLY_ON(BrowserThread::IO); 431 DCHECK_CURRENTLY_ON(BrowserThread::UI);
393 if (!utility_process_host_ || !emf) 432 if (!utility_client_ || !emf)
394 return OnFailed(); 433 return OnFailed();
395 IPC::PlatformFileForTransit transit =
396 IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false);
397 callback_data->set_emf(std::move(emf)); 434 callback_data->set_emf(std::move(emf));
398 // Should reply with OnPageDone(). 435 printing_->RenderPDFPagesToMetafilesGetPage(
399 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( 436 callback_data->page_number(), emf->Duplicate(),
400 callback_data->page_number(), transit)); 437 base::Bind(&PdfToEmfUtilityProcessHostClient::OnPageDone, this));
401 } 438 }
402 439
403 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, 440 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success,
404 float scale_factor) { 441 float scale_factor) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO); 442 DCHECK_CURRENTLY_ON(BrowserThread::UI);
406 if (get_page_callbacks_.empty()) 443 if (get_page_callbacks_.empty())
407 return OnFailed(); 444 return OnFailed();
408 GetPageCallbackData& data = get_page_callbacks_.front(); 445 GetPageCallbackData& data = get_page_callbacks_.front();
409 std::unique_ptr<MetafilePlayer> emf; 446 std::unique_ptr<MetafilePlayer> emf;
410 447
411 if (success) { 448 if (success) {
412 ScopedTempFile temp_emf = data.TakeEmf(); 449 ScopedTempFile temp_emf = data.TakeEmf();
413 if (!temp_emf) // Unexpected message from utility process. 450 if (!temp_emf) // Unexpected message from utility process.
414 return OnFailed(); 451 return OnFailed();
415 emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf)); 452 emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf));
416 } 453 }
417 454
418 BrowserThread::PostTask(BrowserThread::UI, 455 data.callback().Run(data.page_number(), scale_factor, std::move(emf));
419 FROM_HERE,
420 base::Bind(&PdfToEmfConverterImpl::RunCallback,
421 converter_,
422 base::Bind(data.callback(),
423 data.page_number(),
424 scale_factor,
425 base::Passed(&emf))));
426 get_page_callbacks_.pop(); 456 get_page_callbacks_.pop();
427 } 457 }
428 458
429 void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
430 const LOGFONT& font,
431 const base::string16& str) {
432 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
433 // GDI fonts (http://crbug.com/383227), even when using DirectWrite.
434 // Eventually this shouldn't be added and should be moved to
435 // FontCacheDispatcher too. http://crbug.com/356346.
436
437 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
438 // Except that for True Type fonts,
439 // GetTextMetrics will not load the font in memory.
440 // The only way windows seem to load properly, it is to create a similar
441 // device (like the one in which we print), then do an ExtTextOut,
442 // as we do in the printing thread, which is sandboxed.
443 HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
444 HFONT font_handle = CreateFontIndirect(&font);
445 DCHECK(font_handle != nullptr);
446
447 HGDIOBJ old_font = SelectObject(hdc, font_handle);
448 DCHECK(old_font != nullptr);
449
450 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr);
451
452 SelectObject(hdc, old_font);
453 DeleteObject(font_handle);
454
455 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
456
457 if (metafile)
458 DeleteEnhMetaFile(metafile);
459 }
460
461 void PdfToEmfUtilityProcessHostClient::Stop() { 459 void PdfToEmfUtilityProcessHostClient::Stop() {
462 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 460 DCHECK_CURRENTLY_ON(BrowserThread::UI);
463 BrowserThread::PostTask( 461 printing_.reset();
464 BrowserThread::IO,
465 FROM_HERE,
466 base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this));
467 return;
468 }
469 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
470 }
471
472 void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
473 OnFailed();
474 }
475
476 void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) {
477 OnFailed();
478 }
479
480 bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
481 const IPC::Message& message) {
482 bool handled = true;
483 IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
484 IPC_MESSAGE_HANDLER(
485 ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
486 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
487 OnPageDone)
488 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
489 OnPreCacheFontCharacters)
490 IPC_MESSAGE_UNHANDLED(handled = false)
491 IPC_END_MESSAGE_MAP()
492 return handled;
493 }
494
495 bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) {
496 if (utility_process_host_)
497 return utility_process_host_->Send(msg);
498 delete msg;
499 return false;
500 } 462 }
501 463
502 void PdfToEmfUtilityProcessHostClient::OnFailed() { 464 void PdfToEmfUtilityProcessHostClient::OnFailed() {
503 DCHECK_CURRENTLY_ON(BrowserThread::IO); 465 DCHECK_CURRENTLY_ON(BrowserThread::UI);
504 if (!start_callback_.is_null()) 466 if (!start_callback_.is_null())
505 OnPageCount(0); 467 OnPageCount(0);
506 while (!get_page_callbacks_.empty()) 468 while (!get_page_callbacks_.empty())
507 OnPageDone(false, 0.0f); 469 OnPageDone(false, 0.0f);
508 utility_process_host_.reset(); 470 utility_client_.reset();
509 } 471 }
510 472
511 PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { 473 PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) {
512 } 474 }
513 475
514 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { 476 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
515 if (utility_client_.get()) 477 if (utility_client_.get())
516 utility_client_->Stop(); 478 utility_client_->Stop();
517 } 479 }
518 480
(...skipping 22 matching lines...) Expand all
541 503
542 PdfToEmfConverter::~PdfToEmfConverter() { 504 PdfToEmfConverter::~PdfToEmfConverter() {
543 } 505 }
544 506
545 // static 507 // static
546 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { 508 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() {
547 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); 509 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl());
548 } 510 }
549 511
550 } // namespace printing 512 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698