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 64dfd014402e59a81918ff4c907530908f204542..623f74a766567d834af74188de8055b700c8a5f3 100644 |
--- a/chrome/browser/printing/pdf_to_emf_converter.cc |
+++ b/chrome/browser/printing/pdf_to_emf_converter.cc |
@@ -230,6 +230,37 @@ 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: |
+ ~PdfToPostScriptUtilityProcessHostClient() override; |
+ |
+ // 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(); |
@@ -269,6 +300,20 @@ class PdfToEmfConverterImpl : public PdfConverterImpl { |
DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); |
}; |
+class PdfToPostScriptConverterImpl : public PdfConverterImpl { |
+ public: |
+ PdfToPostScriptConverterImpl(); |
+ ~PdfToPostScriptConverterImpl() override; |
+ |
+ 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(); |
@@ -347,6 +392,55 @@ 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() override; |
+ |
+ protected: |
+ // MetafilePlayer: |
+ bool SafePlayback(HDC hdc) const override; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PostScriptMetaFile); |
+}; |
+ |
+PostScriptMetaFile::~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); |
+ 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) |
@@ -464,7 +558,7 @@ void PdfConverterUtilityProcessHostClient::Stop() { |
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
- base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); |
+ base::Bind(&PdfConverterUtilityProcessHostClient::Stop, this)); |
return; |
} |
SendStopMessage(); |
@@ -572,6 +666,55 @@ void PdfToEmfUtilityProcessHostClient::SendStopMessage() { |
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); |
} |
+// Pdf to PostScript |
+PdfToPostScriptUtilityProcessHostClient:: |
+ ~PdfToPostScriptUtilityProcessHostClient() {} |
+ |
+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) { |
+ PdfConverterUtilityProcessHostClient::OnPageDone(success, 0.0f); |
+} |
+ |
// Pdf Converter Impl and subclasses |
PdfConverterImpl::PdfConverterImpl() {} |
@@ -610,6 +753,24 @@ void PdfToEmfConverterImpl::Start( |
utility_client_->Start(data, start_callback); |
} |
+PdfToPostScriptConverterImpl::PdfToPostScriptConverterImpl() |
+ : weak_ptr_factory_(this) {} |
+ |
+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
|
+ if (utility_client_.get()) |
+ utility_client_->Stop(); |
+} |
+ |
+void PdfToPostScriptConverterImpl::Start( |
+ const scoped_refptr<base::RefCountedMemory>& data, |
+ const PdfRenderSettings& conversion_settings, |
+ const StartCallback& start_callback) { |
+ DCHECK(!utility_client_.get()); |
+ utility_client_ = new PdfToPostScriptUtilityProcessHostClient( |
+ weak_ptr_factory_.GetWeakPtr(), conversion_settings); |
+ utility_client_->Start(data, start_callback); |
+} |
+ |
} // namespace |
PdfConverter::~PdfConverter() {} |
@@ -619,4 +780,9 @@ std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToEmfConverter() { |
return base::MakeUnique<PdfToEmfConverterImpl>(); |
} |
+// static |
+std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToPostScriptConverter() { |
+ return base::MakeUnique<PdfToPostScriptConverterImpl>(); |
+} |
+ |
} // namespace printing |