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

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

Issue 2477283002: Convert printing IPCs to Mojo
Patch Set: Follow mojo::GetProxy rename Created 4 years 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/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>,
107 public mojom::FontPreCaching {
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
155 friend class base::RefCountedThreadSafe<PdfToEmfUtilityProcessHostClient>;
162 ~PdfToEmfUtilityProcessHostClient() override; 156 ~PdfToEmfUtilityProcessHostClient() override;
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, 161
168 const base::string16& characters); 162 // mojom::FontPreCaching:
163 void PreCacheFontCharacters(
164 const LOGFONT& log_font,
165 const base::string16& characters,
166 const PreCacheFontCharactersCallback& callback) override;
169 167
170 void OnFailed(); 168 void OnFailed();
171 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); 169 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
172 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); 170 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
173 171
174 scoped_refptr<RefCountedTempDir> temp_dir_; 172 scoped_refptr<RefCountedTempDir> temp_dir_;
175 173
176 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. 174 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
177 base::WeakPtr<PdfToEmfConverterImpl> converter_; 175 base::WeakPtr<PdfToEmfConverterImpl> converter_;
178 PdfRenderSettings settings_; 176 PdfRenderSettings settings_;
179 177
180 // Document loaded callback. 178 // Document loaded callback.
181 PdfToEmfConverter::StartCallback start_callback_; 179 PdfToEmfConverter::StartCallback start_callback_;
182 180
183 // Process host for IPC. 181 std::unique_ptr<content::UtilityProcessMojoClient<mojom::PrintingFactory>>
184 base::WeakPtr<content::UtilityProcessHost> utility_process_host_; 182 utility_client_;
185 183
186 // Queue of callbacks for GetPage() requests. Utility process should reply 184 // Queue of callbacks for GetPage() requests. Utility process should reply
187 // with PageDone in the same order as requests were received. 185 // with PageDone in the same order as requests were received.
188 // Use containers that keeps element pointers valid after push() and pop(). 186 // Use containers that keeps element pointers valid after push() and pop().
189 typedef std::queue<GetPageCallbackData> GetPageCallbacks; 187 typedef std::queue<GetPageCallbackData> GetPageCallbacks;
190 GetPageCallbacks get_page_callbacks_; 188 GetPageCallbacks get_page_callbacks_;
191 189
190 // Bound and used on the UI thread.
191 mojom::PrintingPtr printing_;
192
193 // Interface that receives font precaching requests.
194 mojo::Binding<mojom::FontPreCaching> binding_;
195
192 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); 196 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
193 }; 197 };
194 198
195 class PdfToEmfConverterImpl : public PdfToEmfConverter { 199 class PdfToEmfConverterImpl : public PdfToEmfConverter {
196 public: 200 public:
197 PdfToEmfConverterImpl(); 201 PdfToEmfConverterImpl();
198 202
199 ~PdfToEmfConverterImpl() override; 203 ~PdfToEmfConverterImpl() override;
200 204
201 void Start(const scoped_refptr<base::RefCountedMemory>& data, 205 void Start(const scoped_refptr<base::RefCountedMemory>& data,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 return false; 294 return false;
291 std::vector<char> data(size); 295 std::vector<char> data(size);
292 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) 296 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size)
293 return false; 297 return false;
294 return emf->InitFromData(data.data(), data.size()); 298 return emf->InitFromData(data.data(), data.size());
295 } 299 }
296 300
297 PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( 301 PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient(
298 base::WeakPtr<PdfToEmfConverterImpl> converter, 302 base::WeakPtr<PdfToEmfConverterImpl> converter,
299 const PdfRenderSettings& settings) 303 const PdfRenderSettings& settings)
300 : converter_(converter), settings_(settings) { 304 : converter_(converter), settings_(settings), binding_(this) {}
301 }
302 305
303 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { 306 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
304 } 307 }
305 308
306 void PdfToEmfUtilityProcessHostClient::Start( 309 void PdfToEmfUtilityProcessHostClient::Start(
307 const scoped_refptr<base::RefCountedMemory>& data, 310 const scoped_refptr<base::RefCountedMemory>& data,
308 bool print_text_with_gdi, 311 bool print_text_with_gdi,
309 const PdfToEmfConverter::StartCallback& start_callback) { 312 const PdfToEmfConverter::StartCallback& start_callback) {
310 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 313 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 314
318 // Store callback before any OnFailed() call to make it called on failure. 315 // Store callback before any OnFailed() call to make it called on failure.
319 start_callback_ = start_callback; 316 start_callback_ = start_callback;
320 317
321 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load 318 // 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 319 // gdiplus.dll, change how rendering happens, and not be able to correctly
323 // generate when sent to a metafile DC. 320 // generate when sent to a metafile DC.
324 utility_process_host_ = content::UtilityProcessHost::Create( 321 utility_client_.reset(
Sam McNally 2017/01/05 06:23:15 Prefer base::MakeUnique over std::unique_ptr::rese
tibell 2017/01/12 03:30:14 Done.
325 this, base::ThreadTaskRunnerHandle::Get()) 322 new content::UtilityProcessMojoClient<mojom::PrintingFactory>(
326 ->AsWeakPtr(); 323 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME)));
327 utility_process_host_->SetName(l10n_util::GetStringUTF16( 324 utility_client_->set_error_callback(
328 IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME)); 325 base::Bind(&PdfToEmfUtilityProcessHostClient::OnFailed, this));
326 utility_client_->Start();
327 utility_client_->service()->MakePrinting(
328 mojo::MakeRequest(&printing_), binding_.CreateInterfacePtrAndBind());
329 329
330 BrowserThread::PostTaskAndReplyWithResult( 330 BrowserThread::PostTaskAndReplyWithResult(
331 BrowserThread::FILE, FROM_HERE, 331 BrowserThread::FILE, FROM_HERE,
332 base::Bind(&CreateTempPdfFile, data, &temp_dir_), 332 base::Bind(&CreateTempPdfFile, data, &temp_dir_),
333 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, 333 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this,
334 print_text_with_gdi)); 334 print_text_with_gdi));
335 } 335 }
336 336
337 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, 337 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi,
338 ScopedTempFile pdf) { 338 ScopedTempFile pdf) {
339 DCHECK_CURRENTLY_ON(BrowserThread::IO); 339 DCHECK_CURRENTLY_ON(BrowserThread::UI);
340 if (!utility_process_host_ || !pdf) 340 if (!utility_client_ || !pdf)
341 return OnFailed(); 341 return OnFailed();
342 // Should reply with OnPageCount(). 342 printing_->RenderPDFPagesToMetafiles(
343 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( 343 pdf->Duplicate(), settings_, print_text_with_gdi,
344 IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, 344 base::Bind(&PdfToEmfUtilityProcessHostClient::OnPageCount, this));
345 print_text_with_gdi));
346 } 345 }
347 346
348 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { 347 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO); 348 DCHECK_CURRENTLY_ON(BrowserThread::UI);
350 if (start_callback_.is_null()) 349 if (start_callback_.is_null())
351 return OnFailed(); 350 return OnFailed();
352 BrowserThread::PostTask(BrowserThread::UI, 351 start_callback_.Run(page_count);
Sam McNally 2017/01/05 06:23:15 base::ResetAndReturn(&start_callback_).Run(page_co
tibell 2017/01/12 03:30:14 Done.
353 FROM_HERE,
354 base::Bind(&PdfToEmfConverterImpl::RunCallback,
355 converter_,
356 base::Bind(start_callback_, page_count)));
357 start_callback_.Reset(); 352 start_callback_.Reset();
358 } 353 }
359 354
360 void PdfToEmfUtilityProcessHostClient::GetPage( 355 void PdfToEmfUtilityProcessHostClient::GetPage(
361 int page_number, 356 int page_number,
362 const PdfToEmfConverter::GetPageCallback& get_page_callback) { 357 const PdfToEmfConverter::GetPageCallback& get_page_callback) {
363 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 358 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 359
374 // Store callback before any OnFailed() call to make it called on failure. 360 // Store callback before any OnFailed() call to make it called on failure.
375 get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback)); 361 get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback));
376 362
377 if (!utility_process_host_) 363 if (!utility_client_)
378 return OnFailed(); 364 return OnFailed();
379 365
380 BrowserThread::PostTaskAndReplyWithResult( 366 BrowserThread::PostTaskAndReplyWithResult(
381 BrowserThread::FILE, 367 BrowserThread::FILE,
382 FROM_HERE, 368 FROM_HERE,
383 base::Bind(&CreateTempFile, &temp_dir_), 369 base::Bind(&CreateTempFile, &temp_dir_),
384 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady, 370 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady,
385 this, 371 this,
386 &get_page_callbacks_.back())); 372 &get_page_callbacks_.back()));
387 } 373 }
388 374
389 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( 375 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady(
390 GetPageCallbackData* callback_data, 376 GetPageCallbackData* callback_data,
391 ScopedTempFile emf) { 377 ScopedTempFile emf) {
392 DCHECK_CURRENTLY_ON(BrowserThread::IO); 378 DCHECK_CURRENTLY_ON(BrowserThread::UI);
393 if (!utility_process_host_ || !emf) 379 if (!utility_client_ || !emf)
394 return OnFailed(); 380 return OnFailed();
395 IPC::PlatformFileForTransit transit =
396 IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false);
397 callback_data->set_emf(std::move(emf)); 381 callback_data->set_emf(std::move(emf));
398 // Should reply with OnPageDone(). 382 printing_->RenderPDFPagesToMetafilesGetPage(
399 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( 383 callback_data->page_number(), emf->Duplicate(),
400 callback_data->page_number(), transit)); 384 base::Bind(&PdfToEmfUtilityProcessHostClient::OnPageDone, this));
401 } 385 }
402 386
403 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, 387 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success,
404 float scale_factor) { 388 float scale_factor) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO); 389 DCHECK_CURRENTLY_ON(BrowserThread::UI);
406 if (get_page_callbacks_.empty()) 390 if (get_page_callbacks_.empty())
407 return OnFailed(); 391 return OnFailed();
408 GetPageCallbackData& data = get_page_callbacks_.front(); 392 GetPageCallbackData& data = get_page_callbacks_.front();
409 std::unique_ptr<MetafilePlayer> emf; 393 std::unique_ptr<MetafilePlayer> emf;
410 394
411 if (success) { 395 if (success) {
412 ScopedTempFile temp_emf = data.TakeEmf(); 396 ScopedTempFile temp_emf = data.TakeEmf();
413 if (!temp_emf) // Unexpected message from utility process. 397 if (!temp_emf) // Unexpected message from utility process.
414 return OnFailed(); 398 return OnFailed();
415 emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf)); 399 emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf));
416 } 400 }
417 401
418 BrowserThread::PostTask(BrowserThread::UI, 402 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(); 403 get_page_callbacks_.pop();
427 } 404 }
428 405
429 void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( 406 void PdfToEmfUtilityProcessHostClient::PreCacheFontCharacters(
Sam McNally 2017/01/05 06:23:15 Is the UI thread the right place to be doing this?
tibell 2017/01/12 03:30:14 Done.
430 const LOGFONT& font, 407 const LOGFONT& font,
431 const base::string16& str) { 408 const base::string16& str,
409 const PreCacheFontCharactersCallback& callback) {
432 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache 410 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
433 // GDI fonts (http://crbug.com/383227), even when using DirectWrite. 411 // GDI fonts (http://crbug.com/383227), even when using DirectWrite.
434 // Eventually this shouldn't be added and should be moved to 412 // Eventually this shouldn't be added and should be moved to
435 // FontCacheDispatcher too. http://crbug.com/356346. 413 // FontCacheDispatcher too. http://crbug.com/356346.
436 414
437 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too. 415 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
438 // Except that for True Type fonts, 416 // Except that for True Type fonts,
439 // GetTextMetrics will not load the font in memory. 417 // GetTextMetrics will not load the font in memory.
440 // The only way windows seem to load properly, it is to create a similar 418 // 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, 419 // device (like the one in which we print), then do an ExtTextOut,
442 // as we do in the printing thread, which is sandboxed. 420 // as we do in the printing thread, which is sandboxed.
443 HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr); 421 HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
444 HFONT font_handle = CreateFontIndirect(&font); 422 HFONT font_handle = CreateFontIndirect(&font);
445 DCHECK(font_handle != nullptr); 423 DCHECK(font_handle != nullptr);
446 424
447 HGDIOBJ old_font = SelectObject(hdc, font_handle); 425 HGDIOBJ old_font = SelectObject(hdc, font_handle);
448 DCHECK(old_font != nullptr); 426 DCHECK(old_font != nullptr);
449 427
450 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr); 428 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr);
451 429
452 SelectObject(hdc, old_font); 430 SelectObject(hdc, old_font);
453 DeleteObject(font_handle); 431 DeleteObject(font_handle);
454 432
455 HENHMETAFILE metafile = CloseEnhMetaFile(hdc); 433 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
456 434
457 if (metafile) 435 if (metafile)
458 DeleteEnhMetaFile(metafile); 436 DeleteEnhMetaFile(metafile);
437 callback.Run();
459 } 438 }
460 439
461 void PdfToEmfUtilityProcessHostClient::Stop() { 440 void PdfToEmfUtilityProcessHostClient::Stop() {
462 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 441 DCHECK_CURRENTLY_ON(BrowserThread::UI);
463 BrowserThread::PostTask( 442 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 } 443 }
501 444
502 void PdfToEmfUtilityProcessHostClient::OnFailed() { 445 void PdfToEmfUtilityProcessHostClient::OnFailed() {
503 DCHECK_CURRENTLY_ON(BrowserThread::IO); 446 DCHECK_CURRENTLY_ON(BrowserThread::UI);
504 if (!start_callback_.is_null()) 447 if (!start_callback_.is_null())
505 OnPageCount(0); 448 OnPageCount(0);
506 while (!get_page_callbacks_.empty()) 449 while (!get_page_callbacks_.empty())
507 OnPageDone(false, 0.0f); 450 OnPageDone(false, 0.0f);
508 utility_process_host_.reset(); 451 utility_client_.reset();
509 } 452 }
510 453
511 PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { 454 PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) {
512 } 455 }
513 456
514 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { 457 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
515 if (utility_client_.get()) 458 if (utility_client_.get())
516 utility_client_->Stop(); 459 utility_client_->Stop();
517 } 460 }
518 461
(...skipping 22 matching lines...) Expand all
541 484
542 PdfToEmfConverter::~PdfToEmfConverter() { 485 PdfToEmfConverter::~PdfToEmfConverter() {
543 } 486 }
544 487
545 // static 488 // static
546 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { 489 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() {
547 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); 490 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl());
548 } 491 }
549 492
550 } // namespace printing 493 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698