OLD | NEW |
---|---|
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> |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 IPC::PlatformFileForTransit transit) override; | 223 IPC::PlatformFileForTransit transit) override; |
224 void SendStopMessage() override; | 224 void SendStopMessage() override; |
225 | 225 |
226 // Additional message handler needed for Pdf to Emf | 226 // Additional message handler needed for Pdf to Emf |
227 void OnPreCacheFontCharacters(const LOGFONT& log_font, | 227 void OnPreCacheFontCharacters(const LOGFONT& log_font, |
228 const base::string16& characters); | 228 const base::string16& characters); |
229 | 229 |
230 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); | 230 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); |
231 }; | 231 }; |
232 | 232 |
233 // Converts PDF into PostScript. | |
234 class PdfToPostScriptUtilityProcessHostClient | |
235 : public PdfConverterUtilityProcessHostClient { | |
236 public: | |
237 PdfToPostScriptUtilityProcessHostClient( | |
238 base::WeakPtr<PdfConverterImpl> converter, | |
239 const PdfRenderSettings& settings) | |
240 : PdfConverterUtilityProcessHostClient(converter, settings) {} | |
241 | |
242 // UtilityProcessHostClient implementation. | |
243 bool OnMessageReceived(const IPC::Message& message) override; | |
244 | |
245 private: | |
246 ~PdfToPostScriptUtilityProcessHostClient() override; | |
247 | |
248 // Helpers to send messages and set process name | |
249 base::string16 GetName() const override; | |
250 std::unique_ptr<MetafilePlayer> GetFileFromTemp( | |
251 std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread> | |
252 temp_file) override; | |
253 void SendStartMessage(IPC::PlatformFileForTransit transit) override; | |
254 void SendGetPageMessage(int page_number, | |
255 IPC::PlatformFileForTransit transit) override; | |
256 void SendStopMessage() override; | |
257 | |
258 // Additional message handler needed for Pdf to PostScript | |
259 void OnPageDone(bool success); | |
260 | |
261 DISALLOW_COPY_AND_ASSIGN(PdfToPostScriptUtilityProcessHostClient); | |
262 }; | |
263 | |
233 class PdfConverterImpl : public PdfConverter { | 264 class PdfConverterImpl : public PdfConverter { |
234 public: | 265 public: |
235 PdfConverterImpl(); | 266 PdfConverterImpl(); |
236 | 267 |
237 ~PdfConverterImpl() override; | 268 ~PdfConverterImpl() override; |
238 | 269 |
239 void Start(const scoped_refptr<base::RefCountedMemory>& data, | 270 void Start(const scoped_refptr<base::RefCountedMemory>& data, |
240 const PdfRenderSettings& conversion_settings, | 271 const PdfRenderSettings& conversion_settings, |
241 const StartCallback& start_callback) override; | 272 const StartCallback& start_callback) override; |
242 | 273 |
(...skipping 19 matching lines...) Expand all Loading... | |
262 void Start(const scoped_refptr<base::RefCountedMemory>& data, | 293 void Start(const scoped_refptr<base::RefCountedMemory>& data, |
263 const PdfRenderSettings& conversion_settings, | 294 const PdfRenderSettings& conversion_settings, |
264 const StartCallback& start_callback) override; | 295 const StartCallback& start_callback) override; |
265 | 296 |
266 private: | 297 private: |
267 base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; | 298 base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; |
268 | 299 |
269 DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); | 300 DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); |
270 }; | 301 }; |
271 | 302 |
303 class PdfToPostScriptConverterImpl : public PdfConverterImpl { | |
304 public: | |
305 PdfToPostScriptConverterImpl(); | |
306 ~PdfToPostScriptConverterImpl() override; | |
307 | |
308 void Start(const scoped_refptr<base::RefCountedMemory>& data, | |
309 const PdfRenderSettings& conversion_settings, | |
310 const StartCallback& start_callback) override; | |
311 | |
312 private: | |
313 base::WeakPtrFactory<PdfToPostScriptConverterImpl> weak_ptr_factory_; | |
314 DISALLOW_COPY_AND_ASSIGN(PdfToPostScriptConverterImpl); | |
315 }; | |
316 | |
272 ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { | 317 ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { |
273 if (!temp_dir->get()) | 318 if (!temp_dir->get()) |
274 *temp_dir = new RefCountedTempDir(); | 319 *temp_dir = new RefCountedTempDir(); |
275 ScopedTempFile file; | 320 ScopedTempFile file; |
276 if (!(*temp_dir)->IsValid()) | 321 if (!(*temp_dir)->IsValid()) |
277 return file; | 322 return file; |
278 base::FilePath path; | 323 base::FilePath path; |
279 if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) { | 324 if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) { |
280 PLOG(ERROR) << "Failed to create file in " | 325 PLOG(ERROR) << "Failed to create file in " |
281 << (*temp_dir)->GetPath().value(); | 326 << (*temp_dir)->GetPath().value(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 file_->Seek(base::File::FROM_BEGIN, 0); | 385 file_->Seek(base::File::FROM_BEGIN, 0); |
341 int64_t size = file_->GetLength(); | 386 int64_t size = file_->GetLength(); |
342 if (size <= 0) | 387 if (size <= 0) |
343 return false; | 388 return false; |
344 std::vector<char> data(size); | 389 std::vector<char> data(size); |
345 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) | 390 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) |
346 return false; | 391 return false; |
347 return emf->InitFromData(data.data(), data.size()); | 392 return emf->InitFromData(data.data(), data.size()); |
348 } | 393 } |
349 | 394 |
395 // Postscript metafile subclass to override SafePlayback. | |
396 class PostScriptMetaFile : public LazyEmf { | |
397 public: | |
398 PostScriptMetaFile(const scoped_refptr<RefCountedTempDir>& temp_dir, | |
399 ScopedTempFile file) | |
400 : LazyEmf(temp_dir, std::move(file)) {} | |
401 ~PostScriptMetaFile() override; | |
402 | |
403 protected: | |
404 // MetafilePlayer: | |
405 bool SafePlayback(HDC hdc) const override; | |
406 | |
407 DISALLOW_COPY_AND_ASSIGN(PostScriptMetaFile); | |
408 }; | |
409 | |
410 PostScriptMetaFile::~PostScriptMetaFile() { | |
411 } | |
412 | |
413 bool PostScriptMetaFile::SafePlayback(HDC hdc) const { | |
414 // TODO(thestig): Fix destruction of metafiles. For some reasons | |
415 // instances of Emf are not deleted. https://crbug.com/260806 | |
416 // It's known that the Emf going to be played just once to a printer. So just | |
417 // release |file_| before returning. | |
418 Emf emf; | |
419 if (!LoadEmf(&emf)) { | |
420 Close(); | |
421 return false; | |
422 } | |
423 | |
424 { | |
425 // Ensure enumerator destruction before calling Close() below. | |
426 Emf::Enumerator emf_enum(emf, nullptr, nullptr); | |
427 for (const Emf::Record& record : emf_enum) { | |
428 auto* emf_record = record.record(); | |
429 if (emf_record->iType != EMR_GDICOMMENT) | |
430 continue; | |
431 | |
432 const EMRGDICOMMENT* comment = | |
433 reinterpret_cast<const EMRGDICOMMENT*>(emf_record); | |
434 const char* data = reinterpret_cast<const char*>(comment->Data); | |
435 const uint16_t* ptr = reinterpret_cast<const uint16_t*>(data); | |
436 int ret = ExtEscape(hdc, PASSTHROUGH, 2 + *ptr, data, 0, nullptr); | |
437 DCHECK_EQ(*ptr, ret); | |
438 } | |
439 } | |
440 Close(); | |
441 return true; | |
442 } | |
443 | |
350 PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient( | 444 PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient( |
351 base::WeakPtr<PdfConverterImpl> converter, | 445 base::WeakPtr<PdfConverterImpl> converter, |
352 const PdfRenderSettings& settings) | 446 const PdfRenderSettings& settings) |
353 : converter_(converter), settings_(settings) {} | 447 : converter_(converter), settings_(settings) {} |
354 | 448 |
355 PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {} | 449 PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {} |
356 | 450 |
357 void PdfConverterUtilityProcessHostClient::Start( | 451 void PdfConverterUtilityProcessHostClient::Start( |
358 const scoped_refptr<base::RefCountedMemory>& data, | 452 const scoped_refptr<base::RefCountedMemory>& data, |
359 const PdfConverter::StartCallback& start_callback) { | 453 const PdfConverter::StartCallback& start_callback) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 base::Bind(&PdfConverterImpl::RunCallback, converter_, | 551 base::Bind(&PdfConverterImpl::RunCallback, converter_, |
458 base::Bind(data.callback(), data.page_number(), scale_factor, | 552 base::Bind(data.callback(), data.page_number(), scale_factor, |
459 base::Passed(&file)))); | 553 base::Passed(&file)))); |
460 get_page_callbacks_.pop(); | 554 get_page_callbacks_.pop(); |
461 } | 555 } |
462 | 556 |
463 void PdfConverterUtilityProcessHostClient::Stop() { | 557 void PdfConverterUtilityProcessHostClient::Stop() { |
464 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 558 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
465 BrowserThread::PostTask( | 559 BrowserThread::PostTask( |
466 BrowserThread::IO, FROM_HERE, | 560 BrowserThread::IO, FROM_HERE, |
467 base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); | 561 base::Bind(&PdfConverterUtilityProcessHostClient::Stop, this)); |
468 return; | 562 return; |
469 } | 563 } |
470 SendStopMessage(); | 564 SendStopMessage(); |
471 } | 565 } |
472 | 566 |
473 void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) { | 567 void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) { |
474 OnFailed(); | 568 OnFailed(); |
475 } | 569 } |
476 | 570 |
477 void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed( | 571 void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed( |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 | 659 |
566 void PdfToEmfUtilityProcessHostClient::SendStartMessage( | 660 void PdfToEmfUtilityProcessHostClient::SendStartMessage( |
567 IPC::PlatformFileForTransit transit) { | 661 IPC::PlatformFileForTransit transit) { |
568 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_)); | 662 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_)); |
569 } | 663 } |
570 | 664 |
571 void PdfToEmfUtilityProcessHostClient::SendStopMessage() { | 665 void PdfToEmfUtilityProcessHostClient::SendStopMessage() { |
572 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); | 666 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); |
573 } | 667 } |
574 | 668 |
669 // Pdf to PostScript | |
670 PdfToPostScriptUtilityProcessHostClient:: | |
671 ~PdfToPostScriptUtilityProcessHostClient() {} | |
672 | |
673 bool PdfToPostScriptUtilityProcessHostClient::OnMessageReceived( | |
674 const IPC::Message& message) { | |
675 bool handled = true; | |
676 IPC_BEGIN_MESSAGE_MAP(PdfToPostScriptUtilityProcessHostClient, message) | |
677 IPC_MESSAGE_HANDLER( | |
678 ChromeUtilityHostMsg_RenderPDFPagesToPostScript_PageCount, OnPageCount) | |
679 IPC_MESSAGE_HANDLER( | |
680 ChromeUtilityHostMsg_RenderPDFPagesToPostScript_PageDone, OnPageDone) | |
681 IPC_MESSAGE_UNHANDLED(handled = false) | |
682 IPC_END_MESSAGE_MAP() | |
683 return handled; | |
684 } | |
685 | |
686 base::string16 PdfToPostScriptUtilityProcessHostClient::GetName() const { | |
687 return l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PS_CONVERTOR_NAME); | |
688 } | |
689 | |
690 std::unique_ptr<MetafilePlayer> | |
691 PdfToPostScriptUtilityProcessHostClient::GetFileFromTemp( | |
692 std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread> | |
693 temp_file) { | |
694 return base::MakeUnique<PostScriptMetaFile>(temp_dir_, std::move(temp_file)); | |
695 } | |
696 | |
697 void PdfToPostScriptUtilityProcessHostClient::SendGetPageMessage( | |
698 int page_number, | |
699 IPC::PlatformFileForTransit transit) { | |
700 Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_GetPage(page_number, | |
701 transit)); | |
702 } | |
703 | |
704 void PdfToPostScriptUtilityProcessHostClient::SendStartMessage( | |
705 IPC::PlatformFileForTransit transit) { | |
706 Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_Start(transit, | |
707 settings_)); | |
708 } | |
709 | |
710 void PdfToPostScriptUtilityProcessHostClient::SendStopMessage() { | |
711 Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_Stop()); | |
712 } | |
713 | |
714 void PdfToPostScriptUtilityProcessHostClient::OnPageDone(bool success) { | |
715 PdfConverterUtilityProcessHostClient::OnPageDone(success, 0.0f); | |
716 } | |
717 | |
575 // Pdf Converter Impl and subclasses | 718 // Pdf Converter Impl and subclasses |
576 PdfConverterImpl::PdfConverterImpl() {} | 719 PdfConverterImpl::PdfConverterImpl() {} |
577 | 720 |
578 PdfConverterImpl::~PdfConverterImpl() {} | 721 PdfConverterImpl::~PdfConverterImpl() {} |
579 | 722 |
580 void PdfConverterImpl::Start(const scoped_refptr<base::RefCountedMemory>& data, | 723 void PdfConverterImpl::Start(const scoped_refptr<base::RefCountedMemory>& data, |
581 const PdfRenderSettings& conversion_settings, | 724 const PdfRenderSettings& conversion_settings, |
582 const StartCallback& start_callback) { | 725 const StartCallback& start_callback) { |
583 DCHECK(!utility_client_.get()); | 726 DCHECK(!utility_client_.get()); |
584 } | 727 } |
(...skipping 18 matching lines...) Expand all Loading... | |
603 void PdfToEmfConverterImpl::Start( | 746 void PdfToEmfConverterImpl::Start( |
604 const scoped_refptr<base::RefCountedMemory>& data, | 747 const scoped_refptr<base::RefCountedMemory>& data, |
605 const PdfRenderSettings& conversion_settings, | 748 const PdfRenderSettings& conversion_settings, |
606 const StartCallback& start_callback) { | 749 const StartCallback& start_callback) { |
607 DCHECK(!utility_client_.get()); | 750 DCHECK(!utility_client_.get()); |
608 utility_client_ = new PdfToEmfUtilityProcessHostClient( | 751 utility_client_ = new PdfToEmfUtilityProcessHostClient( |
609 weak_ptr_factory_.GetWeakPtr(), conversion_settings); | 752 weak_ptr_factory_.GetWeakPtr(), conversion_settings); |
610 utility_client_->Start(data, start_callback); | 753 utility_client_->Start(data, start_callback); |
611 } | 754 } |
612 | 755 |
756 PdfToPostScriptConverterImpl::PdfToPostScriptConverterImpl() | |
757 : weak_ptr_factory_(this) {} | |
758 | |
759 PdfToPostScriptConverterImpl::~PdfToPostScriptConverterImpl() { | |
Vitaly Buka (NO REVIEWS)
2017/01/27 22:53:49
how about this way?
https://codereview.chromium.o
Vitaly Buka (NO REVIEWS)
2017/01/27 23:56:41
I think new messages are not worth of 200 lines of
| |
760 if (utility_client_.get()) | |
761 utility_client_->Stop(); | |
762 } | |
763 | |
764 void PdfToPostScriptConverterImpl::Start( | |
765 const scoped_refptr<base::RefCountedMemory>& data, | |
766 const PdfRenderSettings& conversion_settings, | |
767 const StartCallback& start_callback) { | |
768 DCHECK(!utility_client_.get()); | |
769 utility_client_ = new PdfToPostScriptUtilityProcessHostClient( | |
770 weak_ptr_factory_.GetWeakPtr(), conversion_settings); | |
771 utility_client_->Start(data, start_callback); | |
772 } | |
773 | |
613 } // namespace | 774 } // namespace |
614 | 775 |
615 PdfConverter::~PdfConverter() {} | 776 PdfConverter::~PdfConverter() {} |
616 | 777 |
617 // static | 778 // static |
618 std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToEmfConverter() { | 779 std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToEmfConverter() { |
619 return base::MakeUnique<PdfToEmfConverterImpl>(); | 780 return base::MakeUnique<PdfToEmfConverterImpl>(); |
620 } | 781 } |
621 | 782 |
783 // static | |
784 std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToPostScriptConverter() { | |
785 return base::MakeUnique<PdfToPostScriptConverterImpl>(); | |
786 } | |
787 | |
622 } // namespace printing | 788 } // namespace printing |
OLD | NEW |