Chromium Code Reviews| Index: chrome/browser/printing/pdf_to_emf_converter.cc |
| diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc |
| index d94ec49d8e5fd52d309ffa1b7838db440019403c..0c872fe032fcb2004e6e26b26f0b0653e1691c16 100644 |
| --- a/chrome/browser/printing/pdf_to_emf_converter.cc |
| +++ b/chrome/browser/printing/pdf_to_emf_converter.cc |
| @@ -77,7 +77,6 @@ class LazyEmf : public MetafilePlayer { |
| protected: |
| // MetafilePlayer: |
| bool SafePlayback(HDC hdc) const override; |
| - |
| void Close() const; |
| bool LoadEmf(Emf* emf) const; |
| @@ -112,7 +111,6 @@ class PdfConverterUtilityProcessHostClient |
| const PdfRenderSettings& settings); |
| void Start(const scoped_refptr<base::RefCountedMemory>& data, |
| - bool print_text_with_gdi, |
| const PdfConverter::StartCallback& start_callback); |
| void GetPage(int page_number, |
| @@ -152,7 +150,6 @@ class PdfConverterUtilityProcessHostClient |
| private: |
| int page_number_; |
| - |
| PdfConverter::GetPageCallback callback_; |
| ScopedTempFile file_; |
| @@ -169,8 +166,7 @@ class PdfConverterUtilityProcessHostClient |
| std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread> |
| temp_file) = 0; |
| // Send the messages to Start, GetPage, and Stop. |
| - virtual void SendStartMessage(IPC::PlatformFileForTransit transit, |
| - bool print_text_with_gdi) = 0; |
| + virtual void SendStartMessage(IPC::PlatformFileForTransit transit) = 0; |
| virtual void SendGetPageMessage(int page_number, |
| IPC::PlatformFileForTransit transit) = 0; |
| virtual void SendStopMessage() = 0; |
| @@ -180,10 +176,9 @@ class PdfConverterUtilityProcessHostClient |
| void OnPageDone(bool success, float scale_factor); |
| void OnFailed(); |
| - void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); |
| + void OnTempPdfReady(ScopedTempFile pdf); |
| void OnTempFileReady(GetPageCallbackData* callback_data, |
| ScopedTempFile temp_file); |
| - |
| scoped_refptr<RefCountedTempDir> temp_dir_; |
| // Used to suppress callbacks after PdfConverter is deleted. |
| @@ -220,8 +215,7 @@ class PdfToEmfUtilityProcessHostClient |
| std::unique_ptr<MetafilePlayer> GetFileFromTemp( |
| std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread> |
| temp_file) override; |
| - void SendStartMessage(IPC::PlatformFileForTransit transit, |
| - bool print_text_with_gdi) override; |
| + void SendStartMessage(IPC::PlatformFileForTransit transit) override; |
| void SendGetPageMessage(int page_number, |
| IPC::PlatformFileForTransit transit) override; |
| void SendStopMessage() override; |
| @@ -233,6 +227,35 @@ class PdfToEmfUtilityProcessHostClient |
| DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); |
| }; |
| +// Converts PDF into PostScript. |
| +class PdfToPostScriptUtilityProcessHostClient |
| + : public PdfConverterUtilityProcessHostClient { |
| + public: |
| + PdfToPostScriptUtilityProcessHostClient( |
| + base::WeakPtr<PdfConverterImpl> converter, |
| + const PdfRenderSettings& settings) |
| + : PdfConverterUtilityProcessHostClient(converter, settings) {} |
| + |
| + // UtilityProcessHostClient implementation. |
| + bool OnMessageReceived(const IPC::Message& message) override; |
| + |
| + private: |
| + // Helpers to send messages and set process name |
| + base::string16 GetName() const override; |
| + std::unique_ptr<MetafilePlayer> GetFileFromTemp( |
| + std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread> |
| + temp_file) override; |
| + void SendStartMessage(IPC::PlatformFileForTransit transit) override; |
| + void SendGetPageMessage(int page_number, |
| + IPC::PlatformFileForTransit transit) override; |
| + void SendStopMessage() override; |
| + |
| + // Additional message handler needed for Pdf to PostScript |
| + void OnPageDone(bool success); |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PdfToPostScriptUtilityProcessHostClient); |
| +}; |
| + |
| class PdfConverterImpl : public PdfConverter { |
| public: |
| PdfConverterImpl(); |
| @@ -241,7 +264,6 @@ class PdfConverterImpl : public PdfConverter { |
| void Start(const scoped_refptr<base::RefCountedMemory>& data, |
| const PdfRenderSettings& conversion_settings, |
| - bool print_text_with_gdi, |
| const StartCallback& start_callback) override; |
| void GetPage(int page_number, |
| @@ -265,15 +287,27 @@ class PdfToEmfConverterImpl : public PdfConverterImpl { |
| void Start(const scoped_refptr<base::RefCountedMemory>& data, |
| const PdfRenderSettings& conversion_settings, |
| - bool print_text_with_gdi, |
| const StartCallback& start_callback) override; |
| private: |
| base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); |
| }; |
| +class PdfToPostScriptConverterImpl : public PdfConverterImpl { |
| + public: |
| + PdfToPostScriptConverterImpl(); |
| + ~PdfToPostScriptConverterImpl() {} |
| + |
| + void Start(const scoped_refptr<base::RefCountedMemory>& data, |
| + const PdfRenderSettings& conversion_settings, |
| + const StartCallback& start_callback) override; |
| + |
| + private: |
| + base::WeakPtrFactory<PdfToPostScriptConverterImpl> weak_ptr_factory_; |
| + DISALLOW_COPY_AND_ASSIGN(PdfToPostScriptConverterImpl); |
| +}; |
| + |
| ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { |
| if (!temp_dir->get()) |
| *temp_dir = new RefCountedTempDir(); |
| @@ -352,6 +386,52 @@ bool LazyEmf::LoadEmf(Emf* emf) const { |
| return emf->InitFromData(data.data(), data.size()); |
| } |
| +// Postscript metafile subclass to override SafePlayback. |
| +class PostScriptMetaFile : public LazyEmf { |
| + public: |
| + PostScriptMetaFile(const scoped_refptr<RefCountedTempDir>& temp_dir, |
| + ScopedTempFile file) |
| + : LazyEmf(temp_dir, std::move(file)) {} |
| + ~PostScriptMetaFile() {} |
| + |
| + protected: |
| + // MetafilePlayer: |
| + bool SafePlayback(HDC hdc) const override; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PostScriptMetaFile); |
| +}; |
| + |
| +bool PostScriptMetaFile::SafePlayback(HDC hdc) const { |
| + // TODO(thestig): Fix destruction of metafiles. For some reasons |
| + // instances of Emf are not deleted. https://crbug.com/260806 |
| + // It's known that the Emf going to be played just once to a printer. So just |
| + // release |file_| before returning. |
| + Emf emf; |
| + if (!LoadEmf(&emf)) { |
| + Close(); |
| + return false; |
| + } |
| + |
| + { |
| + // Ensure enumerator destruction before calling Close() below. |
| + Emf::Enumerator emf_enum(emf, nullptr, nullptr); |
|
Vitaly Buka (NO REVIEWS)
2017/01/27 00:38:49
Why postscript is encoded as GDI comment into EMF?
rbpotter
2017/01/27 16:37:21
This was originally done by thestig@, so I am not
|
| + for (const Emf::Record& record : emf_enum) { |
| + auto* emf_record = record.record(); |
| + if (emf_record->iType != EMR_GDICOMMENT) |
| + continue; |
| + |
| + const EMRGDICOMMENT* comment = |
| + reinterpret_cast<const EMRGDICOMMENT*>(emf_record); |
| + const char* data = reinterpret_cast<const char*>(comment->Data); |
| + const uint16_t* ptr = reinterpret_cast<const uint16_t*>(data); |
| + int ret = ExtEscape(hdc, PASSTHROUGH, 2 + *ptr, data, 0, nullptr); |
| + DCHECK_EQ(*ptr, ret); |
| + } |
| + } |
| + Close(); |
| + return true; |
| +} |
| + |
| PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient( |
| base::WeakPtr<PdfConverterImpl> converter, |
| const PdfRenderSettings& settings) |
| @@ -361,13 +441,12 @@ PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {} |
| void PdfConverterUtilityProcessHostClient::Start( |
| const scoped_refptr<base::RefCountedMemory>& data, |
| - bool print_text_with_gdi, |
| const PdfConverter::StartCallback& start_callback) { |
| if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data, |
| - print_text_with_gdi, start_callback)); |
| + start_callback)); |
| return; |
| } |
| @@ -385,20 +464,16 @@ void PdfConverterUtilityProcessHostClient::Start( |
| BrowserThread::PostTaskAndReplyWithResult( |
| BrowserThread::FILE, FROM_HERE, |
| base::Bind(&CreateTempPdfFile, data, &temp_dir_), |
| - base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this, |
| - print_text_with_gdi)); |
| + base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this)); |
| } |
| -void PdfConverterUtilityProcessHostClient::OnTempPdfReady( |
| - bool print_text_with_gdi, |
| - ScopedTempFile pdf) { |
| +void PdfConverterUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| if (!utility_process_host_ || !pdf) |
| return OnFailed(); |
| // Should reply with OnPageCount(). |
| SendStartMessage( |
| - IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), |
| - print_text_with_gdi); |
| + IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false)); |
| } |
| void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) { |
| @@ -574,16 +649,60 @@ void PdfToEmfUtilityProcessHostClient::SendGetPageMessage( |
| } |
| void PdfToEmfUtilityProcessHostClient::SendStartMessage( |
| - IPC::PlatformFileForTransit transit, |
| - bool print_text_with_gdi) { |
| - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_, |
| - print_text_with_gdi)); |
| + IPC::PlatformFileForTransit transit) { |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_)); |
| } |
| void PdfToEmfUtilityProcessHostClient::SendStopMessage() { |
| Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); |
| } |
| +// Pdf to PostScript |
| +bool PdfToPostScriptUtilityProcessHostClient::OnMessageReceived( |
| + const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PdfToPostScriptUtilityProcessHostClient, message) |
| + IPC_MESSAGE_HANDLER( |
| + ChromeUtilityHostMsg_RenderPDFPagesToPostScript_PageCount, OnPageCount) |
| + IPC_MESSAGE_HANDLER( |
| + ChromeUtilityHostMsg_RenderPDFPagesToPostScript_PageDone, OnPageDone) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +base::string16 PdfToPostScriptUtilityProcessHostClient::GetName() const { |
| + return l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PS_CONVERTOR_NAME); |
| +} |
| + |
| +std::unique_ptr<MetafilePlayer> |
| +PdfToPostScriptUtilityProcessHostClient::GetFileFromTemp( |
| + std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread> |
| + temp_file) { |
| + return base::MakeUnique<PostScriptMetaFile>(temp_dir_, std::move(temp_file)); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::SendGetPageMessage( |
| + int page_number, |
| + IPC::PlatformFileForTransit transit) { |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_GetPage(page_number, |
| + transit)); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::SendStartMessage( |
| + IPC::PlatformFileForTransit transit) { |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_Start(transit, |
| + settings_)); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::SendStopMessage() { |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_Stop()); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnPageDone(bool success) { |
|
Vitaly Buka (NO REVIEWS)
2017/01/27 00:38:49
Maybe we can have single PdfConverterUtilityProces
rbpotter
2017/01/27 16:37:21
Sorry, I am not sure what you mean exactly. Do you
|
| + PdfConverterUtilityProcessHostClient::OnPageDone(success, 0.0f); |
| +} |
| + |
| // Pdf Converter Impl and subclasses |
| PdfConverterImpl::PdfConverterImpl() {} |
| @@ -591,7 +710,6 @@ PdfConverterImpl::~PdfConverterImpl() {} |
| void PdfConverterImpl::Start(const scoped_refptr<base::RefCountedMemory>& data, |
| const PdfRenderSettings& conversion_settings, |
| - bool print_text_with_gdi, |
| const StartCallback& start_callback) { |
| DCHECK(!utility_client_.get()); |
| } |
| @@ -616,12 +734,24 @@ PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { |
| void PdfToEmfConverterImpl::Start( |
| const scoped_refptr<base::RefCountedMemory>& data, |
| const PdfRenderSettings& conversion_settings, |
| - bool print_text_with_gdi, |
| const StartCallback& start_callback) { |
| DCHECK(!utility_client_.get()); |
| utility_client_ = new PdfToEmfUtilityProcessHostClient( |
| weak_ptr_factory_.GetWeakPtr(), conversion_settings); |
| - utility_client_->Start(data, print_text_with_gdi, start_callback); |
| + utility_client_->Start(data, start_callback); |
| +} |
| + |
| +PdfToPostScriptConverterImpl::PdfToPostScriptConverterImpl() |
| + : weak_ptr_factory_(this) {} |
| + |
| +void PdfToPostScriptConverterImpl::Start( |
| + const scoped_refptr<base::RefCountedMemory>& data, |
| + const PdfRenderSettings& conversion_settings, |
| + const StartCallback& start_callback) { |
| + DCHECK(!utility_client_.get()); |
|
Vitaly Buka (NO REVIEWS)
2017/01/27 00:38:49
There is also https://cs.chromium.org/chromium/src
rbpotter
2017/01/27 16:37:21
Should we add postscript printing there now or in
|
| + utility_client_ = new PdfToPostScriptUtilityProcessHostClient( |
| + weak_ptr_factory_.GetWeakPtr(), conversion_settings); |
| + utility_client_->Start(data, start_callback); |
| } |
| } // namespace |
| @@ -633,4 +763,9 @@ std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToEmfConverter() { |
| return base::MakeUnique<PdfToEmfConverterImpl>(); |
| } |
| +// static |
| +std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToPostScriptConverter() { |
| + return base::MakeUnique<PdfToPostScriptConverterImpl>(); |
| +} |
| + |
| } // namespace printing |