Fix building on Windows

This commit is contained in:
Cheng Zhao 2017-04-17 19:42:12 +09:00
parent 8c5fd76286
commit fb42a72ad8
12 changed files with 505 additions and 283 deletions

View file

@ -31,4 +31,3 @@ namespace IPC {
namespace IPC { namespace IPC {
#include "atom/common/common_message_generator.h" #include "atom/common/common_message_generator.h"
} // namespace IPC } // namespace IPC

View file

@ -9,4 +9,5 @@
#include "chrome/common/tts_messages.h" #include "chrome/common/tts_messages.h"
#include "chrome/common/widevine_cdm_messages.h" #include "chrome/common/widevine_cdm_messages.h"
#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/chrome_utility_messages.h"
#include "chrome/common/chrome_utility_printing_messages.h"
#include "components/pdf/common/pdf_messages.h" #include "components/pdf/common/pdf_messages.h"

View file

@ -18,10 +18,9 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "chrome/common/chrome_utility_messages.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/browser_thread.h"
#include "content/public/browser/child_process_data.h" #include "content/public/browser/child_process_data.h"
#include "content/public/browser/utility_process_host.h" #include "content/public/browser/utility_process_host.h"
@ -30,13 +29,13 @@
#include "printing/pdf_render_settings.h" #include "printing/pdf_render_settings.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
using content::BrowserThread;
namespace printing { namespace printing {
namespace { namespace {
using content::BrowserThread; class PdfConverterImpl;
class PdfToEmfConverterImpl;
// Allows to delete temporary directory after all temporary files created inside // Allows to delete temporary directory after all temporary files created inside
// are closed. Windows cannot delete directory with opened files. Directory is // are closed. Windows cannot delete directory with opened files. Directory is
@ -59,8 +58,8 @@ class RefCountedTempDir
DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir); DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir);
}; };
typedef std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread> using ScopedTempFile =
ScopedTempFile; std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread>;
// Wrapper for Emf to keep only file handle in memory, and load actual data only // 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 // on playback. Emf::InitFromFile() can play metafile directly from disk, but it
@ -74,21 +73,39 @@ class LazyEmf : public MetafilePlayer {
} }
~LazyEmf() override { Close(); } ~LazyEmf() override { Close(); }
protected:
// MetafilePlayer:
bool SafePlayback(HDC hdc) const override; bool SafePlayback(HDC hdc) const override;
bool GetDataAsVector(std::vector<char>* buffer) const override;
bool SaveTo(base::File* file) const override;
private:
void Close() const; void Close() const;
bool LoadEmf(Emf* emf) const; bool LoadEmf(Emf* emf) const;
private:
mutable scoped_refptr<RefCountedTempDir> temp_dir_; mutable scoped_refptr<RefCountedTempDir> temp_dir_;
mutable ScopedTempFile file_; // Mutable because of consts in base class. mutable ScopedTempFile file_; // Mutable because of consts in base class.
bool GetDataAsVector(std::vector<char>* buffer) const override;
bool SaveTo(base::File* file) const override;
DISALLOW_COPY_AND_ASSIGN(LazyEmf); DISALLOW_COPY_AND_ASSIGN(LazyEmf);
}; };
// Converts PDF into EMF. // 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. // Class uses 3 threads: UI, IO and FILE.
// Internal workflow is following: // Internal workflow is following:
// 1. Create instance on the UI thread. (files_, settings_,) // 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 // All these steps work sequentially, so no data should be accessed
// simultaneously by several threads. // simultaneously by several threads.
class PdfToEmfUtilityProcessHostClient class PdfConverterUtilityProcessHostClient
: public content::UtilityProcessHostClient { : public content::UtilityProcessHostClient {
public: public:
PdfToEmfUtilityProcessHostClient( PdfConverterUtilityProcessHostClient(
base::WeakPtr<PdfToEmfConverterImpl> converter, base::WeakPtr<PdfConverterImpl> converter,
const PdfRenderSettings& settings); const PdfRenderSettings& settings);
void Start(const scoped_refptr<base::RefCountedMemory>& data, void Start(const scoped_refptr<base::RefCountedMemory>& data,
bool print_text_with_gdi, const PdfConverter::StartCallback& start_callback);
const PdfToEmfConverter::StartCallback& start_callback);
void GetPage(int page_number, void GetPage(int page_number,
const PdfToEmfConverter::GetPageCallback& get_page_callback); const PdfConverter::GetPageCallback& get_page_callback);
void Stop(); void Stop();
// UtilityProcessHostClient implementation.
void OnProcessCrashed(int exit_code) override;
void OnProcessLaunchFailed(int exit_code) override;
// Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
// sync message replies. // sync message replies.
bool Send(IPC::Message* msg); bool Send(IPC::Message* msg);
// UtilityProcessHostClient implementation. protected:
void OnProcessCrashed(int exit_code) override;
void OnProcessLaunchFailed(int exit_code) override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
class GetPageCallbackData { class GetPageCallbackData {
public: public:
GetPageCallbackData(int page_number, GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback)
PdfToEmfConverter::GetPageCallback callback)
: page_number_(page_number), callback_(callback) {} : page_number_(page_number), callback_(callback) {}
GetPageCallbackData(GetPageCallbackData&& other) { GetPageCallbackData(GetPageCallbackData&& other) {
@ -140,45 +154,62 @@ class PdfToEmfUtilityProcessHostClient
GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { GetPageCallbackData& operator=(GetPageCallbackData&& rhs) {
page_number_ = rhs.page_number_; page_number_ = rhs.page_number_;
callback_ = rhs.callback_; callback_ = rhs.callback_;
emf_ = std::move(rhs.emf_); file_ = std::move(rhs.file_);
return *this; return *this;
} }
int page_number() const { return page_number_; } int page_number() const { return page_number_; }
const PdfToEmfConverter::GetPageCallback& callback() const { const PdfConverter::GetPageCallback& callback() const { return callback_; }
return callback_; ScopedTempFile TakeFile() { return std::move(file_); }
} void set_file(ScopedTempFile file) { file_ = std::move(file); }
ScopedTempFile TakeEmf() { return std::move(emf_); }
void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); }
private: private:
int page_number_; int page_number_;
PdfToEmfConverter::GetPageCallback callback_;
ScopedTempFile emf_; PdfConverter::GetPageCallback callback_;
ScopedTempFile file_;
DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); 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<MetafilePlayer> GetFileFromTemp(
std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
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 OnPageCount(int page_count);
void OnPageDone(bool success, float scale_factor); 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, void OnPreCacheFontCharacters(const LOGFONT& log_font,
const base::string16& characters); const base::string16& characters);
void OnFailed();
void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
scoped_refptr<RefCountedTempDir> temp_dir_; scoped_refptr<RefCountedTempDir> temp_dir_;
// Used to suppress callbacks after PdfToEmfConverterImpl is deleted. // Used to suppress callbacks after PdfConverter is deleted.
base::WeakPtr<PdfToEmfConverterImpl> converter_; base::WeakPtr<PdfConverterImpl> converter_;
PdfRenderSettings settings_; PdfRenderSettings settings_;
// Document loaded callback. // Document loaded callback.
PdfToEmfConverter::StartCallback start_callback_; PdfConverter::StartCallback start_callback_;
// Process host for IPC. // Process host for IPC.
base::WeakPtr<content::UtilityProcessHost> utility_process_host_; base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
@ -186,22 +217,37 @@ class PdfToEmfUtilityProcessHostClient
// Queue of callbacks for GetPage() requests. Utility process should reply // Queue of callbacks for GetPage() requests. Utility process should reply
// with PageDone in the same order as requests were received. // with PageDone in the same order as requests were received.
// Use containers that keeps element pointers valid after push() and pop(). // Use containers that keeps element pointers valid after push() and pop().
typedef std::queue<GetPageCallbackData> GetPageCallbacks; using GetPageCallbacks = std::queue<GetPageCallbackData>;
GetPageCallbacks get_page_callbacks_; GetPageCallbacks get_page_callbacks_;
DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient);
}; };
class PdfToEmfConverterImpl : public PdfToEmfConverter { std::unique_ptr<MetafilePlayer>
public: PdfConverterUtilityProcessHostClient::GetFileFromTemp(
PdfToEmfConverterImpl(); 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));
}
~PdfToEmfConverterImpl() override; 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, void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings, const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi, const StartCallback& start_callback);
const StartCallback& start_callback) override;
void GetPage(int page_number, void GetPage(int page_number,
const GetPageCallback& get_page_callback) override; const GetPageCallback& get_page_callback) override;
@ -209,11 +255,17 @@ class PdfToEmfConverterImpl : public PdfToEmfConverter {
// Helps to cancel callbacks if this object is destroyed. // Helps to cancel callbacks if this object is destroyed.
void RunCallback(const base::Closure& callback); void RunCallback(const base::Closure& callback);
private: void Start(
scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_; const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; const scoped_refptr<base::RefCountedMemory>& data,
const StartCallback& start_callback);
DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); private:
scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
base::WeakPtrFactory<PdfConverterImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl);
}; };
ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
@ -260,10 +312,10 @@ ScopedTempFile CreateTempPdfFile(
bool LazyEmf::SafePlayback(HDC hdc) const { bool LazyEmf::SafePlayback(HDC hdc) const {
Emf emf; Emf emf;
bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); bool result = LoadEmf(&emf) && emf.SafePlayback(hdc);
// TODO(vitalybuka): Fix destruction of metafiles. For some reasons // TODO(thestig): Fix destruction of metafiles. For some reasons
// instances of Emf are not deleted. crbug.com/411683 // 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 // It's known that the Emf going to be played just once to a printer. So just
// release file here. // release |file_| here.
Close(); Close();
return result; return result;
} }
@ -280,7 +332,7 @@ bool LazyEmf::SaveTo(base::File* file) const {
void LazyEmf::Close() const { void LazyEmf::Close() const {
file_.reset(); file_.reset();
temp_dir_ = NULL; temp_dir_ = nullptr;
} }
bool LazyEmf::LoadEmf(Emf* emf) const { bool LazyEmf::LoadEmf(Emf* emf) const {
@ -294,24 +346,55 @@ bool LazyEmf::LoadEmf(Emf* emf) const {
return emf->InitFromData(data.data(), data.size()); return emf->InitFromData(data.data(), data.size());
} }
PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( PostScriptMetaFile::~PostScriptMetaFile() {
base::WeakPtr<PdfToEmfConverterImpl> converter, }
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) const PdfRenderSettings& settings)
: converter_(converter), settings_(settings) { : converter_(converter), settings_(settings) {}
}
PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {}
}
void PdfToEmfUtilityProcessHostClient::Start( void PdfConverterUtilityProcessHostClient::Start(
const scoped_refptr<base::RefCountedMemory>& data, const scoped_refptr<base::RefCountedMemory>& data,
bool print_text_with_gdi, const PdfConverter::StartCallback& start_callback) {
const PdfToEmfConverter::StartCallback& start_callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE, BrowserThread::IO, FROM_HERE,
base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data, base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data,
print_text_with_gdi, start_callback)); start_callback));
return; return;
} }
@ -324,50 +407,41 @@ void PdfToEmfUtilityProcessHostClient::Start(
utility_process_host_ = content::UtilityProcessHost::Create( utility_process_host_ = content::UtilityProcessHost::Create(
this, base::ThreadTaskRunnerHandle::Get()) this, base::ThreadTaskRunnerHandle::Get())
->AsWeakPtr(); ->AsWeakPtr();
utility_process_host_->SetName(base::ASCIIToUTF16( utility_process_host_->SetName(GetName());
"IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME"));
BrowserThread::PostTaskAndReplyWithResult( BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE, FROM_HERE, BrowserThread::FILE, FROM_HERE,
base::Bind(&CreateTempPdfFile, data, &temp_dir_), base::Bind(&CreateTempPdfFile, data, &temp_dir_),
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this));
print_text_with_gdi));
} }
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, void PdfConverterUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
ScopedTempFile pdf) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!utility_process_host_ || !pdf) if (!utility_process_host_ || !pdf)
return OnFailed(); return OnFailed();
// Should reply with OnPageCount(). // Should reply with OnPageCount().
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( SendStartMessage(
IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false));
print_text_with_gdi));
} }
void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (start_callback_.is_null()) if (start_callback_.is_null())
return OnFailed(); return OnFailed();
BrowserThread::PostTask(BrowserThread::UI, BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
FROM_HERE, base::Bind(&PdfConverterImpl::RunCallback, converter_,
base::Bind(&PdfToEmfConverterImpl::RunCallback,
converter_,
base::Bind(start_callback_, page_count))); base::Bind(start_callback_, page_count)));
start_callback_.Reset(); start_callback_.Reset();
} }
void PdfToEmfUtilityProcessHostClient::GetPage( void PdfConverterUtilityProcessHostClient::GetPage(
int page_number, int page_number,
const PdfToEmfConverter::GetPageCallback& get_page_callback) { const PdfConverter::GetPageCallback& get_page_callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::IO, BrowserThread::IO, FROM_HERE,
FROM_HERE, base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this,
base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage, page_number, get_page_callback));
this,
page_number,
get_page_callback));
return; return;
} }
@ -378,55 +452,84 @@ void PdfToEmfUtilityProcessHostClient::GetPage(
return OnFailed(); return OnFailed();
BrowserThread::PostTaskAndReplyWithResult( BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE, BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempFile, &temp_dir_),
FROM_HERE, base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this,
base::Bind(&CreateTempFile, &temp_dir_),
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady,
this,
&get_page_callbacks_.back())); &get_page_callbacks_.back()));
} }
void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( void PdfConverterUtilityProcessHostClient::OnTempFileReady(
GetPageCallbackData* callback_data, GetPageCallbackData* callback_data,
ScopedTempFile emf) { ScopedTempFile temp_file) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!utility_process_host_ || !emf) if (!utility_process_host_ || !temp_file)
return OnFailed(); return OnFailed();
IPC::PlatformFileForTransit transit = IPC::PlatformFileForTransit transit =
IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false); IPC::GetPlatformFileForTransit(temp_file->GetPlatformFile(), false);
callback_data->set_emf(std::move(emf)); callback_data->set_file(std::move(temp_file));
// Should reply with OnPageDone(). // Should reply with OnPageDone().
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( SendGetPageMessage(callback_data->page_number(), transit);
callback_data->page_number(), transit));
} }
void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, void PdfConverterUtilityProcessHostClient::OnPageDone(bool success,
float scale_factor) { float scale_factor) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (get_page_callbacks_.empty()) if (get_page_callbacks_.empty())
return OnFailed(); return OnFailed();
GetPageCallbackData& data = get_page_callbacks_.front(); GetPageCallbackData& data = get_page_callbacks_.front();
std::unique_ptr<MetafilePlayer> emf; std::unique_ptr<MetafilePlayer> file;
if (success) { if (success) {
ScopedTempFile temp_emf = data.TakeEmf(); ScopedTempFile temp_file = data.TakeFile();
if (!temp_emf) // Unexpected message from utility process. if (!temp_file) // Unexpected message from utility process.
return OnFailed(); return OnFailed();
emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf)); file = GetFileFromTemp(std::move(temp_file));
} }
BrowserThread::PostTask(BrowserThread::UI, BrowserThread::PostTask(
FROM_HERE, BrowserThread::UI, FROM_HERE,
base::Bind(&PdfToEmfConverterImpl::RunCallback, base::Bind(&PdfConverterImpl::RunCallback, converter_,
converter_, base::Bind(data.callback(), data.page_number(), scale_factor,
base::Bind(data.callback(), base::Passed(&file))));
data.page_number(),
scale_factor,
base::Passed(&emf))));
get_page_callbacks_.pop(); 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 LOGFONT& font,
const base::string16& str) { const base::string16& str) {
// TODO(scottmg): pdf/ppapi still require the renderer to be able to precache // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
@ -458,29 +561,10 @@ void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
DeleteEnhMetaFile(metafile); DeleteEnhMetaFile(metafile);
} }
void PdfToEmfUtilityProcessHostClient::Stop() { bool PdfConverterUtilityProcessHostClient::OnMessageReceived(
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(
const IPC::Message& message) { const IPC::Message& message) {
bool handled = true; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) IPC_BEGIN_MESSAGE_MAP(PdfConverterUtilityProcessHostClient, message)
IPC_MESSAGE_HANDLER( IPC_MESSAGE_HANDLER(
ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount) ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
@ -492,59 +576,69 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
return handled; return handled;
} }
bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { base::string16 PdfConverterUtilityProcessHostClient::GetName() const {
if (utility_process_host_) return L"ChromeUtilityProcessPDFConvertor";
return utility_process_host_->Send(msg);
delete msg;
return false;
} }
void PdfToEmfUtilityProcessHostClient::OnFailed() { void PdfConverterUtilityProcessHostClient::SendGetPageMessage(
DCHECK_CURRENTLY_ON(BrowserThread::IO); int page_number,
if (!start_callback_.is_null()) IPC::PlatformFileForTransit transit) {
OnPageCount(0); Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number,
while (!get_page_callbacks_.empty()) transit));
OnPageDone(false, 0.0f);
utility_process_host_.reset();
} }
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()) if (utility_client_.get())
utility_client_->Stop(); utility_client_->Stop();
} }
void PdfToEmfConverterImpl::Start( void PdfConverterImpl::Start(
const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
const scoped_refptr<base::RefCountedMemory>& data, const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi,
const StartCallback& start_callback) { const StartCallback& start_callback) {
DCHECK(!utility_client_.get()); DCHECK(!utility_client_);
utility_client_ = new PdfToEmfUtilityProcessHostClient( utility_client_ = utility_client;
weak_ptr_factory_.GetWeakPtr(), conversion_settings); utility_client_->Start(data, start_callback);
utility_client_->Start(data, print_text_with_gdi, start_callback);
} }
void PdfToEmfConverterImpl::GetPage(int page_number, void PdfConverterImpl::GetPage(int page_number,
const GetPageCallback& get_page_callback) { const GetPageCallback& get_page_callback) {
utility_client_->GetPage(page_number, 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); DCHECK_CURRENTLY_ON(BrowserThread::UI);
callback.Run(); callback.Run();
} }
} // namespace } // namespace
PdfToEmfConverter::~PdfToEmfConverter() { PdfConverter::~PdfConverter() {}
}
// static // static
std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { std::unique_ptr<PdfConverter> PdfConverter::StartPdfConverter(
return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); 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 } // namespace printing

View file

@ -15,24 +15,21 @@ namespace printing {
class MetafilePlayer; class MetafilePlayer;
struct PdfRenderSettings; struct PdfRenderSettings;
class PdfToEmfConverter { class PdfConverter {
public: public:
typedef base::Callback<void(int page_count)> StartCallback; using StartCallback = base::Callback<void(int page_count)>;
typedef base::Callback<void(int page_number, using GetPageCallback =
base::Callback<void(int page_number,
float scale_factor, float scale_factor,
std::unique_ptr<MetafilePlayer> emf)> std::unique_ptr<MetafilePlayer> file)>;
GetPageCallback; virtual ~PdfConverter();
virtual ~PdfToEmfConverter();
static std::unique_ptr<PdfToEmfConverter> CreateDefault();
// Starts conversion of PDF provided as |data|. Calls |start_callback| // Starts conversion of PDF provided as |data|. Calls |start_callback|
// with positive |page_count|. |page_count| is 0 if initialization failed. // with positive |page_count|. |page_count| is 0 if initialization failed.
virtual void Start(const scoped_refptr<base::RefCountedMemory>& data, static std::unique_ptr<PdfConverter> StartPdfConverter(
const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings, const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi, const StartCallback& start_callback);
const StartCallback& start_callback) = 0;
// Requests conversion of the page. |page_number| is 0-base page number in // Requests conversion of the page. |page_number| is 0-base page number in
// PDF provided in Start() call. // PDF provided in Start() call.
@ -41,7 +38,6 @@ class PdfToEmfConverter {
virtual void GetPage(int page_number, virtual void GetPage(int page_number,
const GetPageCallback& get_page_callback) = 0; const GetPageCallback& get_page_callback) = 0;
}; };
} // namespace printing } // namespace printing
#endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_ #endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_

View file

@ -223,27 +223,23 @@ PrintedDocument* PrintJob::document() const {
} }
#if defined(OS_WIN) #if defined(OS_WIN)
class PrintJob::PdfConversionState {
class PrintJob::PdfToEmfState {
public: public:
PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area) PdfConversionState(gfx::Size page_size, gfx::Rect content_area)
: page_count_(0), : page_count_(0),
current_page_(0), current_page_(0),
pages_in_progress_(0), pages_in_progress_(0),
page_size_(page_size), page_size_(page_size),
content_area_(content_area), content_area_(content_area) {}
converter_(PdfToEmfConverter::CreateDefault()) {}
void Start(const scoped_refptr<base::RefCountedMemory>& data, void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings, const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi, const PdfConverter::StartCallback& start_callback) {
const PdfToEmfConverter::StartCallback& start_callback) { converter_ = PdfConverter::StartPdfConverter(
converter_->Start(data, conversion_settings, print_text_with_gdi, data, conversion_settings, start_callback);
start_callback);
} }
void GetMorePages( void GetMorePages(const PdfConverter::GetPageCallback& get_page_callback) {
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
const int kMaxNumberOfTempFilesPerDocument = 3; const int kMaxNumberOfTempFilesPerDocument = 3;
while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument && while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
current_page_ < page_count_) { current_page_ < page_count_) {
@ -252,8 +248,7 @@ class PrintJob::PdfToEmfState {
} }
} }
void OnPageProcessed( void OnPageProcessed(const PdfConverter::GetPageCallback& get_page_callback) {
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
--pages_in_progress_; --pages_in_progress_;
GetMorePages(get_page_callback); GetMorePages(get_page_callback);
// Release converter if we don't need this any more. // Release converter if we don't need this any more.
@ -271,7 +266,7 @@ class PrintJob::PdfToEmfState {
int pages_in_progress_; int pages_in_progress_;
gfx::Size page_size_; gfx::Size page_size_;
gfx::Rect content_area_; gfx::Rect content_area_;
std::unique_ptr<PdfToEmfConverter> converter_; std::unique_ptr<PdfConverter> converter_;
}; };
void PrintJob::AppendPrintedPage(int page_number) { void PrintJob::AppendPrintedPage(int page_number) {
@ -283,46 +278,67 @@ void PrintJob::StartPdfToEmfConversion(
const gfx::Size& page_size, const gfx::Size& page_size,
const gfx::Rect& content_area, const gfx::Rect& content_area,
bool print_text_with_gdi) { bool print_text_with_gdi) {
DCHECK(!pdf_to_emf_state_); DCHECK(!pdf_conversion_state_);
pdf_to_emf_state_ = base::MakeUnique<PdfToEmfState>(page_size, content_area); pdf_conversion_state_ =
base::MakeUnique<PdfConversionState>(page_size, content_area);
const int kPrinterDpi = settings().dpi(); const int kPrinterDpi = settings().dpi();
pdf_to_emf_state_->Start( PdfRenderSettings settings(
bytes, PdfRenderSettings(content_area, kPrinterDpi, true), content_area, gfx::Point(0, 0), kPrinterDpi, /*autorotate=*/true,
print_text_with_gdi, base::Bind(&PrintJob::OnPdfToEmfStarted, this)); 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) { if (page_count <= 0) {
pdf_to_emf_state_.reset(); pdf_conversion_state_.reset();
Cancel(); Cancel();
return; return;
} }
pdf_to_emf_state_->set_page_count(page_count); pdf_conversion_state_->set_page_count(page_count);
pdf_to_emf_state_->GetMorePages( pdf_conversion_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); base::Bind(&PrintJob::OnPdfPageConverted, this));
} }
void PrintJob::OnPdfToEmfPageConverted(int page_number, void PrintJob::OnPdfPageConverted(int page_number,
float scale_factor, float scale_factor,
std::unique_ptr<MetafilePlayer> emf) { std::unique_ptr<MetafilePlayer> metafile) {
DCHECK(pdf_to_emf_state_); DCHECK(pdf_conversion_state_);
if (!document_.get() || !emf || page_number < 0 || if (!document_.get() || !metafile || page_number < 0 ||
static_cast<size_t>(page_number) >= pdf_page_mapping_.size()) { static_cast<size_t>(page_number) >= pdf_page_mapping_.size()) {
pdf_to_emf_state_.reset(); pdf_conversion_state_.reset();
Cancel(); Cancel();
return; return;
} }
// Update the rendered document. It will send notifications to the listener. // Update the rendered document. It will send notifications to the listener.
document_->SetPage(pdf_page_mapping_[page_number], std::move(emf), document_->SetPage(pdf_page_mapping_[page_number], std::move(metafile),
scale_factor, pdf_to_emf_state_->page_size(), scale_factor, pdf_conversion_state_->page_size(),
pdf_to_emf_state_->content_area()); pdf_conversion_state_->content_area());
pdf_to_emf_state_->GetMorePages( pdf_conversion_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); base::Bind(&PrintJob::OnPdfPageConverted, this));
} }
#endif // OS_WIN void PrintJob::StartPdfToPostScriptConversion(
const scoped_refptr<base::RefCountedMemory>& bytes,
const gfx::Rect& content_area,
const gfx::Point& physical_offsets,
bool ps_level2) {
DCHECK(!pdf_conversion_state_);
pdf_conversion_state_ = base::MakeUnique<PdfConversionState>(
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) { void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
if (document_.get() == new_document) if (document_.get() == new_document)
@ -373,8 +389,10 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
} }
case JobEventDetails::PAGE_DONE: case JobEventDetails::PAGE_DONE:
#if defined(OS_WIN) #if defined(OS_WIN)
pdf_to_emf_state_->OnPageProcessed( if (pdf_conversion_state_) {
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); pdf_conversion_state_->OnPageProcessed(
base::Bind(&PrintJob::OnPdfPageConverted, this));
}
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
break; break;
default: { default: {

View file

@ -100,6 +100,12 @@ class PrintJob : public PrintJobWorkerOwner,
const gfx::Size& page_size, const gfx::Size& page_size,
const gfx::Rect& content_area, const gfx::Rect& content_area,
bool print_text_with_gdi); bool print_text_with_gdi);
void StartPdfToPostScriptConversion(
const scoped_refptr<base::RefCountedMemory>& bytes,
const gfx::Rect& content_area,
const gfx::Point& physical_offset,
bool ps_level2);
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
protected: protected:
@ -126,8 +132,8 @@ class PrintJob : public PrintJobWorkerOwner,
void HoldUntilStopIsCalled(); void HoldUntilStopIsCalled();
#if defined(OS_WIN) #if defined(OS_WIN)
void OnPdfToEmfStarted(int page_count); void OnPdfConversionStarted(int page_count);
void OnPdfToEmfPageConverted(int page_number, void OnPdfPageConverted(int page_number,
float scale_factor, float scale_factor,
std::unique_ptr<MetafilePlayer> emf); std::unique_ptr<MetafilePlayer> emf);
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
@ -157,8 +163,8 @@ class PrintJob : public PrintJobWorkerOwner,
bool is_canceling_; bool is_canceling_;
#if defined(OS_WIN) #if defined(OS_WIN)
class PdfToEmfState; class PdfConversionState;
std::unique_ptr<PdfToEmfState> pdf_to_emf_state_; std::unique_ptr<PdfConversionState> pdf_conversion_state_;
std::vector<int> pdf_page_mapping_; std::vector<int> pdf_page_mapping_;
#endif // defined(OS_WIN) #endif // defined(OS_WIN)

View file

@ -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 <string>
#include <vector>
#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 <windows.h>
#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

View file

@ -74,6 +74,9 @@ struct PrintMsg_PrintPages_Params {
IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType, IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType,
printing::MARGIN_TYPE_LAST) 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, IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPrintScalingOption,
blink::WebPrintScalingOptionLast) blink::WebPrintScalingOptionLast)
@ -310,39 +313,3 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting,
IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed, IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed,
int /* document cookie */, int /* document cookie */,
int /* request_id */); 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

View file

@ -14,7 +14,6 @@
#include "printing/page_size_margins.h" #include "printing/page_size_margins.h"
#include "printing/pdf_metafile_skia.h" #include "printing/pdf_metafile_skia.h"
#include "printing/units.h" #include "printing/units.h"
#include "skia/ext/platform_device.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h"

View file

@ -8,6 +8,7 @@
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/scoped_native_library.h" #include "base/scoped_native_library.h"
#include "chrome/common/chrome_utility_printing_messages.h"
#include "chrome/common/print_messages.h" #include "chrome/common/print_messages.h"
#include "content/public/utility/utility_thread.h" #include "content/public/utility/utility_thread.h"
#include "pdf/pdf.h" #include "pdf/pdf.h"
@ -59,13 +60,25 @@ bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) {
void PrintingHandlerWin::OnRenderPDFPagesToMetafile( void PrintingHandlerWin::OnRenderPDFPagesToMetafile(
IPC::PlatformFileForTransit pdf_transit, IPC::PlatformFileForTransit pdf_transit,
const PdfRenderSettings& settings, const PdfRenderSettings& settings) {
bool print_text_with_gdi) {
pdf_rendering_settings_ = 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); base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit);
int page_count = LoadPDF(std::move(pdf_file)); int page_count = LoadPDF(std::move(pdf_file));
//int page_count = 1;
Send( Send(
new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count)); new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count));
} }
@ -75,8 +88,12 @@ void PrintingHandlerWin::OnRenderPDFPagesToMetafileGetPage(
IPC::PlatformFileForTransit output_file) { IPC::PlatformFileForTransit output_file) {
base::File emf_file = IPC::PlatformFileForTransitToFile(output_file); base::File emf_file = IPC::PlatformFileForTransitToFile(output_file);
float scale_factor = 1.0f; float scale_factor = 1.0f;
bool success = bool postscript = pdf_rendering_settings_.mode ==
RenderPdfPageToMetafile(page_number, std::move(emf_file), &scale_factor); 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( Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone(
success, scale_factor)); success, scale_factor));
} }
@ -105,7 +122,8 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) {
bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
base::File output_file, base::File output_file,
float* scale_factor) { float* scale_factor,
bool postscript) {
Emf metafile; Emf metafile;
metafile.Init(); metafile.Init();
@ -116,18 +134,30 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
// original coordinates and we'll be able to print in full resolution. // 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 // Before playback we'll need to counter the scaling up that will happen
// in the service (print_system_win.cc). // in the service (print_system_win.cc).
//
// 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( *scale_factor = gfx::CalculatePageScale(
metafile.context(), pdf_rendering_settings_.area.right(), metafile.context(), pdf_rendering_settings_.area.right(),
pdf_rendering_settings_.area.bottom()); pdf_rendering_settings_.area.bottom());
gfx::ScaleDC(metafile.context(), *scale_factor); gfx::ScaleDC(metafile.context(), *scale_factor);
}
// The underlying metafile is of type Emf and ignores the arguments passed // The underlying metafile is of type Emf and ignores the arguments passed
// to StartPage. // to StartPage.
metafile.StartPage(gfx::Size(), gfx::Rect(), 1); 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( if (!chrome_pdf::RenderPDFPageToDC(
&pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(), &pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(),
pdf_rendering_settings_.dpi, pdf_rendering_settings_.area.x(), pdf_rendering_settings_.dpi,
pdf_rendering_settings_.area.y(), pdf_rendering_settings_.area.x() - offset_x,
pdf_rendering_settings_.area.y() - offset_y,
pdf_rendering_settings_.area.width(), pdf_rendering_settings_.area.width(),
pdf_rendering_settings_.area.height(), true, false, true, true, pdf_rendering_settings_.area.height(), true, false, true, true,
pdf_rendering_settings_.autorotate)) { pdf_rendering_settings_.autorotate)) {
@ -138,4 +168,4 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
return metafile.SaveTo(&output_file); return metafile.SaveTo(&output_file);
} }
} // printing } // namespace printing

View file

@ -29,8 +29,7 @@ class PrintingHandlerWin : public UtilityMessageHandler {
private: private:
// IPC message handlers. // IPC message handlers.
void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit, void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit,
const PdfRenderSettings& settings, const PdfRenderSettings& settings);
bool print_text_with_gdi);
void OnRenderPDFPagesToMetafileGetPage( void OnRenderPDFPagesToMetafileGetPage(
int page_number, int page_number,
IPC::PlatformFileForTransit output_file); IPC::PlatformFileForTransit output_file);
@ -39,7 +38,8 @@ class PrintingHandlerWin : public UtilityMessageHandler {
int LoadPDF(base::File pdf_file); int LoadPDF(base::File pdf_file);
bool RenderPdfPageToMetafile(int page_number, bool RenderPdfPageToMetafile(int page_number,
base::File output_file, base::File output_file,
float* scale_factor); float* scale_factor,
bool postscript);
std::vector<char> pdf_data_; std::vector<char> pdf_data_;
PdfRenderSettings pdf_rendering_settings_; PdfRenderSettings pdf_rendering_settings_;

View file

@ -240,6 +240,7 @@
4302, # (atldlgs.h) 'type cast': truncation from 'LPCTSTR' to 'WORD' 4302, # (atldlgs.h) 'type cast': truncation from 'LPCTSTR' to 'WORD'
4458, # (atldlgs.h) declaration of 'dwCommonButtons' hides class member 4458, # (atldlgs.h) declaration of 'dwCommonButtons' hides class member
4503, # decorated name length exceeded, name was truncated 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' 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 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 4838, # (atlgdi.h) conversion from 'int' to 'UINT' requires a narrowing conversion