Index: chrome/browser/printing/pdf_to_emf_converter.cc |
diff --git a/chrome/browser/local_discovery/pwg_raster_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc |
similarity index 50% |
copy from chrome/browser/local_discovery/pwg_raster_converter.cc |
copy to chrome/browser/printing/pdf_to_emf_converter.cc |
index 0f39430ba201d7f90f4439e64ab0a3fc6e3db5cc..bce69a6b5bf0cf0cb7ae3d7caedcd52f989a0784 100644 |
--- a/chrome/browser/local_discovery/pwg_raster_converter.cc |
+++ b/chrome/browser/printing/pdf_to_emf_converter.cc |
@@ -1,8 +1,8 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
+// 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. |
-#include "chrome/browser/local_discovery/pwg_raster_converter.h" |
+#include "chrome/browser/printing/pdf_to_emf_converter.h" |
#include "base/bind_helpers.h" |
#include "base/cancelable_callback.h" |
@@ -16,7 +16,7 @@ |
#include "content/public/browser/utility_process_host.h" |
#include "content/public/browser/utility_process_host_client.h" |
-namespace local_discovery { |
+namespace printing { |
namespace { |
@@ -33,8 +33,8 @@ class FileHandlers { |
void Init(base::RefCountedMemory* data); |
bool IsValid(); |
- base::FilePath GetPwgPath() const { |
- return temp_dir_.path().AppendASCII("output.pwg"); |
+ base::FilePath GetEmfPath() const { |
+ return temp_dir_.path().AppendASCII("output.emf"); |
} |
base::FilePath GetPdfPath() const { |
@@ -48,17 +48,13 @@ class FileHandlers { |
return transit; |
} |
- IPC::PlatformFileForTransit GetPwgForProcess(base::ProcessHandle process) { |
- DCHECK(pwg_file_.IsValid()); |
- IPC::PlatformFileForTransit transit = |
- IPC::TakeFileHandleForProcess(pwg_file_.Pass(), process); |
- return transit; |
+ const base::FilePath& GetBasePath() const { |
+ return temp_dir_.path(); |
} |
private: |
base::ScopedTempDir temp_dir_; |
base::File pdf_file_; |
- base::File pwg_file_; |
}; |
void FileHandlers::Init(base::RefCountedMemory* data) { |
@@ -76,16 +72,13 @@ void FileHandlers::Init(base::RefCountedMemory* data) { |
// Reopen in read only mode. |
pdf_file_.Initialize(GetPdfPath(), |
base::File::FLAG_OPEN | base::File::FLAG_READ); |
- pwg_file_.Initialize( |
- GetPwgPath(), |
- base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_APPEND); |
} |
bool FileHandlers::IsValid() { |
- return pdf_file_.IsValid() && pwg_file_.IsValid(); |
+ return pdf_file_.IsValid(); |
} |
-// Converts PDF into PWG raster. |
+// Converts PDF into EMF. |
// Class uses 3 threads: UI, IO and FILE. |
// Internal workflow is following: |
// 1. Create instance on the UI thread. (files_, settings_,) |
@@ -97,190 +90,217 @@ bool FileHandlers::IsValid() { |
// This step posts |FileHandlers| to be destroyed on the FILE thread. |
// All these steps work sequentially, so no data should be accessed |
// simultaneously by several threads. |
-class PwgUtilityProcessHostClient : public content::UtilityProcessHostClient { |
+class PdfToEmfUtilityProcessHostClient |
+ : public content::UtilityProcessHostClient { |
public: |
- explicit PwgUtilityProcessHostClient( |
- const printing::PdfRenderSettings& settings, |
- const printing::PwgRasterSettings& bitmap_settings); |
+ explicit PdfToEmfUtilityProcessHostClient( |
+ const printing::PdfRenderSettings& settings); |
void Convert(base::RefCountedMemory* data, |
- const PWGRasterConverter::ResultCallback& callback); |
+ const PdfToEmfConverter::ResultCallback& callback); |
// UtilityProcessHostClient implementation. |
virtual void OnProcessCrashed(int exit_code) OVERRIDE; |
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
private: |
- virtual ~PwgUtilityProcessHostClient(); |
+ virtual ~PdfToEmfUtilityProcessHostClient(); |
// Message handlers. |
void OnProcessStarted(); |
- void OnSucceeded(); |
+ void OnSucceeded(const std::vector<printing::PageRange>& page_ranges, |
+ double scale_factor); |
void OnFailed(); |
- void RunCallback(bool success); |
+ void RunCallback(const std::vector<printing::PageRange>& page_ranges, |
+ double scale_factor); |
void StartProcessOnIOThread(); |
- void RunCallbackOnUIThread(bool success); |
+ void RunCallbackOnUIThread( |
+ const std::vector<printing::PageRange>& page_ranges, |
+ double scale_factor); |
void OnFilesReadyOnUIThread(); |
scoped_ptr<FileHandlers> files_; |
printing::PdfRenderSettings settings_; |
- printing::PwgRasterSettings bitmap_settings_; |
- PWGRasterConverter::ResultCallback callback_; |
+ PdfToEmfConverter::ResultCallback callback_; |
base::WeakPtr<content::UtilityProcessHost> utility_process_host_; |
- DISALLOW_COPY_AND_ASSIGN(PwgUtilityProcessHostClient); |
+ DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); |
}; |
-PwgUtilityProcessHostClient::PwgUtilityProcessHostClient( |
- const printing::PdfRenderSettings& settings, |
- const printing::PwgRasterSettings& bitmap_settings) |
- : settings_(settings), bitmap_settings_(bitmap_settings) {} |
+PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( |
+ const printing::PdfRenderSettings& settings) |
+ : settings_(settings) {} |
-PwgUtilityProcessHostClient::~PwgUtilityProcessHostClient() { |
+PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { |
// Delete temp directory. |
BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, files_.release()); |
} |
-void PwgUtilityProcessHostClient::Convert( |
+void PdfToEmfUtilityProcessHostClient::Convert( |
base::RefCountedMemory* data, |
- const PWGRasterConverter::ResultCallback& callback) { |
+ const PdfToEmfConverter::ResultCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
callback_ = callback; |
CHECK(!files_); |
files_.reset(new FileHandlers()); |
BrowserThread::PostTaskAndReply( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&FileHandlers::Init, base::Unretained(files_.get()), |
+ BrowserThread::FILE, |
+ FROM_HERE, |
+ base::Bind(&FileHandlers::Init, |
+ base::Unretained(files_.get()), |
make_scoped_refptr(data)), |
- base::Bind(&PwgUtilityProcessHostClient::OnFilesReadyOnUIThread, this)); |
+ base::Bind(&PdfToEmfUtilityProcessHostClient::OnFilesReadyOnUIThread, |
+ this)); |
} |
-void PwgUtilityProcessHostClient::OnProcessCrashed(int exit_code) { |
+void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) { |
OnFailed(); |
} |
-bool PwgUtilityProcessHostClient::OnMessageReceived( |
+bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( |
const IPC::Message& message) { |
bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(PwgUtilityProcessHostClient, message) |
+ IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) |
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, OnProcessStarted) |
IPC_MESSAGE_HANDLER( |
- ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Succeeded, OnSucceeded) |
- IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Failed, |
+ ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_Succeeded, OnSucceeded) |
+ IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed, |
OnFailed) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |
} |
-void PwgUtilityProcessHostClient::OnProcessStarted() { |
+void PdfToEmfUtilityProcessHostClient::OnProcessStarted() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
if (!utility_process_host_) { |
- RunCallbackOnUIThread(false); |
+ RunCallbackOnUIThread(std::vector<printing::PageRange>(), 0.0); |
return; |
} |
base::ProcessHandle process = utility_process_host_->GetData().handle; |
- utility_process_host_->Send(new ChromeUtilityMsg_RenderPDFPagesToPWGRaster( |
- files_->GetPdfForProcess(process), |
- settings_, |
- bitmap_settings_, |
- files_->GetPwgForProcess(process))); |
+ utility_process_host_->Send( |
+ new ChromeUtilityMsg_RenderPDFPagesToMetafiles( |
+ files_->GetPdfForProcess(process), |
+ files_->GetEmfPath(), |
+ settings_, |
+ std::vector<printing::PageRange>())); |
utility_process_host_.reset(); |
} |
-void PwgUtilityProcessHostClient::OnSucceeded() { |
+void PdfToEmfUtilityProcessHostClient::OnSucceeded( |
+ const std::vector<printing::PageRange>& page_ranges, |
+ double scale_factor) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- RunCallback(true); |
+ RunCallback(page_ranges, scale_factor); |
} |
-void PwgUtilityProcessHostClient::OnFailed() { |
+void PdfToEmfUtilityProcessHostClient::OnFailed() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- RunCallback(false); |
+ RunCallback(std::vector<printing::PageRange>(), 0.0); |
} |
-void PwgUtilityProcessHostClient::OnFilesReadyOnUIThread() { |
+void PdfToEmfUtilityProcessHostClient::OnFilesReadyOnUIThread() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
if (!files_->IsValid()) { |
- RunCallbackOnUIThread(false); |
+ RunCallbackOnUIThread(std::vector<printing::PageRange>(), 0.0); |
return; |
} |
BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&PwgUtilityProcessHostClient::StartProcessOnIOThread, this)); |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&PdfToEmfUtilityProcessHostClient::StartProcessOnIOThread, |
+ this)); |
} |
-void PwgUtilityProcessHostClient::StartProcessOnIOThread() { |
+void PdfToEmfUtilityProcessHostClient::StartProcessOnIOThread() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
utility_process_host_ = |
content::UtilityProcessHost::Create( |
this, |
base::MessageLoop::current()->message_loop_proxy())->AsWeakPtr(); |
+ // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load |
+ // gdiplus.dll, change how rendering happens, and not be able to correctly |
+ // generate when sent to a metafile DC. |
+ utility_process_host_->SetExposedDir(files_->GetBasePath()); |
utility_process_host_->Send(new ChromeUtilityMsg_StartupPing); |
} |
-void PwgUtilityProcessHostClient::RunCallback(bool success) { |
+void PdfToEmfUtilityProcessHostClient::RunCallback( |
+ const std::vector<printing::PageRange>& page_ranges, |
+ double scale_factor) { |
BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&PwgUtilityProcessHostClient::RunCallbackOnUIThread, this, |
- success)); |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&PdfToEmfUtilityProcessHostClient::RunCallbackOnUIThread, |
+ this, |
+ page_ranges, |
+ scale_factor)); |
} |
-void PwgUtilityProcessHostClient::RunCallbackOnUIThread(bool success) { |
+void PdfToEmfUtilityProcessHostClient::RunCallbackOnUIThread( |
+ const std::vector<printing::PageRange>& page_ranges, |
+ double scale_factor) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ std::vector<base::FilePath> page_filenames; |
+ std::vector<printing::PageRange>::const_iterator iter; |
+ for (iter = page_ranges.begin(); iter != page_ranges.end(); ++iter) { |
+ for (int page_number = iter->from; page_number <= iter->to; ++page_number) { |
+ page_filenames.push_back(files_->GetEmfPath().InsertBeforeExtensionASCII( |
+ base::StringPrintf(".%d", page_number))); |
+ } |
+ } |
if (!callback_.is_null()) { |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
- base::Bind(callback_, success, |
- files_->GetPwgPath())); |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(callback_, scale_factor, page_filenames)); |
callback_.Reset(); |
} |
} |
-class PWGRasterConverterImpl : public PWGRasterConverter { |
+class PdfToEmfConverterImpl : public PdfToEmfConverter { |
public: |
- PWGRasterConverterImpl(); |
+ PdfToEmfConverterImpl(); |
- virtual ~PWGRasterConverterImpl(); |
+ virtual ~PdfToEmfConverterImpl(); |
virtual void Start(base::RefCountedMemory* data, |
const printing::PdfRenderSettings& conversion_settings, |
- const printing::PwgRasterSettings& bitmap_settings, |
const ResultCallback& callback) OVERRIDE; |
private: |
- scoped_refptr<PwgUtilityProcessHostClient> utility_client_; |
+ scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_; |
base::CancelableCallback<ResultCallback::RunType> callback_; |
- DISALLOW_COPY_AND_ASSIGN(PWGRasterConverterImpl); |
+ DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); |
}; |
-PWGRasterConverterImpl::PWGRasterConverterImpl() { |
+PdfToEmfConverterImpl::PdfToEmfConverterImpl() { |
} |
-PWGRasterConverterImpl::~PWGRasterConverterImpl() { |
+PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { |
} |
-void PWGRasterConverterImpl::Start( |
+void PdfToEmfConverterImpl::Start( |
base::RefCountedMemory* data, |
const printing::PdfRenderSettings& conversion_settings, |
- const printing::PwgRasterSettings& bitmap_settings, |
const ResultCallback& callback) { |
// Rebind cancelable callback to avoid calling callback if |
- // PWGRasterConverterImpl is destroyed. |
+ // PdfToEmfConverterImpl is destroyed. |
callback_.Reset(callback); |
- utility_client_ = |
- new PwgUtilityProcessHostClient(conversion_settings, bitmap_settings); |
+ utility_client_ = new PdfToEmfUtilityProcessHostClient(conversion_settings); |
utility_client_->Convert(data, callback_.callback()); |
} |
} // namespace |
// static |
-scoped_ptr<PWGRasterConverter> PWGRasterConverter::CreateDefault() { |
- return scoped_ptr<PWGRasterConverter>(new PWGRasterConverterImpl()); |
+scoped_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { |
+ return scoped_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); |
} |
-} // namespace local_discovery |
+} // namespace printing |