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

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

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

Powered by Google App Engine
This is Rietveld 408576698