diff --git a/atom/common/common_message_generator.cc b/atom/common/common_message_generator.cc index 854fc8778e9c..6b14637cf3c3 100644 --- a/atom/common/common_message_generator.cc +++ b/atom/common/common_message_generator.cc @@ -31,4 +31,3 @@ namespace IPC { namespace IPC { #include "atom/common/common_message_generator.h" } // namespace IPC - diff --git a/atom/common/common_message_generator.h b/atom/common/common_message_generator.h index a63c40b96234..8b41a17f29b0 100644 --- a/atom/common/common_message_generator.h +++ b/atom/common/common_message_generator.h @@ -9,4 +9,5 @@ #include "chrome/common/tts_messages.h" #include "chrome/common/widevine_cdm_messages.h" #include "chrome/common/chrome_utility_messages.h" +#include "chrome/common/chrome_utility_printing_messages.h" #include "components/pdf/common/pdf_messages.h" diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc index b06c3a06409d..a35e80cea232 100644 --- a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc @@ -18,10 +18,9 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/common/chrome_utility_messages.h" -#include "chrome/common/print_messages.h" +#include "chrome/common/chrome_utility_printing_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/utility_process_host.h" @@ -30,13 +29,13 @@ #include "printing/pdf_render_settings.h" #include "ui/base/l10n/l10n_util.h" +using content::BrowserThread; + namespace printing { namespace { -using content::BrowserThread; - -class PdfToEmfConverterImpl; +class PdfConverterImpl; // Allows to delete temporary directory after all temporary files created inside // are closed. Windows cannot delete directory with opened files. Directory is @@ -59,8 +58,8 @@ class RefCountedTempDir DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir); }; -typedef std::unique_ptr - ScopedTempFile; +using ScopedTempFile = + std::unique_ptr; // Wrapper for Emf to keep only file handle in memory, and load actual data only // on playback. Emf::InitFromFile() can play metafile directly from disk, but it @@ -74,21 +73,39 @@ class LazyEmf : public MetafilePlayer { } ~LazyEmf() override { Close(); } + protected: + // MetafilePlayer: bool SafePlayback(HDC hdc) const override; - bool GetDataAsVector(std::vector* buffer) const override; - bool SaveTo(base::File* file) const override; - private: void Close() const; bool LoadEmf(Emf* emf) const; + private: mutable scoped_refptr temp_dir_; mutable ScopedTempFile file_; // Mutable because of consts in base class. + bool GetDataAsVector(std::vector* buffer) const override; + bool SaveTo(base::File* file) const override; + DISALLOW_COPY_AND_ASSIGN(LazyEmf); }; -// Converts PDF into EMF. +// Postscript metafile subclass to override SafePlayback. +class PostScriptMetaFile : public LazyEmf { + public: + PostScriptMetaFile(const scoped_refptr& 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: // 1. Create instance on the UI thread. (files_, settings_,) @@ -101,36 +118,33 @@ class LazyEmf : public MetafilePlayer { // // All these steps work sequentially, so no data should be accessed // simultaneously by several threads. -class PdfToEmfUtilityProcessHostClient +class PdfConverterUtilityProcessHostClient : public content::UtilityProcessHostClient { public: - PdfToEmfUtilityProcessHostClient( - base::WeakPtr converter, + PdfConverterUtilityProcessHostClient( + base::WeakPtr converter, const PdfRenderSettings& settings); void Start(const scoped_refptr& data, - bool print_text_with_gdi, - const PdfToEmfConverter::StartCallback& start_callback); + const PdfConverter::StartCallback& start_callback); void GetPage(int page_number, - const PdfToEmfConverter::GetPageCallback& get_page_callback); + const PdfConverter::GetPageCallback& get_page_callback); void Stop(); + // UtilityProcessHostClient implementation. + void OnProcessCrashed(int exit_code) override; + void OnProcessLaunchFailed(int exit_code) override; + // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters // sync message replies. bool Send(IPC::Message* msg); - // UtilityProcessHostClient implementation. - void OnProcessCrashed(int exit_code) override; - void OnProcessLaunchFailed(int exit_code) override; - bool OnMessageReceived(const IPC::Message& message) override; - - private: + protected: class GetPageCallbackData { public: - GetPageCallbackData(int page_number, - PdfToEmfConverter::GetPageCallback callback) + GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback) : page_number_(page_number), callback_(callback) {} GetPageCallbackData(GetPageCallbackData&& other) { @@ -140,45 +154,62 @@ class PdfToEmfUtilityProcessHostClient GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { page_number_ = rhs.page_number_; callback_ = rhs.callback_; - emf_ = std::move(rhs.emf_); + file_ = std::move(rhs.file_); return *this; } int page_number() const { return page_number_; } - const PdfToEmfConverter::GetPageCallback& callback() const { - return callback_; - } - ScopedTempFile TakeEmf() { return std::move(emf_); } - void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); } + const PdfConverter::GetPageCallback& callback() const { return callback_; } + ScopedTempFile TakeFile() { return std::move(file_); } + void set_file(ScopedTempFile file) { file_ = std::move(file); } private: int page_number_; - PdfToEmfConverter::GetPageCallback callback_; - ScopedTempFile emf_; + + PdfConverter::GetPageCallback callback_; + ScopedTempFile file_; DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); }; - ~PdfToEmfUtilityProcessHostClient() override; + ~PdfConverterUtilityProcessHostClient() override; - // Message handlers. + bool OnMessageReceived(const IPC::Message& message) override; + + // Helper functions: must be overridden by subclasses + // Set the process name + virtual base::string16 GetName() const; + // Create a metafileplayer subclass file from a temporary file. + virtual std::unique_ptr GetFileFromTemp( + std::unique_ptr + temp_file); + // Send the messages to Start, GetPage, and Stop. + virtual void SendStartMessage(IPC::PlatformFileForTransit transit); + virtual void SendGetPageMessage(int page_number, + IPC::PlatformFileForTransit transit); + virtual void SendStopMessage(); + + // Message handlers: void OnPageCount(int page_count); void OnPageDone(bool success, float scale_factor); + + void OnFailed(); + void OnTempPdfReady(ScopedTempFile pdf); + 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); - void OnFailed(); - void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); - void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); - scoped_refptr temp_dir_; - // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. - base::WeakPtr converter_; + // Used to suppress callbacks after PdfConverter is deleted. + base::WeakPtr converter_; PdfRenderSettings settings_; // Document loaded callback. - PdfToEmfConverter::StartCallback start_callback_; + PdfConverter::StartCallback start_callback_; // Process host for IPC. base::WeakPtr utility_process_host_; @@ -186,22 +217,37 @@ class PdfToEmfUtilityProcessHostClient // Queue of callbacks for GetPage() requests. Utility process should reply // with PageDone in the same order as requests were received. // Use containers that keeps element pointers valid after push() and pop(). - typedef std::queue GetPageCallbacks; + using GetPageCallbacks = std::queue; GetPageCallbacks get_page_callbacks_; - DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); + DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient); }; -class PdfToEmfConverterImpl : public PdfToEmfConverter { - public: - PdfToEmfConverterImpl(); +std::unique_ptr +PdfConverterUtilityProcessHostClient::GetFileFromTemp( + std::unique_ptr + temp_file) { + if (settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 || + settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3) { + return base::MakeUnique(temp_dir_, + std::move(temp_file)); + } + return base::MakeUnique(temp_dir_, std::move(temp_file)); +} - ~PdfToEmfConverterImpl() override; +class PdfConverterImpl : public PdfConverter { + public: + PdfConverterImpl(); + + ~PdfConverterImpl() override; + + base::WeakPtr GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } void Start(const scoped_refptr& data, const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const StartCallback& start_callback) override; + const StartCallback& start_callback); void GetPage(int page_number, const GetPageCallback& get_page_callback) override; @@ -209,11 +255,17 @@ class PdfToEmfConverterImpl : public PdfToEmfConverter { // Helps to cancel callbacks if this object is destroyed. void RunCallback(const base::Closure& callback); - private: - scoped_refptr utility_client_; - base::WeakPtrFactory weak_ptr_factory_; + void Start( + const scoped_refptr& utility_client, + const scoped_refptr& data, + const StartCallback& start_callback); - DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); + private: + scoped_refptr utility_client_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl); }; ScopedTempFile CreateTempFile(scoped_refptr* temp_dir) { @@ -260,10 +312,10 @@ ScopedTempFile CreateTempPdfFile( bool LazyEmf::SafePlayback(HDC hdc) const { Emf emf; bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); - // TODO(vitalybuka): Fix destruction of metafiles. For some reasons - // instances of Emf are not deleted. crbug.com/411683 + // 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 here. + // release |file_| here. Close(); return result; } @@ -280,7 +332,7 @@ bool LazyEmf::SaveTo(base::File* file) const { void LazyEmf::Close() const { file_.reset(); - temp_dir_ = NULL; + temp_dir_ = nullptr; } bool LazyEmf::LoadEmf(Emf* emf) const { @@ -294,24 +346,55 @@ bool LazyEmf::LoadEmf(Emf* emf) const { return emf->InitFromData(data.data(), data.size()); } -PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( - base::WeakPtr converter, +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(emf_record); + const char* data = reinterpret_cast(comment->Data); + const uint16_t* ptr = reinterpret_cast(data); + int ret = ExtEscape(hdc, PASSTHROUGH, 2 + *ptr, data, 0, nullptr); + DCHECK_EQ(*ptr, ret); + } + } + Close(); + return true; +} + +PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient( + base::WeakPtr converter, const PdfRenderSettings& settings) - : converter_(converter), settings_(settings) { -} + : converter_(converter), settings_(settings) {} -PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { -} +PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {} -void PdfToEmfUtilityProcessHostClient::Start( +void PdfConverterUtilityProcessHostClient::Start( const scoped_refptr& data, - bool print_text_with_gdi, - const PdfToEmfConverter::StartCallback& start_callback) { + const PdfConverter::StartCallback& start_callback) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data, - print_text_with_gdi, start_callback)); + base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data, + start_callback)); return; } @@ -324,50 +407,41 @@ void PdfToEmfUtilityProcessHostClient::Start( utility_process_host_ = content::UtilityProcessHost::Create( this, base::ThreadTaskRunnerHandle::Get()) ->AsWeakPtr(); - utility_process_host_->SetName(base::ASCIIToUTF16( - "IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME")); + utility_process_host_->SetName(GetName()); BrowserThread::PostTaskAndReplyWithResult( BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempPdfFile, data, &temp_dir_), - base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, - print_text_with_gdi)); + base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this)); } -void PdfToEmfUtilityProcessHostClient::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(). - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( - IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, - print_text_with_gdi)); + SendStartMessage( + IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false)); } -void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { +void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (start_callback_.is_null()) return OnFailed(); - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&PdfToEmfConverterImpl::RunCallback, - converter_, + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&PdfConverterImpl::RunCallback, converter_, base::Bind(start_callback_, page_count))); start_callback_.Reset(); } -void PdfToEmfUtilityProcessHostClient::GetPage( +void PdfConverterUtilityProcessHostClient::GetPage( int page_number, - const PdfToEmfConverter::GetPageCallback& get_page_callback) { + const PdfConverter::GetPageCallback& get_page_callback) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage, - this, - page_number, - get_page_callback)); + BrowserThread::IO, FROM_HERE, + base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this, + page_number, get_page_callback)); return; } @@ -378,55 +452,84 @@ void PdfToEmfUtilityProcessHostClient::GetPage( return OnFailed(); BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::FILE, - FROM_HERE, - base::Bind(&CreateTempFile, &temp_dir_), - base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady, - this, + BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempFile, &temp_dir_), + base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this, &get_page_callbacks_.back())); } -void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( +void PdfConverterUtilityProcessHostClient::OnTempFileReady( GetPageCallbackData* callback_data, - ScopedTempFile emf) { + ScopedTempFile temp_file) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!utility_process_host_ || !emf) + if (!utility_process_host_ || !temp_file) return OnFailed(); IPC::PlatformFileForTransit transit = - IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false); - callback_data->set_emf(std::move(emf)); + IPC::GetPlatformFileForTransit(temp_file->GetPlatformFile(), false); + callback_data->set_file(std::move(temp_file)); // Should reply with OnPageDone(). - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( - callback_data->page_number(), transit)); + SendGetPageMessage(callback_data->page_number(), transit); } -void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, - float scale_factor) { +void PdfConverterUtilityProcessHostClient::OnPageDone(bool success, + float scale_factor) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (get_page_callbacks_.empty()) return OnFailed(); GetPageCallbackData& data = get_page_callbacks_.front(); - std::unique_ptr emf; + std::unique_ptr file; if (success) { - ScopedTempFile temp_emf = data.TakeEmf(); - if (!temp_emf) // Unexpected message from utility process. + ScopedTempFile temp_file = data.TakeFile(); + if (!temp_file) // Unexpected message from utility process. return OnFailed(); - emf = base::MakeUnique(temp_dir_, std::move(temp_emf)); + file = GetFileFromTemp(std::move(temp_file)); } - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&PdfToEmfConverterImpl::RunCallback, - converter_, - base::Bind(data.callback(), - data.page_number(), - scale_factor, - base::Passed(&emf)))); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&PdfConverterImpl::RunCallback, converter_, + base::Bind(data.callback(), data.page_number(), scale_factor, + base::Passed(&file)))); get_page_callbacks_.pop(); } -void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( +void PdfConverterUtilityProcessHostClient::Stop() { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PdfConverterUtilityProcessHostClient::Stop, this)); + return; + } + SendStopMessage(); +} + +void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) { + OnFailed(); +} + +void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed( + int exit_code) { + OnFailed(); +} + +bool PdfConverterUtilityProcessHostClient::Send(IPC::Message* msg) { + if (utility_process_host_) + return utility_process_host_->Send(msg); + delete msg; + return false; +} + +void PdfConverterUtilityProcessHostClient::OnFailed() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!start_callback_.is_null()) + OnPageCount(0); + while (!get_page_callbacks_.empty()) + OnPageDone(false, 0.0f); + utility_process_host_.reset(); +} + + +void PdfConverterUtilityProcessHostClient::OnPreCacheFontCharacters( const LOGFONT& font, const base::string16& str) { // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache @@ -458,29 +561,10 @@ void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( DeleteEnhMetaFile(metafile); } -void PdfToEmfUtilityProcessHostClient::Stop() { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); - return; - } - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); -} - -void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) { - OnFailed(); -} - -void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) { - OnFailed(); -} - -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, @@ -492,59 +576,69 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( return handled; } -bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { - if (utility_process_host_) - return utility_process_host_->Send(msg); - delete msg; - return false; +base::string16 PdfConverterUtilityProcessHostClient::GetName() const { + return L"ChromeUtilityProcessPDFConvertor"; } -void PdfToEmfUtilityProcessHostClient::OnFailed() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!start_callback_.is_null()) - OnPageCount(0); - while (!get_page_callbacks_.empty()) - OnPageDone(false, 0.0f); - utility_process_host_.reset(); +void PdfConverterUtilityProcessHostClient::SendGetPageMessage( + int page_number, + IPC::PlatformFileForTransit transit) { + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number, + transit)); } -PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { +void PdfConverterUtilityProcessHostClient::SendStartMessage( + IPC::PlatformFileForTransit transit) { + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_)); } -PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { +void PdfConverterUtilityProcessHostClient::SendStopMessage() { + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); +} + +// Pdf Converter Impl and subclasses +PdfConverterImpl::PdfConverterImpl() : weak_ptr_factory_(this) {} + +PdfConverterImpl::~PdfConverterImpl() { if (utility_client_.get()) utility_client_->Stop(); } -void PdfToEmfConverterImpl::Start( - const scoped_refptr& 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); +void PdfConverterImpl::Start( + const scoped_refptr& utility_client, + const scoped_refptr& data, + const StartCallback& start_callback) { + DCHECK(!utility_client_); + utility_client_ = utility_client; + utility_client_->Start(data, start_callback); } -void PdfToEmfConverterImpl::GetPage(int page_number, - const GetPageCallback& get_page_callback) { +void PdfConverterImpl::GetPage(int page_number, + const GetPageCallback& get_page_callback) { utility_client_->GetPage(page_number, get_page_callback); } -void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) { +void PdfConverterImpl::RunCallback(const base::Closure& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); callback.Run(); } } // namespace -PdfToEmfConverter::~PdfToEmfConverter() { -} +PdfConverter::~PdfConverter() {} // static -std::unique_ptr PdfToEmfConverter::CreateDefault() { - return std::unique_ptr(new PdfToEmfConverterImpl()); +std::unique_ptr PdfConverter::StartPdfConverter( + const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback) { + std::unique_ptr converter = + base::MakeUnique(); + converter->Start( + new PdfConverterUtilityProcessHostClient(converter->GetWeakPtr(), + conversion_settings), + data, start_callback); + return std::move(converter); } } // namespace printing diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h index 1f5271527406..9990400a7bce 100644 --- a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h @@ -15,24 +15,21 @@ namespace printing { class MetafilePlayer; struct PdfRenderSettings; -class PdfToEmfConverter { +class PdfConverter { public: - typedef base::Callback StartCallback; - typedef base::Callback emf)> - GetPageCallback; - - virtual ~PdfToEmfConverter(); - - static std::unique_ptr CreateDefault(); + using StartCallback = base::Callback; + using GetPageCallback = + base::Callback file)>; + virtual ~PdfConverter(); // Starts conversion of PDF provided as |data|. Calls |start_callback| // with positive |page_count|. |page_count| is 0 if initialization failed. - virtual void Start(const scoped_refptr& data, - const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const StartCallback& start_callback) = 0; + static std::unique_ptr StartPdfConverter( + const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback); // Requests conversion of the page. |page_number| is 0-base page number in // PDF provided in Start() call. @@ -41,7 +38,6 @@ class PdfToEmfConverter { virtual void GetPage(int page_number, const GetPageCallback& get_page_callback) = 0; }; - } // namespace printing #endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_ diff --git a/chromium_src/chrome/browser/printing/print_job.cc b/chromium_src/chrome/browser/printing/print_job.cc index 8a969618bdb1..c5038f370de7 100644 --- a/chromium_src/chrome/browser/printing/print_job.cc +++ b/chromium_src/chrome/browser/printing/print_job.cc @@ -223,27 +223,23 @@ PrintedDocument* PrintJob::document() const { } #if defined(OS_WIN) - -class PrintJob::PdfToEmfState { +class PrintJob::PdfConversionState { public: - PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area) + PdfConversionState(gfx::Size page_size, gfx::Rect content_area) : page_count_(0), current_page_(0), pages_in_progress_(0), page_size_(page_size), - content_area_(content_area), - converter_(PdfToEmfConverter::CreateDefault()) {} + content_area_(content_area) {} void Start(const scoped_refptr& data, const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const PdfToEmfConverter::StartCallback& start_callback) { - converter_->Start(data, conversion_settings, print_text_with_gdi, - start_callback); + const PdfConverter::StartCallback& start_callback) { + converter_ = PdfConverter::StartPdfConverter( + data, conversion_settings, start_callback); } - void GetMorePages( - const PdfToEmfConverter::GetPageCallback& get_page_callback) { + void GetMorePages(const PdfConverter::GetPageCallback& get_page_callback) { const int kMaxNumberOfTempFilesPerDocument = 3; while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument && current_page_ < page_count_) { @@ -252,8 +248,7 @@ class PrintJob::PdfToEmfState { } } - void OnPageProcessed( - const PdfToEmfConverter::GetPageCallback& get_page_callback) { + void OnPageProcessed(const PdfConverter::GetPageCallback& get_page_callback) { --pages_in_progress_; GetMorePages(get_page_callback); // Release converter if we don't need this any more. @@ -271,7 +266,7 @@ class PrintJob::PdfToEmfState { int pages_in_progress_; gfx::Size page_size_; gfx::Rect content_area_; - std::unique_ptr converter_; + std::unique_ptr converter_; }; void PrintJob::AppendPrintedPage(int page_number) { @@ -283,46 +278,67 @@ void PrintJob::StartPdfToEmfConversion( const gfx::Size& page_size, const gfx::Rect& content_area, bool print_text_with_gdi) { - DCHECK(!pdf_to_emf_state_); - pdf_to_emf_state_ = base::MakeUnique(page_size, content_area); + DCHECK(!pdf_conversion_state_); + pdf_conversion_state_ = + base::MakeUnique(page_size, content_area); const int kPrinterDpi = settings().dpi(); - pdf_to_emf_state_->Start( - bytes, PdfRenderSettings(content_area, kPrinterDpi, true), - print_text_with_gdi, base::Bind(&PrintJob::OnPdfToEmfStarted, this)); + PdfRenderSettings settings( + content_area, gfx::Point(0, 0), kPrinterDpi, /*autorotate=*/true, + print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT + : PdfRenderSettings::Mode::NORMAL); + pdf_conversion_state_->Start( + bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this)); } -void PrintJob::OnPdfToEmfStarted(int page_count) { +void PrintJob::OnPdfConversionStarted(int page_count) { if (page_count <= 0) { - pdf_to_emf_state_.reset(); + pdf_conversion_state_.reset(); Cancel(); return; } - pdf_to_emf_state_->set_page_count(page_count); - pdf_to_emf_state_->GetMorePages( - base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); + pdf_conversion_state_->set_page_count(page_count); + pdf_conversion_state_->GetMorePages( + base::Bind(&PrintJob::OnPdfPageConverted, this)); } -void PrintJob::OnPdfToEmfPageConverted(int page_number, - float scale_factor, - std::unique_ptr emf) { - DCHECK(pdf_to_emf_state_); - if (!document_.get() || !emf || page_number < 0 || +void PrintJob::OnPdfPageConverted(int page_number, + float scale_factor, + std::unique_ptr metafile) { + DCHECK(pdf_conversion_state_); + if (!document_.get() || !metafile || page_number < 0 || static_cast(page_number) >= pdf_page_mapping_.size()) { - pdf_to_emf_state_.reset(); + pdf_conversion_state_.reset(); Cancel(); return; } // Update the rendered document. It will send notifications to the listener. - document_->SetPage(pdf_page_mapping_[page_number], std::move(emf), - scale_factor, pdf_to_emf_state_->page_size(), - pdf_to_emf_state_->content_area()); + document_->SetPage(pdf_page_mapping_[page_number], std::move(metafile), + scale_factor, pdf_conversion_state_->page_size(), + pdf_conversion_state_->content_area()); - pdf_to_emf_state_->GetMorePages( - base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); + pdf_conversion_state_->GetMorePages( + base::Bind(&PrintJob::OnPdfPageConverted, this)); } -#endif // OS_WIN +void PrintJob::StartPdfToPostScriptConversion( + const scoped_refptr& bytes, + const gfx::Rect& content_area, + const gfx::Point& physical_offsets, + bool ps_level2) { + DCHECK(!pdf_conversion_state_); + pdf_conversion_state_ = base::MakeUnique( + gfx::Size(), gfx::Rect()); + const int kPrinterDpi = settings().dpi(); + PdfRenderSettings settings( + content_area, physical_offsets, kPrinterDpi, true /* autorotate? */, + ps_level2 ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 + : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3); + pdf_conversion_state_->Start( + bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this)); +} + +#endif // defined(OS_WIN) void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) { if (document_.get() == new_document) @@ -373,8 +389,10 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { } case JobEventDetails::PAGE_DONE: #if defined(OS_WIN) - pdf_to_emf_state_->OnPageProcessed( - base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); + if (pdf_conversion_state_) { + pdf_conversion_state_->OnPageProcessed( + base::Bind(&PrintJob::OnPdfPageConverted, this)); + } #endif // defined(OS_WIN) break; default: { diff --git a/chromium_src/chrome/browser/printing/print_job.h b/chromium_src/chrome/browser/printing/print_job.h index e5c77aeb2345..bca518f6fcdb 100644 --- a/chromium_src/chrome/browser/printing/print_job.h +++ b/chromium_src/chrome/browser/printing/print_job.h @@ -100,6 +100,12 @@ class PrintJob : public PrintJobWorkerOwner, const gfx::Size& page_size, const gfx::Rect& content_area, bool print_text_with_gdi); + + void StartPdfToPostScriptConversion( + const scoped_refptr& bytes, + const gfx::Rect& content_area, + const gfx::Point& physical_offset, + bool ps_level2); #endif // defined(OS_WIN) protected: @@ -126,10 +132,10 @@ class PrintJob : public PrintJobWorkerOwner, void HoldUntilStopIsCalled(); #if defined(OS_WIN) - void OnPdfToEmfStarted(int page_count); - void OnPdfToEmfPageConverted(int page_number, - float scale_factor, - std::unique_ptr emf); + void OnPdfConversionStarted(int page_count); + void OnPdfPageConverted(int page_number, + float scale_factor, + std::unique_ptr emf); #endif // defined(OS_WIN) content::NotificationRegistrar registrar_; @@ -157,8 +163,8 @@ class PrintJob : public PrintJobWorkerOwner, bool is_canceling_; #if defined(OS_WIN) - class PdfToEmfState; - std::unique_ptr pdf_to_emf_state_; + class PdfConversionState; + std::unique_ptr pdf_conversion_state_; std::vector pdf_page_mapping_; #endif // defined(OS_WIN) diff --git a/chromium_src/chrome/common/chrome_utility_printing_messages.h b/chromium_src/chrome/common/chrome_utility_printing_messages.h new file mode 100644 index 000000000000..fc71f0bd05f3 --- /dev/null +++ b/chromium_src/chrome/common/chrome_utility_printing_messages.h @@ -0,0 +1,111 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Multiply-included message file, so no include guard. + +#include +#include + +#include "base/strings/string16.h" +#include "build/build_config.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_param_traits.h" +#include "ipc/ipc_platform_file.h" +#include "printing/backend/print_backend.h" +#include "printing/features/features.h" +#include "printing/page_range.h" +#include "printing/pdf_render_settings.h" +#include "printing/pwg_raster_settings.h" + +#if defined(OS_WIN) +#include +#endif + +#define IPC_MESSAGE_START ChromeUtilityPrintingMsgStart + +IPC_ENUM_TRAITS_MAX_VALUE(printing::PdfRenderSettings::Mode, + printing::PdfRenderSettings::Mode::LAST) + +IPC_STRUCT_TRAITS_BEGIN(printing::PdfRenderSettings) + IPC_STRUCT_TRAITS_MEMBER(area) + IPC_STRUCT_TRAITS_MEMBER(offsets) + IPC_STRUCT_TRAITS_MEMBER(dpi) + IPC_STRUCT_TRAITS_MEMBER(autorotate) + IPC_STRUCT_TRAITS_MEMBER(mode) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(printing::PrinterCapsAndDefaults) + IPC_STRUCT_TRAITS_MEMBER(printer_capabilities) + IPC_STRUCT_TRAITS_MEMBER(caps_mime_type) + IPC_STRUCT_TRAITS_MEMBER(printer_defaults) + IPC_STRUCT_TRAITS_MEMBER(defaults_mime_type) +IPC_STRUCT_TRAITS_END() + +IPC_ENUM_TRAITS_MAX_VALUE(printing::ColorModel, printing::PROCESSCOLORMODEL_RGB) + +IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults::Paper) + IPC_STRUCT_TRAITS_MEMBER(display_name) + IPC_STRUCT_TRAITS_MEMBER(vendor_id) + IPC_STRUCT_TRAITS_MEMBER(size_um) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults) + IPC_STRUCT_TRAITS_MEMBER(collate_capable) + IPC_STRUCT_TRAITS_MEMBER(collate_default) + IPC_STRUCT_TRAITS_MEMBER(copies_capable) + IPC_STRUCT_TRAITS_MEMBER(duplex_capable) + IPC_STRUCT_TRAITS_MEMBER(duplex_default) + IPC_STRUCT_TRAITS_MEMBER(color_changeable) + IPC_STRUCT_TRAITS_MEMBER(color_default) + IPC_STRUCT_TRAITS_MEMBER(color_model) + IPC_STRUCT_TRAITS_MEMBER(bw_model) + IPC_STRUCT_TRAITS_MEMBER(papers) + IPC_STRUCT_TRAITS_MEMBER(default_paper) + IPC_STRUCT_TRAITS_MEMBER(dpis) + IPC_STRUCT_TRAITS_MEMBER(default_dpi) +IPC_STRUCT_TRAITS_END() + +IPC_ENUM_TRAITS_MAX_VALUE(printing::PwgRasterTransformType, + printing::TRANSFORM_TYPE_LAST) + +IPC_STRUCT_TRAITS_BEGIN(printing::PwgRasterSettings) + IPC_STRUCT_TRAITS_MEMBER(odd_page_transform) + IPC_STRUCT_TRAITS_MEMBER(rotate_all_pages) + IPC_STRUCT_TRAITS_MEMBER(reverse_page_order) +IPC_STRUCT_TRAITS_END() + +#if defined(OS_WIN) +// Reply when the utility process loaded PDF. |page_count| is 0, if loading +// failed. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, + int /* page_count */) + +// Reply when the utility process rendered the PDF page. +IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, + bool /* success */, + float /* scale_factor */) + +// Request that the given font characters be loaded by the browser so it's +// cached by the OS. Please see +// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details. +IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters, + LOGFONT /* font_data */, + base::string16 /* characters */) + +// Tell the utility process to start rendering the given PDF into a metafile. +// Utility process would be alive until +// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles, + IPC::PlatformFileForTransit /* input_file */, + printing::PdfRenderSettings /* settings */) + +// Requests conversion of the next page. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, + int /* page_number */, + IPC::PlatformFileForTransit /* output_file */) + +// Requests utility process to stop conversion and exit. +IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop) + +#endif // OS_WIN diff --git a/chromium_src/chrome/common/print_messages.h b/chromium_src/chrome/common/print_messages.h index e74dfafa71aa..196d8be508c4 100644 --- a/chromium_src/chrome/common/print_messages.h +++ b/chromium_src/chrome/common/print_messages.h @@ -74,6 +74,9 @@ struct PrintMsg_PrintPages_Params { IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType, printing::MARGIN_TYPE_LAST) +IPC_ENUM_TRAITS_MIN_MAX_VALUE(printing::DuplexMode, + printing::UNKNOWN_DUPLEX_MODE, + printing::SHORT_EDGE) IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPrintScalingOption, blink::WebPrintScalingOptionLast) @@ -310,39 +313,3 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting, IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed, int /* document cookie */, int /* request_id */); - -#if defined(OS_WIN) -// Tell the utility process to start rendering the given PDF into a metafile. -// Utility process would be alive until -// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message. -IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_RenderPDFPagesToMetafiles, - IPC::PlatformFileForTransit /* input_file */, - printing::PdfRenderSettings /* settings */, - bool /* print_text_with_gdi */) - -// Requests conversion of the next page. -IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, - int /* page_number */, - IPC::PlatformFileForTransit /* output_file */) - -// Requests utility process to stop conversion and exit. -IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop) - -// Reply when the utility process loaded PDF. |page_count| is 0, if loading -// failed. -IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, - int /* page_count */) - -// Reply when the utility process rendered the PDF page. -IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, - bool /* success */, - float /* scale_factor */) - -// Request that the given font characters be loaded by the browser so it's -// cached by the OS. Please see -// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details. -IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters, - LOGFONT /* font_data */, - base::string16 /* characters */) - -#endif diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc index 6449f09feec2..abac55430030 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc @@ -14,7 +14,6 @@ #include "printing/page_size_margins.h" #include "printing/pdf_metafile_skia.h" #include "printing/units.h" -#include "skia/ext/platform_device.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" diff --git a/chromium_src/chrome/utility/printing_handler_win.cc b/chromium_src/chrome/utility/printing_handler_win.cc index 4265991272af..cd01a09601a8 100644 --- a/chromium_src/chrome/utility/printing_handler_win.cc +++ b/chromium_src/chrome/utility/printing_handler_win.cc @@ -8,6 +8,7 @@ #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/scoped_native_library.h" +#include "chrome/common/chrome_utility_printing_messages.h" #include "chrome/common/print_messages.h" #include "content/public/utility/utility_thread.h" #include "pdf/pdf.h" @@ -59,13 +60,25 @@ bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) { void PrintingHandlerWin::OnRenderPDFPagesToMetafile( IPC::PlatformFileForTransit pdf_transit, - const PdfRenderSettings& settings, - bool print_text_with_gdi) { + const PdfRenderSettings& settings) { pdf_rendering_settings_ = settings; - chrome_pdf::SetPDFUseGDIPrinting(print_text_with_gdi); + chrome_pdf::SetPDFUseGDIPrinting(pdf_rendering_settings_.mode == + PdfRenderSettings::Mode::GDI_TEXT); + int postscript_level; + switch (pdf_rendering_settings_.mode) { + case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2: + postscript_level = 2; + break; + case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3: + postscript_level = 3; + break; + default: + postscript_level = 0; // Not using postscript. + } + chrome_pdf::SetPDFPostscriptPrintingLevel(postscript_level); + base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); int page_count = LoadPDF(std::move(pdf_file)); - //int page_count = 1; Send( new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count)); } @@ -75,8 +88,12 @@ void PrintingHandlerWin::OnRenderPDFPagesToMetafileGetPage( IPC::PlatformFileForTransit output_file) { base::File emf_file = IPC::PlatformFileForTransitToFile(output_file); float scale_factor = 1.0f; - bool success = - RenderPdfPageToMetafile(page_number, std::move(emf_file), &scale_factor); + bool postscript = pdf_rendering_settings_.mode == + PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 || + pdf_rendering_settings_.mode == + PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3; + bool success = RenderPdfPageToMetafile(page_number, std::move(emf_file), + &scale_factor, postscript); Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone( success, scale_factor)); } @@ -105,7 +122,8 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) { bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, base::File output_file, - float* scale_factor) { + float* scale_factor, + bool postscript) { Emf metafile; metafile.Init(); @@ -116,18 +134,30 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, // original coordinates and we'll be able to print in full resolution. // Before playback we'll need to counter the scaling up that will happen // in the service (print_system_win.cc). - *scale_factor = gfx::CalculatePageScale( - metafile.context(), pdf_rendering_settings_.area.right(), - pdf_rendering_settings_.area.bottom()); - gfx::ScaleDC(metafile.context(), *scale_factor); + // + // The postscript driver does not use the metafile size since it outputs + // postscript rather than a metafile. Instead it uses the printable area + // sent to RenderPDFPageToDC to determine the area to render. Therefore, + // don't scale the DC to match the metafile, and send the printer physical + // offsets to the driver. + if (!postscript) { + *scale_factor = gfx::CalculatePageScale( + metafile.context(), pdf_rendering_settings_.area.right(), + pdf_rendering_settings_.area.bottom()); + gfx::ScaleDC(metafile.context(), *scale_factor); + } // The underlying metafile is of type Emf and ignores the arguments passed // to StartPage. metafile.StartPage(gfx::Size(), gfx::Rect(), 1); + int offset_x = postscript ? pdf_rendering_settings_.offsets.x() : 0; + int offset_y = postscript ? pdf_rendering_settings_.offsets.y() : 0; + if (!chrome_pdf::RenderPDFPageToDC( &pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(), - pdf_rendering_settings_.dpi, pdf_rendering_settings_.area.x(), - pdf_rendering_settings_.area.y(), + pdf_rendering_settings_.dpi, + pdf_rendering_settings_.area.x() - offset_x, + pdf_rendering_settings_.area.y() - offset_y, pdf_rendering_settings_.area.width(), pdf_rendering_settings_.area.height(), true, false, true, true, pdf_rendering_settings_.autorotate)) { @@ -138,4 +168,4 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, return metafile.SaveTo(&output_file); } -} // printing +} // namespace printing diff --git a/chromium_src/chrome/utility/printing_handler_win.h b/chromium_src/chrome/utility/printing_handler_win.h index b4a1902dc714..d058e7e50556 100644 --- a/chromium_src/chrome/utility/printing_handler_win.h +++ b/chromium_src/chrome/utility/printing_handler_win.h @@ -29,8 +29,7 @@ class PrintingHandlerWin : public UtilityMessageHandler { private: // IPC message handlers. void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit, - const PdfRenderSettings& settings, - bool print_text_with_gdi); + const PdfRenderSettings& settings); void OnRenderPDFPagesToMetafileGetPage( int page_number, IPC::PlatformFileForTransit output_file); @@ -39,7 +38,8 @@ class PrintingHandlerWin : public UtilityMessageHandler { int LoadPDF(base::File pdf_file); bool RenderPdfPageToMetafile(int page_number, base::File output_file, - float* scale_factor); + float* scale_factor, + bool postscript); std::vector pdf_data_; PdfRenderSettings pdf_rendering_settings_; diff --git a/common.gypi b/common.gypi index 7c1bf366aa66..d4b7646c28ef 100644 --- a/common.gypi +++ b/common.gypi @@ -240,6 +240,7 @@ 4302, # (atldlgs.h) 'type cast': truncation from 'LPCTSTR' to 'WORD' 4458, # (atldlgs.h) declaration of 'dwCommonButtons' hides class member 4503, # decorated name length exceeded, name was truncated + 4714, # (atomicstring.h) function marked as __forceinline not inlined 4800, # (v8.h) forcing value to bool 'true' or 'false' 4819, # The file contains a character that cannot be represented in the current code page 4838, # (atlgdi.h) conversion from 'int' to 'UINT' requires a narrowing conversion