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

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

Issue 2114583002: Windows: Make it possible to print text with GDI. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase again, resolve conflicts Created 4 years, 3 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
« no previous file with comments | « chrome/browser/printing/pdf_to_emf_converter.h ('k') | chrome/browser/printing/print_job.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 9
9 #include <memory> 10 #include <memory>
10 #include <queue> 11 #include <queue>
11 #include <utility> 12 #include <utility>
12 #include <vector> 13 #include <vector>
13 14
14 #include "base/files/file.h" 15 #include "base/files/file.h"
15 #include "base/files/file_util.h" 16 #include "base/files/file_util.h"
16 #include "base/files/scoped_temp_dir.h" 17 #include "base/files/scoped_temp_dir.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 // All these steps work sequentially, so no data should be accessed 101 // All these steps work sequentially, so no data should be accessed
101 // simultaneously by several threads. 102 // simultaneously by several threads.
102 class PdfToEmfUtilityProcessHostClient 103 class PdfToEmfUtilityProcessHostClient
103 : public content::UtilityProcessHostClient { 104 : public content::UtilityProcessHostClient {
104 public: 105 public:
105 PdfToEmfUtilityProcessHostClient( 106 PdfToEmfUtilityProcessHostClient(
106 base::WeakPtr<PdfToEmfConverterImpl> converter, 107 base::WeakPtr<PdfToEmfConverterImpl> converter,
107 const PdfRenderSettings& settings); 108 const PdfRenderSettings& settings);
108 109
109 void Start(const scoped_refptr<base::RefCountedMemory>& data, 110 void Start(const scoped_refptr<base::RefCountedMemory>& data,
111 bool print_text_with_gdi,
110 const PdfToEmfConverter::StartCallback& start_callback); 112 const PdfToEmfConverter::StartCallback& start_callback);
111 113
112 void GetPage(int page_number, 114 void GetPage(int page_number,
113 const PdfToEmfConverter::GetPageCallback& get_page_callback); 115 const PdfToEmfConverter::GetPageCallback& get_page_callback);
114 116
115 void Stop(); 117 void Stop();
116 118
119 // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
120 // sync message replies.
121 bool Send(IPC::Message* msg);
122
117 // UtilityProcessHostClient implementation. 123 // UtilityProcessHostClient implementation.
118 void OnProcessCrashed(int exit_code) override; 124 void OnProcessCrashed(int exit_code) override;
119 void OnProcessLaunchFailed(int exit_code) override; 125 void OnProcessLaunchFailed(int exit_code) override;
120 bool OnMessageReceived(const IPC::Message& message) override; 126 bool OnMessageReceived(const IPC::Message& message) override;
121 127
122 private: 128 private:
123 class GetPageCallbackData { 129 class GetPageCallbackData {
124 public: 130 public:
125 GetPageCallbackData(int page_number, 131 GetPageCallbackData(int page_number,
126 PdfToEmfConverter::GetPageCallback callback) 132 PdfToEmfConverter::GetPageCallback callback)
(...skipping 20 matching lines...) Expand all
147 private: 153 private:
148 int page_number_; 154 int page_number_;
149 PdfToEmfConverter::GetPageCallback callback_; 155 PdfToEmfConverter::GetPageCallback callback_;
150 ScopedTempFile emf_; 156 ScopedTempFile emf_;
151 157
152 DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); 158 DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData);
153 }; 159 };
154 160
155 ~PdfToEmfUtilityProcessHostClient() override; 161 ~PdfToEmfUtilityProcessHostClient() override;
156 162
157 bool Send(IPC::Message* msg);
158
159 // Message handlers. 163 // Message handlers.
160 void OnPageCount(int page_count); 164 void OnPageCount(int page_count);
161 void OnPageDone(bool success, float scale_factor); 165 void OnPageDone(bool success, float scale_factor);
166 void OnPreCacheFontCharacters(const LOGFONT& log_font,
167 const base::string16& characters);
162 168
163 void OnFailed(); 169 void OnFailed();
164 void OnTempPdfReady(ScopedTempFile pdf); 170 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
165 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); 171 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
166 172
167 scoped_refptr<RefCountedTempDir> temp_dir_; 173 scoped_refptr<RefCountedTempDir> temp_dir_;
168 174
169 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. 175 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
170 base::WeakPtr<PdfToEmfConverterImpl> converter_; 176 base::WeakPtr<PdfToEmfConverterImpl> converter_;
171 PdfRenderSettings settings_; 177 PdfRenderSettings settings_;
172 178
173 // Document loaded callback. 179 // Document loaded callback.
174 PdfToEmfConverter::StartCallback start_callback_; 180 PdfToEmfConverter::StartCallback start_callback_;
(...skipping 11 matching lines...) Expand all
186 }; 192 };
187 193
188 class PdfToEmfConverterImpl : public PdfToEmfConverter { 194 class PdfToEmfConverterImpl : public PdfToEmfConverter {
189 public: 195 public:
190 PdfToEmfConverterImpl(); 196 PdfToEmfConverterImpl();
191 197
192 ~PdfToEmfConverterImpl() override; 198 ~PdfToEmfConverterImpl() override;
193 199
194 void Start(const scoped_refptr<base::RefCountedMemory>& data, 200 void Start(const scoped_refptr<base::RefCountedMemory>& data,
195 const PdfRenderSettings& conversion_settings, 201 const PdfRenderSettings& conversion_settings,
202 bool print_text_with_gdi,
196 const StartCallback& start_callback) override; 203 const StartCallback& start_callback) override;
197 204
198 void GetPage(int page_number, 205 void GetPage(int page_number,
199 const GetPageCallback& get_page_callback) override; 206 const GetPageCallback& get_page_callback) override;
200 207
201 // Helps to cancel callbacks if this object is destroyed. 208 // Helps to cancel callbacks if this object is destroyed.
202 void RunCallback(const base::Closure& callback); 209 void RunCallback(const base::Closure& callback);
203 210
204 private: 211 private:
205 scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_; 212 scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 base::WeakPtr<PdfToEmfConverterImpl> converter, 297 base::WeakPtr<PdfToEmfConverterImpl> converter,
291 const PdfRenderSettings& settings) 298 const PdfRenderSettings& settings)
292 : converter_(converter), settings_(settings) { 299 : converter_(converter), settings_(settings) {
293 } 300 }
294 301
295 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { 302 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
296 } 303 }
297 304
298 void PdfToEmfUtilityProcessHostClient::Start( 305 void PdfToEmfUtilityProcessHostClient::Start(
299 const scoped_refptr<base::RefCountedMemory>& data, 306 const scoped_refptr<base::RefCountedMemory>& data,
307 bool print_text_with_gdi,
300 const PdfToEmfConverter::StartCallback& start_callback) { 308 const PdfToEmfConverter::StartCallback& start_callback) {
301 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 309 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
302 BrowserThread::PostTask(BrowserThread::IO, 310 BrowserThread::PostTask(
303 FROM_HERE, 311 BrowserThread::IO, FROM_HERE,
304 base::Bind(&PdfToEmfUtilityProcessHostClient::Start, 312 base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data,
305 this, 313 print_text_with_gdi, start_callback));
306 data,
307 start_callback));
308 return; 314 return;
309 } 315 }
310 316
311 // Store callback before any OnFailed() call to make it called on failure. 317 // Store callback before any OnFailed() call to make it called on failure.
312 start_callback_ = start_callback; 318 start_callback_ = start_callback;
313 319
314 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load 320 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load
315 // gdiplus.dll, change how rendering happens, and not be able to correctly 321 // gdiplus.dll, change how rendering happens, and not be able to correctly
316 // generate when sent to a metafile DC. 322 // generate when sent to a metafile DC.
317 utility_process_host_ = content::UtilityProcessHost::Create( 323 utility_process_host_ = content::UtilityProcessHost::Create(
318 this, base::ThreadTaskRunnerHandle::Get()) 324 this, base::ThreadTaskRunnerHandle::Get())
319 ->AsWeakPtr(); 325 ->AsWeakPtr();
320 utility_process_host_->SetName(l10n_util::GetStringUTF16( 326 utility_process_host_->SetName(l10n_util::GetStringUTF16(
321 IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME)); 327 IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME));
322 328
323 BrowserThread::PostTaskAndReplyWithResult( 329 BrowserThread::PostTaskAndReplyWithResult(
324 BrowserThread::FILE, 330 BrowserThread::FILE, FROM_HERE,
325 FROM_HERE,
326 base::Bind(&CreateTempPdfFile, data, &temp_dir_), 331 base::Bind(&CreateTempPdfFile, data, &temp_dir_),
327 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this)); 332 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this,
333 print_text_with_gdi));
328 } 334 }
329 335
330 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) { 336 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi,
337 ScopedTempFile pdf) {
331 DCHECK_CURRENTLY_ON(BrowserThread::IO); 338 DCHECK_CURRENTLY_ON(BrowserThread::IO);
332 if (!utility_process_host_ || !pdf) 339 if (!utility_process_host_ || !pdf)
333 return OnFailed(); 340 return OnFailed();
334 // Should reply with OnPageCount(). 341 // Should reply with OnPageCount().
335 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( 342 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(
336 IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), 343 IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_,
337 settings_)); 344 print_text_with_gdi));
338 } 345 }
339 346
340 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { 347 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
341 DCHECK_CURRENTLY_ON(BrowserThread::IO); 348 DCHECK_CURRENTLY_ON(BrowserThread::IO);
342 if (start_callback_.is_null()) 349 if (start_callback_.is_null())
343 return OnFailed(); 350 return OnFailed();
344 BrowserThread::PostTask(BrowserThread::UI, 351 BrowserThread::PostTask(BrowserThread::UI,
345 FROM_HERE, 352 FROM_HERE,
346 base::Bind(&PdfToEmfConverterImpl::RunCallback, 353 base::Bind(&PdfToEmfConverterImpl::RunCallback,
347 converter_, 354 converter_,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 FROM_HERE, 418 FROM_HERE,
412 base::Bind(&PdfToEmfConverterImpl::RunCallback, 419 base::Bind(&PdfToEmfConverterImpl::RunCallback,
413 converter_, 420 converter_,
414 base::Bind(data.callback(), 421 base::Bind(data.callback(),
415 data.page_number(), 422 data.page_number(),
416 scale_factor, 423 scale_factor,
417 base::Passed(&emf)))); 424 base::Passed(&emf))));
418 get_page_callbacks_.pop(); 425 get_page_callbacks_.pop();
419 } 426 }
420 427
428 void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
429 const LOGFONT& font,
430 const base::string16& str) {
431 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
432 // GDI fonts (http://crbug.com/383227), even when using DirectWrite.
433 // Eventually this shouldn't be added and should be moved to
434 // FontCacheDispatcher too. http://crbug.com/356346.
435
436 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
437 // Except that for True Type fonts,
438 // GetTextMetrics will not load the font in memory.
439 // The only way windows seem to load properly, it is to create a similar
440 // device (like the one in which we print), then do an ExtTextOut,
441 // as we do in the printing thread, which is sandboxed.
442 HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
443 HFONT font_handle = CreateFontIndirect(&font);
444 DCHECK(font_handle != nullptr);
445
446 HGDIOBJ old_font = SelectObject(hdc, font_handle);
447 DCHECK(old_font != nullptr);
448
449 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr);
450
451 SelectObject(hdc, old_font);
452 DeleteObject(font_handle);
453
454 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
455
456 if (metafile)
457 DeleteEnhMetaFile(metafile);
458 }
459
421 void PdfToEmfUtilityProcessHostClient::Stop() { 460 void PdfToEmfUtilityProcessHostClient::Stop() {
422 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 461 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
423 BrowserThread::PostTask( 462 BrowserThread::PostTask(
424 BrowserThread::IO, 463 BrowserThread::IO,
425 FROM_HERE, 464 FROM_HERE,
426 base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); 465 base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this));
427 return; 466 return;
428 } 467 }
429 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); 468 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
430 } 469 }
431 470
432 void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) { 471 void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
433 OnFailed(); 472 OnFailed();
434 } 473 }
435 474
436 void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) { 475 void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) {
437 OnFailed(); 476 OnFailed();
438 } 477 }
439 478
440 bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( 479 bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
441 const IPC::Message& message) { 480 const IPC::Message& message) {
442 bool handled = true; 481 bool handled = true;
443 IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) 482 IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
444 IPC_MESSAGE_HANDLER( 483 IPC_MESSAGE_HANDLER(
445 ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount) 484 ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
446 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, 485 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
447 OnPageDone) 486 OnPageDone)
487 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
488 OnPreCacheFontCharacters)
448 IPC_MESSAGE_UNHANDLED(handled = false) 489 IPC_MESSAGE_UNHANDLED(handled = false)
449 IPC_END_MESSAGE_MAP() 490 IPC_END_MESSAGE_MAP()
450 return handled; 491 return handled;
451 } 492 }
452 493
453 bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { 494 bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) {
454 if (utility_process_host_) 495 if (utility_process_host_)
455 return utility_process_host_->Send(msg); 496 return utility_process_host_->Send(msg);
456 delete msg; 497 delete msg;
457 return false; 498 return false;
(...skipping 12 matching lines...) Expand all
470 } 511 }
471 512
472 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { 513 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
473 if (utility_client_.get()) 514 if (utility_client_.get())
474 utility_client_->Stop(); 515 utility_client_->Stop();
475 } 516 }
476 517
477 void PdfToEmfConverterImpl::Start( 518 void PdfToEmfConverterImpl::Start(
478 const scoped_refptr<base::RefCountedMemory>& data, 519 const scoped_refptr<base::RefCountedMemory>& data,
479 const PdfRenderSettings& conversion_settings, 520 const PdfRenderSettings& conversion_settings,
521 bool print_text_with_gdi,
480 const StartCallback& start_callback) { 522 const StartCallback& start_callback) {
481 DCHECK(!utility_client_.get()); 523 DCHECK(!utility_client_.get());
482 utility_client_ = new PdfToEmfUtilityProcessHostClient( 524 utility_client_ = new PdfToEmfUtilityProcessHostClient(
483 weak_ptr_factory_.GetWeakPtr(), conversion_settings); 525 weak_ptr_factory_.GetWeakPtr(), conversion_settings);
484 utility_client_->Start(data, start_callback); 526 utility_client_->Start(data, print_text_with_gdi, start_callback);
485 } 527 }
486 528
487 void PdfToEmfConverterImpl::GetPage(int page_number, 529 void PdfToEmfConverterImpl::GetPage(int page_number,
488 const GetPageCallback& get_page_callback) { 530 const GetPageCallback& get_page_callback) {
489 utility_client_->GetPage(page_number, get_page_callback); 531 utility_client_->GetPage(page_number, get_page_callback);
490 } 532 }
491 533
492 void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) { 534 void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) {
493 DCHECK_CURRENTLY_ON(BrowserThread::UI); 535 DCHECK_CURRENTLY_ON(BrowserThread::UI);
494 callback.Run(); 536 callback.Run();
495 } 537 }
496 538
497 } // namespace 539 } // namespace
498 540
499 PdfToEmfConverter::~PdfToEmfConverter() { 541 PdfToEmfConverter::~PdfToEmfConverter() {
500 } 542 }
501 543
502 // static 544 // static
503 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { 545 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() {
504 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); 546 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl());
505 } 547 }
506 548
507 } // namespace printing 549 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/pdf_to_emf_converter.h ('k') | chrome/browser/printing/print_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698