Index: chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
index 4f032c87704de7027e234e2b21efe1641a1b0b95..ec36966f873fae4cbc8a8866eed6fe1041634153 100644 |
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
@@ -4,21 +4,74 @@ |
#include "chrome/browser/ui/webui/print_preview/extension_printer_handler.h" |
+#include <algorithm> |
+ |
#include "base/bind.h" |
#include "base/callback.h" |
-#include "base/values.h" |
+#include "base/files/file_path.h" |
+#include "base/files/file_util.h" |
+#include "base/location.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/ref_counted_memory.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "base/threading/worker_pool.h" |
+#include "chrome/browser/local_discovery/pwg_raster_converter.h" |
#include "components/cloud_devices/common/cloud_device_description.h" |
#include "components/cloud_devices/common/printer_description.h" |
#include "extensions/browser/api/printer_provider/printer_provider_api.h" |
-#include "printing/print_job_constants.h" |
- |
+#include "printing/pdf_render_settings.h" |
+#include "printing/pwg_raster_settings.h" |
+#include "printing/units.h" |
+#include "ui/gfx/geometry/rect.h" |
+#include "ui/gfx/geometry/size.h" |
namespace { |
const char kContentTypePdf[] = "application/pdf"; |
+const char kContentTypePWGRaster[] = "image/pwg-raster"; |
const char kContentTypeAll[] = "*/*"; |
const char kInvalidDataPrintError[] = "INVALID_DATA"; |
+// Reads raster data from file path |raster_path| to a RefCountedMemory object, |
+// which is then passed to |callback| on |response_task_runner|. |
+void ReadConvertedPWGRasterFileOnWorkerThread( |
+ const base::FilePath& raster_path, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, |
+ const ExtensionPrinterHandler::RefCountedMemoryCallback& callback) { |
+ scoped_refptr<base::RefCountedMemory> result; |
+ int64 file_size; |
+ if (base::GetFileSize(raster_path, &file_size) && |
+ file_size <= extensions::PrinterProviderAPI::kMaxDocumentSize) { |
+ scoped_ptr<std::string> data(new std::string()); |
+ data->reserve(file_size); |
+ |
+ if (base::ReadFileToString(raster_path, data.get())) |
+ result = base::RefCountedString::TakeString(data.release()); |
+ } else { |
+ LOG(ERROR) << "Invalid raster file size."; |
+ } |
+ |
+ response_task_runner->PostTask(FROM_HERE, base::Bind(callback, result)); |
+} |
+ |
+// Posts a task to read a file containing converted PWG raster data to the |
+// worker pool. |
+void ReadConvertedPWGRasterFile( |
+ const ExtensionPrinterHandler::RefCountedMemoryCallback& callback, |
+ bool success, |
+ const base::FilePath& pwg_file_path) { |
+ if (!success) { |
+ callback.Run(scoped_refptr<base::RefCountedMemory>()); |
+ return; |
+ } |
+ |
+ base::WorkerPool::GetTaskRunner(true)->PostTask( |
Vitaly Buka (NO REVIEWS)
2015/02/17 19:43:54
PostTaskAndReplyWithResult is appropriate here
tbarzic
2015/02/18 02:55:49
Done.
|
+ FROM_HERE, |
+ base::Bind(&ReadConvertedPWGRasterFileOnWorkerThread, pwg_file_path, |
+ base::ThreadTaskRunnerHandle::Get(), callback)); |
+} |
+ |
} // namespace |
ExtensionPrinterHandler::ExtensionPrinterHandler( |
@@ -59,11 +112,13 @@ void ExtensionPrinterHandler::StartPrint( |
const std::string& destination_id, |
const std::string& capability, |
const std::string& ticket_json, |
+ const gfx::Size& size, |
const scoped_refptr<base::RefCountedMemory>& print_data, |
const PrinterHandler::PrintCallback& callback) { |
- extensions::PrinterProviderAPI::PrintJob print_job; |
- print_job.printer_id = destination_id; |
- print_job.ticket_json = ticket_json; |
+ scoped_ptr<extensions::PrinterProviderAPI::PrintJob> print_job( |
+ new extensions::PrinterProviderAPI::PrintJob()); |
+ print_job->printer_id = destination_id; |
+ print_job->ticket_json = ticket_json; |
cloud_devices::CloudDeviceDescription printer_description; |
printer_description.InitFromString(capability); |
@@ -74,20 +129,63 @@ void ExtensionPrinterHandler::StartPrint( |
const bool kUsePdf = content_types.Contains(kContentTypePdf) || |
content_types.Contains(kContentTypeAll); |
- if (!kUsePdf) { |
- // TODO(tbarzic): Convert data to PWG raster if the printer does not support |
- // PDF. |
+ if (kUsePdf) { |
+ print_job->content_type = kContentTypePdf; |
+ DispatchPrintJob(callback, print_job.Pass(), print_data); |
+ return; |
+ } |
+ |
+ print_job->content_type = kContentTypePWGRaster; |
+ ConvertToPWGRaster(print_data, printer_description, size, |
+ base::Bind(&ExtensionPrinterHandler::DispatchPrintJob, |
+ weak_ptr_factory_.GetWeakPtr(), callback, |
+ base::Passed(&print_job))); |
+} |
+ |
+void ExtensionPrinterHandler::ConvertToPWGRaster( |
+ const scoped_refptr<base::RefCountedMemory>& data, |
+ const cloud_devices::CloudDeviceDescription& printer_description, |
+ const gfx::Size& size, |
Vitaly Buka (NO REVIEWS)
2015/02/17 19:43:54
looks like this code is very similar to privet ver
tbarzic
2015/02/18 02:55:49
Yeah, meant to do that before sending the cl for r
|
+ const ExtensionPrinterHandler::RefCountedMemoryCallback& callback) { |
+ |
+ int dpi = printing::kDefaultPdfDpi; |
+ cloud_devices::printer::DpiCapability dpis; |
+ if (dpis.LoadFrom(printer_description)) |
+ dpi = std::max(dpis.GetDefault().horizontal, dpis.GetDefault().vertical); |
+ |
+ double scale = dpi; |
+ scale /= printing::kPointsPerInch; |
+ |
+ gfx::Rect area(std::min(size.width(), size.height()) * scale, |
+ std::max(size.width(), size.height()) * scale); |
+ |
+ if (!pwg_raster_converter_) { |
+ pwg_raster_converter_ = |
+ local_discovery::PWGRasterConverter::CreateDefault(); |
+ } |
+ pwg_raster_converter_->Start( |
+ data.get(), printing::PdfRenderSettings(area, dpi, true), |
+ printing::PwgRasterSettings(), |
+ base::Bind(&ReadConvertedPWGRasterFile, callback)); |
+ |
+} |
+ |
+void ExtensionPrinterHandler::DispatchPrintJob( |
+ const PrinterHandler::PrintCallback& callback, |
+ scoped_ptr<extensions::PrinterProviderAPI::PrintJob> print_job, |
+ const scoped_refptr<base::RefCountedMemory>& print_data) { |
+ if (!print_data) { |
WrapPrintCallback(callback, false, kInvalidDataPrintError); |
return; |
} |
- print_job.content_type = kContentTypePdf; |
- print_job.document_bytes = print_data; |
+ print_job->document_bytes = print_data; |
+ |
extensions::PrinterProviderAPI::GetFactoryInstance() |
->Get(browser_context_) |
->DispatchPrintRequested( |
- print_job, base::Bind(&ExtensionPrinterHandler::WrapPrintCallback, |
- weak_ptr_factory_.GetWeakPtr(), callback)); |
+ *print_job, base::Bind(&ExtensionPrinterHandler::WrapPrintCallback, |
+ weak_ptr_factory_.GetWeakPtr(), callback)); |
} |
void ExtensionPrinterHandler::WrapGetPrintersCallback( |