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

Unified Diff: chrome/browser/printing/pdf_to_emf_converter.cc

Issue 2633573002: Add Postscript Printing (Closed)
Patch Set: Rebase Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698