Index: chrome/browser/printing/print_job.cc |
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc |
index 2569af4ea7743c7727f212f75da4edcab3654da5..09986115a65336fda00648863a7b02c1e6da3e8e 100644 |
--- a/chrome/browser/printing/print_job.cc |
+++ b/chrome/browser/printing/print_job.cc |
@@ -17,6 +17,11 @@ |
#include "printing/printed_document.h" |
#include "printing/printed_page.h" |
+#if defined(OS_WIN) |
+#include "chrome/browser/printing/pdf_to_emf_converter.h" |
+#include "printing/pdf_render_settings.h" |
+#endif |
+ |
using base::TimeDelta; |
namespace { |
@@ -214,6 +219,103 @@ PrintedDocument* PrintJob::document() const { |
return document_.get(); |
} |
+#if defined(OS_WIN) |
+ |
+class PrintJob::PdfToEmfState { |
+ public: |
+ PdfToEmfState(const gfx::Size& page_size, const 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()) {} |
+ |
+ void Start(const scoped_refptr<base::RefCountedMemory>& data, |
+ const PdfRenderSettings& conversion_settings, |
+ const PdfToEmfConverter::StartCallback& start_callback) { |
+ converter_->Start(data, conversion_settings, start_callback); |
+ } |
+ |
+ void GetMorePages( |
+ const PdfToEmfConverter::GetPageCallback& get_page_callback) { |
+ const int kMaxNumberOfTempFilesPerDocument = 3; |
+ while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument && |
+ current_page_ < page_count_) { |
+ ++pages_in_progress_; |
+ converter_->GetPage(current_page_++, get_page_callback); |
+ } |
+ } |
+ |
+ void OnPageProcessed( |
+ const PdfToEmfConverter::GetPageCallback& get_page_callback) { |
+ --pages_in_progress_; |
+ GetMorePages(get_page_callback); |
+ // Release converter if we don't need this any more. |
+ if (!pages_in_progress_ && current_page_ >= page_count_) |
+ converter_.reset(); |
+ } |
+ |
+ void set_page_count(int page_count) { page_count_ = page_count; } |
+ gfx::Size page_size() const { return page_size_; } |
+ gfx::Rect content_area() const { return content_area_; } |
+ |
+ private: |
+ int page_count_; |
+ int current_page_; |
+ int pages_in_progress_; |
+ gfx::Size page_size_; |
+ gfx::Rect content_area_; |
+ scoped_ptr<PdfToEmfConverter> converter_; |
+}; |
+ |
+void PrintJob::StartPdfToEmfConversion( |
+ const scoped_refptr<base::RefCountedMemory>& bytes, |
+ const gfx::Size& page_size, |
+ const gfx::Rect& content_area) { |
+ DCHECK(!ptd_to_emf_state_.get()); |
+ ptd_to_emf_state_.reset(new PdfToEmfState(page_size, content_area)); |
+ const int kPrinterDpi = settings().dpi(); |
+ ptd_to_emf_state_->Start( |
+ bytes, |
+ printing::PdfRenderSettings(content_area, kPrinterDpi, true), |
+ base::Bind(&PrintJob::OnPdfToEmfStarted, this)); |
+} |
+ |
+void PrintJob::OnPdfToEmfStarted(int page_count) { |
+ if (page_count <= 0) { |
+ ptd_to_emf_state_.reset(); |
+ Cancel(); |
+ return; |
+ } |
+ ptd_to_emf_state_->set_page_count(page_count); |
+ ptd_to_emf_state_->GetMorePages( |
+ base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); |
+} |
+ |
+void PrintJob::OnPdfToEmfPageConverted(int page_number, |
+ double scale_factor, |
+ scoped_ptr<MetafilePlayer> emf) { |
+ DCHECK(ptd_to_emf_state_); |
+ if (!document_.get() || !emf) { |
+ ptd_to_emf_state_.reset(); |
+ Cancel(); |
+ return; |
+ } |
+ |
+ // Update the rendered document. It will send notifications to the listener. |
+ document_->SetPage(page_number, |
+ emf.Pass(), |
+ scale_factor, |
+ ptd_to_emf_state_->page_size(), |
+ ptd_to_emf_state_->content_area()); |
+ |
+ ptd_to_emf_state_->GetMorePages( |
+ base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); |
+} |
+ |
+#endif // OS_WIN |
+ |
void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) { |
if (document_.get() == new_document) |
return; |
@@ -252,7 +354,6 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { |
} |
case JobEventDetails::NEW_DOC: |
case JobEventDetails::NEW_PAGE: |
- case JobEventDetails::PAGE_DONE: |
case JobEventDetails::JOB_DONE: |
case JobEventDetails::ALL_PAGES_REQUESTED: { |
// Don't care. |
@@ -264,6 +365,12 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { |
FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this)); |
break; |
} |
+ case JobEventDetails::PAGE_DONE: |
+#if defined(OS_WIN) |
+ ptd_to_emf_state_->OnPageProcessed( |
+ base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); |
+#endif // OS_WIN |
+ break; |
default: { |
NOTREACHED(); |
break; |