| 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..84a9c21eac7c5e640742ffc0663d5a5c81e966f4 100644
|
| --- a/chrome/browser/printing/pdf_to_emf_converter.cc
|
| +++ b/chrome/browser/printing/pdf_to_emf_converter.cc
|
| @@ -91,6 +91,21 @@ class LazyEmf : public MetafilePlayer {
|
| DISALLOW_COPY_AND_ASSIGN(LazyEmf);
|
| };
|
|
|
| +// 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);
|
| +};
|
| +
|
| // Class for converting PDF to another format for printing (Emf, Postscript).
|
| // Class uses 3 threads: UI, IO and FILE.
|
| // Internal workflow is following:
|
| @@ -160,18 +175,20 @@ class PdfConverterUtilityProcessHostClient
|
|
|
| ~PdfConverterUtilityProcessHostClient() override;
|
|
|
| + bool OnMessageReceived(const IPC::Message& message) override;
|
| +
|
| // Helper functions: must be overridden by subclasses
|
| // Set the process name
|
| - virtual base::string16 GetName() const = 0;
|
| + virtual base::string16 GetName() const;
|
| // Create a metafileplayer subclass file from a temporary file.
|
| virtual std::unique_ptr<MetafilePlayer> GetFileFromTemp(
|
| std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
|
| - temp_file) = 0;
|
| + temp_file);
|
| // Send the messages to Start, GetPage, and Stop.
|
| - virtual void SendStartMessage(IPC::PlatformFileForTransit transit) = 0;
|
| + virtual void SendStartMessage(IPC::PlatformFileForTransit transit);
|
| virtual void SendGetPageMessage(int page_number,
|
| - IPC::PlatformFileForTransit transit) = 0;
|
| - virtual void SendStopMessage() = 0;
|
| + IPC::PlatformFileForTransit transit);
|
| + virtual void SendStopMessage();
|
|
|
| // Message handlers:
|
| void OnPageCount(int page_count);
|
| @@ -182,6 +199,10 @@ class PdfConverterUtilityProcessHostClient
|
| void OnTempFileReady(GetPageCallbackData* callback_data,
|
| ScopedTempFile temp_file);
|
|
|
| + // Additional message handler needed for Pdf to Emf
|
| + void OnPreCacheFontCharacters(const LOGFONT& log_font,
|
| + const base::string16& characters);
|
| +
|
| scoped_refptr<RefCountedTempDir> temp_dir_;
|
|
|
| // Used to suppress callbacks after PdfConverter is deleted.
|
| @@ -199,46 +220,35 @@ class PdfConverterUtilityProcessHostClient
|
| // Use containers that keeps element pointers valid after push() and pop().
|
| using GetPageCallbacks = std::queue<GetPageCallbackData>;
|
| GetPageCallbacks get_page_callbacks_;
|
| -};
|
| -
|
| -// Converts PDF into Emf.
|
| -class PdfToEmfUtilityProcessHostClient
|
| - : public PdfConverterUtilityProcessHostClient {
|
| - public:
|
| - PdfToEmfUtilityProcessHostClient(base::WeakPtr<PdfConverterImpl> converter,
|
| - const PdfRenderSettings& settings)
|
| - : PdfConverterUtilityProcessHostClient(converter, settings) {}
|
| -
|
| - bool OnMessageReceived(const IPC::Message& message) override;
|
|
|
| - private:
|
| - ~PdfToEmfUtilityProcessHostClient() 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 Emf
|
| - void OnPreCacheFontCharacters(const LOGFONT& log_font,
|
| - const base::string16& characters);
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
|
| + DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient);
|
| };
|
|
|
| +std::unique_ptr<MetafilePlayer>
|
| +PdfConverterUtilityProcessHostClient::GetFileFromTemp(
|
| + std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
|
| + temp_file) {
|
| + if (settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
|
| + settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3) {
|
| + return base::MakeUnique<PostScriptMetaFile>(temp_dir_,
|
| + std::move(temp_file));
|
| + }
|
| + return base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_file));
|
| +}
|
| +
|
| class PdfConverterImpl : public PdfConverter {
|
| public:
|
| PdfConverterImpl();
|
|
|
| ~PdfConverterImpl() override;
|
|
|
| + base::WeakPtr<PdfConverterImpl> GetWeakPtr() {
|
| + return weak_ptr_factory_.GetWeakPtr();
|
| + }
|
| +
|
| void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
| const PdfRenderSettings& conversion_settings,
|
| - const StartCallback& start_callback) override;
|
| + const StartCallback& start_callback);
|
|
|
| void GetPage(int page_number,
|
| const GetPageCallback& get_page_callback) override;
|
| @@ -246,27 +256,17 @@ class PdfConverterImpl : public PdfConverter {
|
| // Helps to cancel callbacks if this object is destroyed.
|
| void RunCallback(const base::Closure& callback);
|
|
|
| - protected:
|
| - scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
|
| + void Start(
|
| + const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
|
| + const scoped_refptr<base::RefCountedMemory>& data,
|
| + const StartCallback& start_callback);
|
|
|
| private:
|
| - DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl);
|
| -};
|
| -
|
| -class PdfToEmfConverterImpl : public PdfConverterImpl {
|
| - public:
|
| - PdfToEmfConverterImpl();
|
| -
|
| - ~PdfToEmfConverterImpl() override;
|
| -
|
| - void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
| - const PdfRenderSettings& conversion_settings,
|
| - const StartCallback& start_callback) override;
|
| + scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
|
|
|
| - private:
|
| - base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_;
|
| + base::WeakPtrFactory<PdfConverterImpl> weak_ptr_factory_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl);
|
| + DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl);
|
| };
|
|
|
| ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
|
| @@ -347,6 +347,40 @@ bool LazyEmf::LoadEmf(Emf* emf) const {
|
| return emf->InitFromData(data.data(), data.size());
|
| }
|
|
|
| +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 +498,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();
|
| @@ -495,10 +529,8 @@ void PdfConverterUtilityProcessHostClient::OnFailed() {
|
| utility_process_host_.reset();
|
| }
|
|
|
| -// PDF to Emf
|
| -PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {}
|
|
|
| -void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
|
| +void PdfConverterUtilityProcessHostClient::OnPreCacheFontCharacters(
|
| const LOGFONT& font,
|
| const base::string16& str) {
|
| // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
|
| @@ -530,10 +562,10 @@ void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
|
| DeleteEnhMetaFile(metafile);
|
| }
|
|
|
| -bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
|
| +bool PdfConverterUtilityProcessHostClient::OnMessageReceived(
|
| const IPC::Message& message) {
|
| bool handled = true;
|
| - IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
|
| + IPC_BEGIN_MESSAGE_MAP(PdfConverterUtilityProcessHostClient, message)
|
| IPC_MESSAGE_HANDLER(
|
| ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
|
| IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
|
| @@ -545,42 +577,44 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
|
| return handled;
|
| }
|
|
|
| -base::string16 PdfToEmfUtilityProcessHostClient::GetName() const {
|
| - return l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME);
|
| +base::string16 PdfConverterUtilityProcessHostClient::GetName() const {
|
| + return l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PDF_CONVERTOR_NAME);
|
| }
|
|
|
| -std::unique_ptr<MetafilePlayer>
|
| -PdfToEmfUtilityProcessHostClient::GetFileFromTemp(
|
| - std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
|
| - temp_file) {
|
| - return base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_file));
|
| -}
|
| -
|
| -void PdfToEmfUtilityProcessHostClient::SendGetPageMessage(
|
| +void PdfConverterUtilityProcessHostClient::SendGetPageMessage(
|
| int page_number,
|
| IPC::PlatformFileForTransit transit) {
|
| Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number,
|
| transit));
|
| }
|
|
|
| -void PdfToEmfUtilityProcessHostClient::SendStartMessage(
|
| +void PdfConverterUtilityProcessHostClient::SendStartMessage(
|
| IPC::PlatformFileForTransit transit) {
|
| Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_));
|
| }
|
|
|
| -void PdfToEmfUtilityProcessHostClient::SendStopMessage() {
|
| +void PdfConverterUtilityProcessHostClient::SendStopMessage() {
|
| Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
|
| }
|
| -
|
| +/*void PdfToPostScriptUtilityProcessHostClient::OnPageDone(bool success) {
|
| + PdfConverterUtilityProcessHostClient::OnPageDone(success, 0.0f);
|
| +}
|
| +*/
|
| // Pdf Converter Impl and subclasses
|
| -PdfConverterImpl::PdfConverterImpl() {}
|
| +PdfConverterImpl::PdfConverterImpl() : weak_ptr_factory_(this) {}
|
|
|
| -PdfConverterImpl::~PdfConverterImpl() {}
|
| +PdfConverterImpl::~PdfConverterImpl() {
|
| + if (utility_client_.get())
|
| + utility_client_->Stop();
|
| +}
|
|
|
| -void PdfConverterImpl::Start(const scoped_refptr<base::RefCountedMemory>& data,
|
| - const PdfRenderSettings& conversion_settings,
|
| - const StartCallback& start_callback) {
|
| - DCHECK(!utility_client_.get());
|
| +void PdfConverterImpl::Start(
|
| + const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
|
| + const scoped_refptr<base::RefCountedMemory>& data,
|
| + const StartCallback& start_callback) {
|
| + DCHECK(!utility_client_);
|
| + utility_client_ = utility_client;
|
| + utility_client_->Start(data, start_callback);
|
| }
|
|
|
| void PdfConverterImpl::GetPage(int page_number,
|
| @@ -593,30 +627,22 @@ void PdfConverterImpl::RunCallback(const base::Closure& callback) {
|
| callback.Run();
|
| }
|
|
|
| -PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) {}
|
| -
|
| -PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
|
| - if (utility_client_.get())
|
| - utility_client_->Stop();
|
| -}
|
| -
|
| -void PdfToEmfConverterImpl::Start(
|
| - const scoped_refptr<base::RefCountedMemory>& data,
|
| - const PdfRenderSettings& conversion_settings,
|
| - const StartCallback& start_callback) {
|
| - DCHECK(!utility_client_.get());
|
| - utility_client_ = new PdfToEmfUtilityProcessHostClient(
|
| - weak_ptr_factory_.GetWeakPtr(), conversion_settings);
|
| - utility_client_->Start(data, start_callback);
|
| -}
|
| -
|
| } // namespace
|
|
|
| PdfConverter::~PdfConverter() {}
|
|
|
| // static
|
| -std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToEmfConverter() {
|
| - return base::MakeUnique<PdfToEmfConverterImpl>();
|
| +std::unique_ptr<PdfConverter> PdfConverter::StartPdfConverter(
|
| + const scoped_refptr<base::RefCountedMemory>& data,
|
| + const PdfRenderSettings& conversion_settings,
|
| + const StartCallback& start_callback) {
|
| + std::unique_ptr<PdfConverterImpl> converter =
|
| + base::MakeUnique<PdfConverterImpl>();
|
| + converter->Start(
|
| + new PdfConverterUtilityProcessHostClient(converter->GetWeakPtr(),
|
| + conversion_settings),
|
| + data, start_callback);
|
| + return std::move(converter);
|
| }
|
|
|
| } // namespace printing
|
|
|