#include "chrome/service/cloud_print/print_system.h"
#include "base/command_line.h"
-#include "base/file_util.h"
+#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "printing/backend/win_helper.h"
#include "printing/emf_win.h"
#include "printing/page_range.h"
+#include "printing/pdf_render_settings.h"
#include "printing/printing_utils.h"
+#include "ui/gfx/geometry/rect.h"
namespace cloud_print {
bool ret = false;
if (printer_.OpenPrinter(printer_name_to_use)) {
printer_change_.Set(FindFirstPrinterChangeNotification(
- printer_, PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL));
+ printer_.Get(), PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL));
if (printer_change_.IsValid()) {
- ret = watcher_.StartWatching(printer_change_, this);
+ ret = watcher_.StartWatching(printer_change_.Get(), this);
}
}
if (!ret) {
delegate_->OnJobChanged();
}
}
- watcher_.StartWatching(printer_change_, this);
+ watcher_.StartWatching(printer_change_.Get(), this);
}
bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) {
DCHECK(printer_info);
- return InitBasicPrinterInfo(printer_, printer_info);
+ return InitBasicPrinterInfo(printer_.Get(), printer_info);
}
private:
virtual void OnPrinterChanged() OVERRIDE {}
virtual void OnJobChanged() OVERRIDE {}
- protected:
+ protected:
virtual ~PrintServerWatcherWin() {}
private:
delegate_->OnJobChanged();
}
- protected:
+ protected:
virtual ~PrinterWatcherWin() {}
private:
class Core : public ServiceUtilityProcessHost::Client,
public base::win::ObjectWatcher::Delegate {
public:
- Core()
- : last_page_printed_(-1),
- job_id_(-1),
- delegate_(NULL),
- saved_dc_(0) {
- }
+ Core() : job_id_(-1), delegate_(NULL), saved_dc_(0) {}
~Core() {}
return false;
}
base::string16 printer_wide = base::UTF8ToWide(printer_name);
- last_page_printed_ = -1;
// We only support PDF and XPS documents for now.
if (print_data_mime_type == kContentTypePDF) {
scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode;
saved_dc_ = SaveDC(printer_dc_.Get());
print_data_file_path_ = print_data_file_path;
delegate_ = delegate;
- RenderNextPDFPages();
+ RenderPDFPages();
} else if (print_data_mime_type == kContentTypeXPS) {
DCHECK(print_ticket_mime_type == kContentTypeXML);
bool ret = PrintXPSDocument(printer_name,
}
// ServiceUtilityProcessHost::Client implementation.
- virtual void OnRenderPDFPagesToMetafileSucceeded(
- const printing::Emf& metafile,
- int highest_rendered_page_number,
- double scale_factor) OVERRIDE {
+ virtual void OnRenderPDFPagesToMetafilePageDone(
+ double scale_factor,
+ const printing::MetafilePlayer& emf) OVERRIDE {
PreparePageDCForPrinting(printer_dc_.Get(), scale_factor);
- metafile.SafePlayback(printer_dc_.Get());
- bool done_printing = (highest_rendered_page_number !=
- last_page_printed_ + kPageCountPerBatch);
- last_page_printed_ = highest_rendered_page_number;
- if (done_printing)
- PrintJobDone();
- else
- RenderNextPDFPages();
+ ::StartPage(printer_dc_.Get());
+ emf.SafePlayback(printer_dc_.Get());
+ ::EndPage(printer_dc_.Get());
}
+ // ServiceUtilityProcessHost::Client implementation.
+ virtual void OnRenderPDFPagesToMetafileDone(bool success) OVERRIDE {
+ PrintJobDone(success);
+ }
+
+ virtual void OnChildDied() OVERRIDE { PrintJobDone(false); }
+
// base::win::ObjectWatcher::Delegate implementation.
virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
DCHECK(xps_print_job_);
}
}
- virtual void OnRenderPDFPagesToMetafileFailed() OVERRIDE {
- PrintJobDone();
- }
-
- virtual void OnChildDied() OVERRIDE {
- PrintJobDone();
- }
-
private:
// Helper class to allow PrintXPSDocument() to have multiple exits.
class PrintJobCanceler {
DISALLOW_COPY_AND_ASSIGN(PrintJobCanceler);
};
- void PrintJobDone() {
+ void PrintJobDone(bool success) {
// If there is no delegate, then there is nothing pending to process.
if (!delegate_)
return;
RestoreDC(printer_dc_.Get(), saved_dc_);
EndDoc(printer_dc_.Get());
- if (-1 == last_page_printed_) {
- delegate_->OnJobSpoolFailed();
- } else {
+ if (success) {
delegate_->OnJobSpoolSucceeded(job_id_);
+ } else {
+ delegate_->OnJobSpoolFailed();
}
delegate_ = NULL;
}
- void RenderNextPDFPages() {
- printing::PageRange range;
- // Render 10 pages at a time.
- range.from = last_page_printed_ + 1;
- range.to = last_page_printed_ + kPageCountPerBatch;
- std::vector<printing::PageRange> page_ranges;
- page_ranges.push_back(range);
-
+ void RenderPDFPages() {
int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX);
int dc_width = GetDeviceCaps(printer_dc_.Get(), PHYSICALWIDTH);
int dc_height = GetDeviceCaps(printer_dc_.Get(), PHYSICALHEIGHT);
gfx::Rect render_area(0, 0, dc_width, dc_height);
g_service_process->io_thread()->message_loop_proxy()->PostTask(
FROM_HERE,
- base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox, this,
- print_data_file_path_, render_area, printer_dpi,
- page_ranges, base::MessageLoopProxy::current()));
+ base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox,
+ this,
+ print_data_file_path_,
+ render_area,
+ printer_dpi,
+ base::MessageLoopProxy::current()));
}
// Called on the service process IO thread.
- void RenderPDFPagesInSandbox(
- const base::FilePath& pdf_path, const gfx::Rect& render_area,
- int render_dpi, const std::vector<printing::PageRange>& page_ranges,
- const scoped_refptr<base::MessageLoopProxy>&
- client_message_loop_proxy) {
+ void RenderPDFPagesInSandbox(const base::FilePath& pdf_path,
+ const gfx::Rect& render_area,
+ int render_dpi,
+ const scoped_refptr<base::MessageLoopProxy>&
+ client_message_loop_proxy) {
DCHECK(g_service_process->io_thread()->message_loop_proxy()->
BelongsToCurrentThread());
scoped_ptr<ServiceUtilityProcessHost> utility_host(
// PDF that matches paper size and orientation.
if (utility_host->StartRenderPDFPagesToMetafile(
pdf_path,
- printing::PdfRenderSettings(render_area, render_dpi, false),
- page_ranges)) {
+ printing::PdfRenderSettings(render_area, render_dpi, false))) {
// The object will self-destruct when the child process dies.
utility_host.release();
+ } else {
+ client_message_loop_proxy->PostTask(
+ FROM_HERE, base::Bind(&Core::PrintJobDone, this, false));
}
}
return true;
}
- // Some Cairo-generated PDFs from Chrome OS result in huge metafiles.
- // So the PageCountPerBatch is set to 1 for now.
- // TODO(sanjeevr): Figure out a smarter way to determine the pages per
- // batch. Filed a bug to track this at
- // http://code.google.com/p/chromium/issues/detail?id=57350.
- static const int kPageCountPerBatch = 1;
-
- int last_page_printed_;
PlatformJobId job_id_;
PrintSystem::JobSpooler::Delegate* delegate_;
int saved_dc_;
bool ret = false;
if (printer_handle.IsValid()) {
DWORD bytes_needed = 0;
- GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed);
+ GetJob(printer_handle.Get(), job_id, 1, NULL, 0, &bytes_needed);
DWORD last_error = GetLastError();
if (ERROR_INVALID_PARAMETER != last_error) {
// ERROR_INVALID_PARAMETER normally means that the job id is not valid.
DCHECK(last_error == ERROR_INSUFFICIENT_BUFFER);
scoped_ptr<BYTE[]> job_info_buffer(new BYTE[bytes_needed]);
- if (GetJob(printer_handle, job_id, 1, job_info_buffer.get(), bytes_needed,
- &bytes_needed)) {
+ if (GetJob(printer_handle.Get(), job_id, 1, job_info_buffer.get(),
+ bytes_needed, &bytes_needed)) {
JOB_INFO_1 *job_info =
reinterpret_cast<JOB_INFO_1 *>(job_info_buffer.get());
if (job_info->pStatus) {