Chromium Code Reviews| 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 |