diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index 0171951e2b2b..4a58440685b9 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc @@ -12,6 +12,7 @@ #include "base/timer/timer.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/printing/print_job_worker.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "printing/printed_document.h" #include "printing/printed_page.h" @@ -69,7 +70,10 @@ void PrintJob::Initialize(PrintJobWorkerOwner* job, settings_ = job->settings(); PrintedDocument* new_doc = - new PrintedDocument(settings_, source_, job->cookie()); + new PrintedDocument(settings_, + source_, + job->cookie(), + content::BrowserThread::GetBlockingPool()); new_doc->set_page_count(page_count); UpdatePrintedDocument(new_doc); diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 88ef3e9e5c16..f79478514a8b 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc @@ -120,39 +120,19 @@ void PrintJobWorker::SetSettings( DCHECK_EQ(message_loop(), base::MessageLoop::current()); BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), + BrowserThread::UI, + FROM_HERE, + base::Bind(&HoldRefCallback, + make_scoped_refptr(owner_), base::Bind(&PrintJobWorker::UpdatePrintSettings, - base::Unretained(this), new_settings))); + base::Unretained(this), + base::Owned(new_settings)))); } void PrintJobWorker::UpdatePrintSettings( const base::DictionaryValue* const new_settings) { - // Create new PageRanges based on |new_settings|. - PageRanges new_ranges; - const base::ListValue* page_range_array; - if (new_settings->GetList(kSettingPageRange, &page_range_array)) { - for (size_t index = 0; index < page_range_array->GetSize(); ++index) { - const base::DictionaryValue* dict; - if (!page_range_array->GetDictionary(index, &dict)) - continue; - - PageRange range; - if (!dict->GetInteger(kSettingPageRangeFrom, &range.from) || - !dict->GetInteger(kSettingPageRangeTo, &range.to)) { - continue; - } - - // Page numbers are 1-based in the dictionary. - // Page numbers are 0-based for the printing context. - range.from--; - range.to--; - new_ranges.push_back(range); - } - } PrintingContext::Result result = - printing_context_->UpdatePrintSettings(*new_settings, new_ranges); - delete new_settings; + printing_context_->UpdatePrintSettings(*new_settings); GetSettingsDone(result); } @@ -272,8 +252,8 @@ void PrintJobWorker::OnNewPage() { while (true) { // Is the page available? - scoped_refptr page; - if (!document_->GetPage(page_number_.ToInt(), &page)) { + scoped_refptr page = document_->GetPage(page_number_.ToInt()); + if (!page) { // We need to wait for the page to be available. base::MessageLoop::current()->PostDelayedTask( FROM_HERE, diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index a26af75754cb..8dbab4150029 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc @@ -50,12 +50,16 @@ using base::TimeDelta; using content::BrowserThread; +namespace printing { + +namespace { + #if defined(OS_WIN) && !defined(WIN_PDF_METAFILE_FOR_PRINTING) // Limits memory usage by raster to 64 MiB. const int kMaxRasterSizeInPixels = 16*1024*1024; #endif -namespace printing { +} // namespace PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), @@ -234,6 +238,8 @@ void PrintViewManagerBase::OnDidPrintPage( reinterpret_cast(shared_buf.memory()), params.data_size); + document->DebugDumpData(bytes, FILE_PATH_LITERAL(".pdf")); + if (!pdf_to_emf_converter_) pdf_to_emf_converter_ = PdfToEmfConverter::CreateDefault(); diff --git a/printing/BUILD.gn b/printing/BUILD.gn index ac07ec96d23e..6d767aafa9b3 100644 --- a/printing/BUILD.gn +++ b/printing/BUILD.gn @@ -39,7 +39,6 @@ component("printing") { "page_range.h", "page_setup.cc", "page_setup.h", - "page_size_margins.cc", "page_size_margins.h", "pdf_metafile_cg_mac.cc", "pdf_metafile_cg_mac.h", @@ -52,8 +51,8 @@ component("printing") { "print_job_constants.h", "print_settings.cc", "print_settings.h", - "print_settings_initializer.cc", - "print_settings_initializer.h", + "print_settings_conversion.cc", + "print_settings_conversion.h", "print_settings_initializer_mac.cc", "print_settings_initializer_mac.h", "print_settings_initializer_win.cc", diff --git a/printing/page_size_margins.cc b/printing/page_size_margins.cc deleted file mode 100644 index a28c6ada3c84..000000000000 --- a/printing/page_size_margins.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2012 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 "printing/page_size_margins.h" - -#include "base/logging.h" -#include "base/values.h" -#include "printing/print_job_constants.h" - -namespace printing { - -void GetCustomMarginsFromJobSettings(const base::DictionaryValue& settings, - PageSizeMargins* page_size_margins) { - const base::DictionaryValue* custom_margins; - if (!settings.GetDictionary(kSettingMarginsCustom, &custom_margins) || - !custom_margins->GetDouble(kSettingMarginTop, - &page_size_margins->margin_top) || - !custom_margins->GetDouble(kSettingMarginBottom, - &page_size_margins->margin_bottom) || - !custom_margins->GetDouble(kSettingMarginLeft, - &page_size_margins->margin_left) || - !custom_margins->GetDouble(kSettingMarginRight, - &page_size_margins->margin_right)) { - NOTREACHED(); - } -} - -} // namespace printing diff --git a/printing/page_size_margins.h b/printing/page_size_margins.h index b6913724a90b..478730850a32 100644 --- a/printing/page_size_margins.h +++ b/printing/page_size_margins.h @@ -7,10 +7,6 @@ #include "printing/printing_export.h" -namespace base { -class DictionaryValue; -} - namespace printing { // Struct that holds margin and content area sizes of a page. Units are @@ -24,9 +20,6 @@ struct PageSizeMargins { double margin_left; }; -PRINTING_EXPORT void GetCustomMarginsFromJobSettings( - const base::DictionaryValue& settings, PageSizeMargins* page_size_margins); - } // namespace printing #endif // PRINTING_PAGE_SIZE_MARGINS_H_ diff --git a/printing/print_settings.h b/printing/print_settings.h index b942189c2c2f..01b3135fbee3 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h @@ -49,6 +49,9 @@ class PRINTING_EXPORT PrintSettings { void Clear(); void SetCustomMargins(const PageMargins& requested_margins_in_points); + const PageMargins& requested_custom_margins_in_points() const { + return requested_custom_margins_in_points_; + } void set_margin_type(MarginType margin_type) { margin_type_ = margin_type; } MarginType margin_type() const { return margin_type_; } diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc new file mode 100644 index 000000000000..a0c5eacf33bc --- /dev/null +++ b/printing/print_settings_conversion.cc @@ -0,0 +1,249 @@ +// 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 "printing/print_settings_conversion.h" + +#include +#include +#include + +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "base/values.h" +#include "printing/page_size_margins.h" +#include "printing/print_job_constants.h" +#include "printing/print_settings.h" +#include "printing/units.h" + +namespace printing { + +namespace { + +void GetCustomMarginsFromJobSettings(const base::DictionaryValue& settings, + PageSizeMargins* page_size_margins) { + const base::DictionaryValue* custom_margins; + if (!settings.GetDictionary(kSettingMarginsCustom, &custom_margins) || + !custom_margins->GetDouble(kSettingMarginTop, + &page_size_margins->margin_top) || + !custom_margins->GetDouble(kSettingMarginBottom, + &page_size_margins->margin_bottom) || + !custom_margins->GetDouble(kSettingMarginLeft, + &page_size_margins->margin_left) || + !custom_margins->GetDouble(kSettingMarginRight, + &page_size_margins->margin_right)) { + NOTREACHED(); + } +} + +void SetMarginsToJobSettings(const std::string& json_path, + const PageMargins& margins, + base::DictionaryValue* job_settings) { + base::DictionaryValue* dict = new base::DictionaryValue; + job_settings->Set(json_path, dict); + dict->SetInteger(kSettingMarginTop, margins.top); + dict->SetInteger(kSettingMarginBottom, margins.bottom); + dict->SetInteger(kSettingMarginLeft, margins.left); + dict->SetInteger(kSettingMarginRight, margins.right); +} + +void SetSizeToJobSettings(const std::string& json_path, + const gfx::Size& size, + base::DictionaryValue* job_settings) { + base::DictionaryValue* dict = new base::DictionaryValue; + job_settings->Set(json_path, dict); + dict->SetInteger("width", size.width()); + dict->SetInteger("height", size.height()); +} + +void SetRectToJobSettings(const std::string& json_path, + const gfx::Rect& rect, + base::DictionaryValue* job_settings) { + base::DictionaryValue* dict = new base::DictionaryValue; + job_settings->Set(json_path, dict); + dict->SetInteger("x", rect.x()); + dict->SetInteger("y", rect.y()); + dict->SetInteger("width", rect.width()); + dict->SetInteger("height", rect.height()); +} + +} // namespace + +bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings, + PrintSettings* settings) { + bool display_header_footer = false; + if (!job_settings.GetBoolean(kSettingHeaderFooterEnabled, + &display_header_footer)) { + return false; + } + settings->set_display_header_footer(display_header_footer); + + if (settings->display_header_footer()) { + base::string16 title; + base::string16 url; + if (!job_settings.GetString(kSettingHeaderFooterTitle, &title) || + !job_settings.GetString(kSettingHeaderFooterURL, &url)) { + return false; + } + settings->set_title(title); + settings->set_url(url); + } + + bool backgrounds = false; + bool selection_only = false; + if (!job_settings.GetBoolean(kSettingShouldPrintBackgrounds, &backgrounds) || + !job_settings.GetBoolean(kSettingShouldPrintSelectionOnly, + &selection_only)) { + return false; + } + settings->set_should_print_backgrounds(backgrounds); + settings->set_selection_only(selection_only); + + PrintSettings::RequestedMedia requested_media; + const base::DictionaryValue* media_size_value = NULL; + if (job_settings.GetDictionary(kSettingMediaSize, &media_size_value)) { + int width_microns = 0; + int height_microns = 0; + if (media_size_value->GetInteger(kSettingMediaSizeWidthMicrons, + &width_microns) && + media_size_value->GetInteger(kSettingMediaSizeHeightMicrons, + &height_microns)) { + requested_media.size_microns = gfx::Size(width_microns, height_microns); + } + std::string vendor_id; + if (media_size_value->GetString(kSettingMediaSizeVendorId, &vendor_id) && + !vendor_id.empty()) { + requested_media.vendor_id = vendor_id; + } + } + settings->set_requested_media(requested_media); + + int margin_type = DEFAULT_MARGINS; + if (!job_settings.GetInteger(kSettingMarginsType, &margin_type) || + (margin_type != DEFAULT_MARGINS && + margin_type != NO_MARGINS && + margin_type != CUSTOM_MARGINS && + margin_type != PRINTABLE_AREA_MARGINS)) { + margin_type = DEFAULT_MARGINS; + } + settings->set_margin_type(static_cast(margin_type)); + + if (margin_type == CUSTOM_MARGINS) { + PageSizeMargins page_size_margins; + GetCustomMarginsFromJobSettings(job_settings, &page_size_margins); + + PageMargins margins_in_points; + margins_in_points.Clear(); + margins_in_points.top = page_size_margins.margin_top; + margins_in_points.bottom = page_size_margins.margin_bottom; + margins_in_points.left = page_size_margins.margin_left; + margins_in_points.right = page_size_margins.margin_right; + + settings->SetCustomMargins(margins_in_points); + } + + PageRanges new_ranges; + const base::ListValue* page_range_array = NULL; + if (job_settings.GetList(kSettingPageRange, &page_range_array)) { + for (size_t index = 0; index < page_range_array->GetSize(); ++index) { + const base::DictionaryValue* dict; + if (!page_range_array->GetDictionary(index, &dict)) + continue; + + PageRange range; + if (!dict->GetInteger(kSettingPageRangeFrom, &range.from) || + !dict->GetInteger(kSettingPageRangeTo, &range.to)) { + continue; + } + + // Page numbers are 1-based in the dictionary. + // Page numbers are 0-based for the printing context. + range.from--; + range.to--; + new_ranges.push_back(range); + } + } + settings->set_ranges(new_ranges); + + int color = 0; + bool landscape = false; + int duplex_mode = 0; + base::string16 device_name; + bool collate = false; + int copies = 1; + + if (!job_settings.GetBoolean(kSettingCollate, &collate) || + !job_settings.GetInteger(kSettingCopies, &copies) || + !job_settings.GetInteger(kSettingColor, &color) || + !job_settings.GetInteger(kSettingDuplexMode, &duplex_mode) || + !job_settings.GetBoolean(kSettingLandscape, &landscape) || + !job_settings.GetString(kSettingDeviceName, &device_name)) { + return false; + } + + settings->set_collate(collate); + settings->set_copies(copies); + settings->SetOrientation(landscape); + settings->set_device_name(device_name); + settings->set_duplex_mode(static_cast(duplex_mode)); + settings->set_color(static_cast(color)); + + return true; +} + +void PrintSettingsToJobSettingsDebug(const PrintSettings& settings, + base::DictionaryValue* job_settings) { + job_settings->SetBoolean(kSettingHeaderFooterEnabled, + settings.display_header_footer()); + job_settings->SetString(kSettingHeaderFooterTitle, settings.title()); + job_settings->SetString(kSettingHeaderFooterURL, settings.url()); + job_settings->SetBoolean(kSettingShouldPrintBackgrounds, + settings.should_print_backgrounds()); + job_settings->SetBoolean(kSettingShouldPrintSelectionOnly, + settings.selection_only()); + job_settings->SetInteger(kSettingMarginsType, settings.margin_type()); + if (!settings.ranges().empty()) { + base::ListValue* page_range_array = new base::ListValue; + job_settings->Set(kSettingPageRange, page_range_array); + for (size_t i = 0; i < settings.ranges().size(); ++i) { + base::DictionaryValue* dict = new base::DictionaryValue; + page_range_array->Append(dict); + dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1); + dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1); + } + } + + job_settings->SetBoolean(kSettingCollate, settings.collate()); + job_settings->SetInteger(kSettingCopies, settings.copies()); + job_settings->SetInteger(kSettingColor, settings.color()); + job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode()); + job_settings->SetBoolean(kSettingLandscape, settings.landscape()); + job_settings->SetString(kSettingDeviceName, settings.device_name()); + + // Following values are not read form JSON by InitSettings, so do not have + // common public constants. So just serialize in "debug" section. + base::DictionaryValue* debug = new base::DictionaryValue; + job_settings->Set("debug", debug); + debug->SetDouble("minShrink", settings.min_shrink()); + debug->SetDouble("maxShrink", settings.max_shrink()); + debug->SetInteger("desiredDpi", settings.desired_dpi()); + debug->SetInteger("dpi", settings.dpi()); + debug->SetInteger("deviceUnitsPerInch", settings.device_units_per_inch()); + debug->SetBoolean("support_alpha_blend", settings.should_print_backgrounds()); + debug->SetString("media_vendor_od", settings.requested_media().vendor_id); + SetSizeToJobSettings( + "media_size", settings.requested_media().size_microns, debug); + SetMarginsToJobSettings("requested_custom_margins_in_points", + settings.requested_custom_margins_in_points(), + debug); + const PageSetup& page_setup = settings.page_setup_device_units(); + SetMarginsToJobSettings( + "effective_margins", page_setup.effective_margins(), debug); + SetSizeToJobSettings("physical_size", page_setup.physical_size(), debug); + SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug); + SetRectToJobSettings("content_area", page_setup.content_area(), debug); + SetRectToJobSettings("printable_area", page_setup.printable_area(), debug); +} + +} // namespace printing diff --git a/printing/print_settings_conversion.h b/printing/print_settings_conversion.h new file mode 100644 index 000000000000..92e8670c06e6 --- /dev/null +++ b/printing/print_settings_conversion.h @@ -0,0 +1,31 @@ +// 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. + +#ifndef PRINTING_PRINT_SETTINGS_CONVERSION_H_ +#define PRINTING_PRINT_SETTINGS_CONVERSION_H_ + +#include "base/basictypes.h" +#include "base/logging.h" +#include "printing/page_range.h" +#include "printing/printing_export.h" + +namespace base { +class DictionaryValue; +} + +namespace printing { + +class PrintSettings; + +bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings, + PrintSettings* print_settings); + +// Use for debug only, because output is not completely consistent with format +// of |PrintSettingsFromJobSettings| input. +void PrintSettingsToJobSettingsDebug(const PrintSettings& settings, + base::DictionaryValue* job_settings); + +} // namespace printing + +#endif // PRINTING_PRINT_SETTINGS_CONVERSION_H_ diff --git a/printing/print_settings_initializer.cc b/printing/print_settings_initializer.cc deleted file mode 100644 index df6a32e40e5a..000000000000 --- a/printing/print_settings_initializer.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2011 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 "printing/print_settings_initializer.h" - -#include -#include -#include - -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "base/values.h" -#include "printing/page_size_margins.h" -#include "printing/print_job_constants.h" -#include "printing/print_settings.h" -#include "printing/units.h" - -namespace printing { - -bool PrintSettingsInitializer::InitSettings( - const base::DictionaryValue& job_settings, - const PageRanges& ranges, - PrintSettings* settings) { - bool display_header_footer = false; - if (!job_settings.GetBoolean(kSettingHeaderFooterEnabled, - &display_header_footer)) { - return false; - } - settings->set_display_header_footer(display_header_footer); - - if (settings->display_header_footer()) { - base::string16 title; - base::string16 url; - if (!job_settings.GetString(kSettingHeaderFooterTitle, &title) || - !job_settings.GetString(kSettingHeaderFooterURL, &url)) { - return false; - } - settings->set_title(title); - settings->set_url(url); - } - - bool backgrounds = false; - bool selection_only = false; - if (!job_settings.GetBoolean(kSettingShouldPrintBackgrounds, &backgrounds) || - !job_settings.GetBoolean(kSettingShouldPrintSelectionOnly, - &selection_only)) { - return false; - } - settings->set_should_print_backgrounds(backgrounds); - settings->set_selection_only(selection_only); - - PrintSettings::RequestedMedia requested_media; - const base::DictionaryValue* media_size_value = NULL; - if (job_settings.GetDictionary(kSettingMediaSize, &media_size_value)) { - int width_microns = 0; - int height_microns = 0; - if (media_size_value->GetInteger(kSettingMediaSizeWidthMicrons, - &width_microns) && - media_size_value->GetInteger(kSettingMediaSizeHeightMicrons, - &height_microns)) { - requested_media.size_microns = gfx::Size(width_microns, height_microns); - } - std::string vendor_id; - if (media_size_value->GetString(kSettingMediaSizeVendorId, &vendor_id) && - !vendor_id.empty()) { - requested_media.vendor_id = vendor_id; - } - } - settings->set_requested_media(requested_media); - - int margin_type = DEFAULT_MARGINS; - if (!job_settings.GetInteger(kSettingMarginsType, &margin_type) || - (margin_type != DEFAULT_MARGINS && - margin_type != NO_MARGINS && - margin_type != CUSTOM_MARGINS && - margin_type != PRINTABLE_AREA_MARGINS)) { - margin_type = DEFAULT_MARGINS; - } - settings->set_margin_type(static_cast(margin_type)); - - if (margin_type == CUSTOM_MARGINS) { - PageSizeMargins page_size_margins; - GetCustomMarginsFromJobSettings(job_settings, &page_size_margins); - - PageMargins margins_in_points; - margins_in_points.Clear(); - margins_in_points.top = page_size_margins.margin_top; - margins_in_points.bottom = page_size_margins.margin_bottom; - margins_in_points.left = page_size_margins.margin_left; - margins_in_points.right = page_size_margins.margin_right; - - settings->SetCustomMargins(margins_in_points); - } - - settings->set_ranges(ranges); - - int color = 0; - bool landscape = false; - int duplex_mode = 0; - base::string16 device_name; - bool collate = false; - int copies = 1; - - if (!job_settings.GetBoolean(kSettingCollate, &collate) || - !job_settings.GetInteger(kSettingCopies, &copies) || - !job_settings.GetInteger(kSettingColor, &color) || - !job_settings.GetInteger(kSettingDuplexMode, &duplex_mode) || - !job_settings.GetBoolean(kSettingLandscape, &landscape) || - !job_settings.GetString(kSettingDeviceName, &device_name)) { - return false; - } - - settings->set_collate(collate); - settings->set_copies(copies); - settings->SetOrientation(landscape); - settings->set_device_name(device_name); - settings->set_duplex_mode(static_cast(duplex_mode)); - settings->set_color(static_cast(color)); - - return true; -} - -} // namespace printing diff --git a/printing/print_settings_initializer.h b/printing/print_settings_initializer.h deleted file mode 100644 index a1093c5a3b86..000000000000 --- a/printing/print_settings_initializer.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef PRINTING_PRINT_SETTINGS_INITIALIZER_H_ -#define PRINTING_PRINT_SETTINGS_INITIALIZER_H_ - -#include "base/basictypes.h" -#include "base/logging.h" -#include "printing/page_range.h" -#include "printing/printing_export.h" - -namespace base { -class DictionaryValue; -} - -namespace printing { - -class PrintSettings; - -// Initializes the header footer strings in the PrintSettings object from the -// provided |job_settings|. -class PRINTING_EXPORT PrintSettingsInitializer { - public: - static bool InitSettings( - const base::DictionaryValue& job_settings, - const PageRanges& ranges, - PrintSettings* print_settings); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(PrintSettingsInitializer); -}; - -} // namespace printing - -#endif // PRINTING_PRINT_SETTINGS_INITIALIZER_H_ - diff --git a/printing/printed_document.cc b/printing/printed_document.cc index 77e3953f4d82..6d2a9a037ddc 100644 --- a/printing/printed_document.cc +++ b/printing/printed_document.cc @@ -9,16 +9,23 @@ #include #include +#include "base/bind.h" #include "base/file_util.h" #include "base/files/file_path.h" #include "base/i18n/file_util_icu.h" #include "base/i18n/time_formatting.h" +#include "base/json/json_writer.h" #include "base/lazy_instance.h" +#include "base/memory/ref_counted_memory.h" #include "base/message_loop/message_loop.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "base/values.h" #include "printing/page_number.h" +#include "printing/print_settings_conversion.h" #include "printing/printed_page.h" #include "printing/printed_pages_source.h" #include "printing/units.h" @@ -26,30 +33,65 @@ #include "ui/gfx/font.h" #include "ui/gfx/text_elider.h" +namespace printing { + namespace { -struct PrintDebugDumpPath { - PrintDebugDumpPath() - : enabled(false) { - } +base::LazyInstance g_debug_dump_info = + LAZY_INSTANCE_INITIALIZER; - bool enabled; - base::FilePath debug_dump_path; -}; +void DebugDumpPageTask(const base::string16& doc_name, + const PrintedPage* page) { + if (g_debug_dump_info.Get().empty()) + return; -base::LazyInstance g_debug_dump_info = - LAZY_INSTANCE_INITIALIZER; + base::string16 filename = doc_name; + filename += + base::ASCIIToUTF16(base::StringPrintf("_%04d", page->page_number())); +#if defined(OS_WIN) + page->metafile()->SaveTo(PrintedDocument::CreateDebugDumpPath( + filename, FILE_PATH_LITERAL(".emf"))); +#else // OS_WIN + page->metafile()->SaveTo(PrintedDocument::CreateDebugDumpPath( + filename, FILE_PATH_LITERAL(".pdf"))); +#endif // OS_WIN +} -} // namespace +void DebugDumpDataTask(const base::string16& doc_name, + const base::FilePath::StringType& extension, + const base::RefCountedMemory* data) { + base::FilePath path = + PrintedDocument::CreateDebugDumpPath(doc_name, extension); + if (path.empty()) + return; + base::WriteFile(path, + reinterpret_cast(data->front()), + base::checked_cast(data->size())); +} -namespace printing { +void DebugDumpSettings(const base::string16& doc_name, + const PrintSettings& settings, + base::TaskRunner* blocking_runner) { + base::DictionaryValue job_settings; + PrintSettingsToJobSettingsDebug(settings, &job_settings); + std::string settings_str; + base::JSONWriter::WriteWithOptions( + &job_settings, base::JSONWriter::OPTIONS_PRETTY_PRINT, &settings_str); + scoped_refptr data = + base::RefCountedString::TakeString(&settings_str); + blocking_runner->PostTask( + FROM_HERE, + base::Bind( + &DebugDumpDataTask, doc_name, FILE_PATH_LITERAL(".json"), data)); +} + +} // namespace PrintedDocument::PrintedDocument(const PrintSettings& settings, PrintedPagesSource* source, - int cookie) - : mutable_(source), - immutable_(settings, source, cookie) { - + int cookie, + base::TaskRunner* blocking_runner) + : mutable_(source), immutable_(settings, source, cookie, blocking_runner) { // Records the expected page count if a range is setup. if (!settings.ranges().empty()) { // If there is a range, set the number of page @@ -58,6 +100,9 @@ PrintedDocument::PrintedDocument(const PrintSettings& settings, mutable_.expected_page_count_ += range.to - range.from + 1; } } + + if (!g_debug_dump_info.Get().empty()) + DebugDumpSettings(name(), settings, blocking_runner); } PrintedDocument::~PrintedDocument() { @@ -86,20 +131,22 @@ void PrintedDocument::SetPage(int page_number, mutable_.first_page = page_number; #endif } - DebugDump(*page.get()); + + if (!g_debug_dump_info.Get().empty()) { + immutable_.blocking_runner_->PostTask( + FROM_HERE, base::Bind(&DebugDumpPageTask, name(), page)); + } } -bool PrintedDocument::GetPage(int page_number, - scoped_refptr* page) { - base::AutoLock lock(lock_); - PrintedPages::const_iterator itr = mutable_.pages_.find(page_number); - if (itr != mutable_.pages_.end()) { - if (itr->second.get()) { - *page = itr->second; - return true; - } +scoped_refptr PrintedDocument::GetPage(int page_number) { + scoped_refptr page; + { + base::AutoLock lock(lock_); + PrintedPages::const_iterator itr = mutable_.pages_.find(page_number); + if (itr != mutable_.pages_.end()) + page = itr->second; } - return false; + return page; } bool PrintedDocument::IsComplete() const { @@ -173,35 +220,40 @@ int PrintedDocument::expected_page_count() const { return mutable_.expected_page_count_; } -void PrintedDocument::DebugDump(const PrintedPage& page) { - if (!g_debug_dump_info.Get().enabled) - return; +void PrintedDocument::set_debug_dump_path( + const base::FilePath& debug_dump_path) { + g_debug_dump_info.Get() = debug_dump_path; +} +base::FilePath PrintedDocument::CreateDebugDumpPath( + const base::string16& document_name, + const base::FilePath::StringType& extension) { + if (g_debug_dump_info.Get().empty()) + return base::FilePath(); + // Create a filename. base::string16 filename; - filename += name(); + base::Time now(base::Time::Now()); + filename = base::TimeFormatShortDateAndTime(now); filename += base::ASCIIToUTF16("_"); - filename += base::ASCIIToUTF16( - base::StringPrintf("%02d", page.page_number())); + filename += document_name; + base::FilePath::StringType system_filename; #if defined(OS_WIN) - filename += base::ASCIIToUTF16("_.emf"); - page.metafile()->SaveTo( - g_debug_dump_info.Get().debug_dump_path.Append(filename)); -#else // OS_WIN - filename += base::ASCIIToUTF16("_.pdf"); - page.metafile()->SaveTo( - g_debug_dump_info.Get().debug_dump_path.Append( - base::UTF16ToUTF8(filename))); + system_filename = filename; +#else // OS_WIN + system_filename = base::UTF16ToUTF8(filename); #endif // OS_WIN + file_util::ReplaceIllegalCharactersInPath(&system_filename, '_'); + return g_debug_dump_info.Get().Append(system_filename).AddExtension( + extension); } -void PrintedDocument::set_debug_dump_path( - const base::FilePath& debug_dump_path) { - g_debug_dump_info.Get().enabled = !debug_dump_path.empty(); - g_debug_dump_info.Get().debug_dump_path = debug_dump_path; -} - -const base::FilePath& PrintedDocument::debug_dump_path() { - return g_debug_dump_info.Get().debug_dump_path; +void PrintedDocument::DebugDumpData( + const base::RefCountedMemory* data, + const base::FilePath::StringType& extension) { + if (g_debug_dump_info.Get().empty()) + return; + immutable_.blocking_runner_->PostTask( + FROM_HERE, base::Bind(&DebugDumpDataTask, name(), extension, data)); } PrintedDocument::Mutable::Mutable(PrintedPagesSource* source) @@ -218,11 +270,12 @@ PrintedDocument::Mutable::~Mutable() { PrintedDocument::Immutable::Immutable(const PrintSettings& settings, PrintedPagesSource* source, - int cookie) + int cookie, + base::TaskRunner* blocking_runner) : settings_(settings), - source_message_loop_(base::MessageLoop::current()), name_(source->RenderSourceName()), - cookie_(cookie) { + cookie_(cookie), + blocking_runner_(blocking_runner) { } PrintedDocument::Immutable::~Immutable() { diff --git a/printing/printed_document.h b/printing/printed_document.h index 3341d54221ab..4d0e41ec5d0f 100644 --- a/printing/printed_document.h +++ b/printing/printed_document.h @@ -7,6 +7,7 @@ #include +#include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "base/synchronization/lock.h" @@ -14,8 +15,8 @@ #include "ui/gfx/native_widget_types.h" namespace base { -class FilePath; -class MessageLoop; +class RefCountedMemory; +class TaskRunner; } namespace printing { @@ -38,7 +39,8 @@ class PRINTING_EXPORT PrintedDocument // originating source and settings. PrintedDocument(const PrintSettings& settings, PrintedPagesSource* source, - int cookie); + int cookie, + base::TaskRunner* blocking_runner); // Sets a page's data. 0-based. Takes metafile ownership. // Note: locks for a short amount of time. @@ -51,9 +53,9 @@ class PRINTING_EXPORT PrintedDocument const gfx::Rect& page_rect); // Retrieves a page. If the page is not available right now, it - // requests to have this page be rendered and returns false. + // requests to have this page be rendered and returns NULL. // Note: locks for a short amount of time. - bool GetPage(int page_number, scoped_refptr* page); + scoped_refptr GetPage(int page_number); // Draws the page in the context. // Note: locks for a short amount of time in debug only. @@ -102,7 +104,16 @@ class PRINTING_EXPORT PrintedDocument // no files are generated. static void set_debug_dump_path(const base::FilePath& debug_dump_path); - static const base::FilePath& debug_dump_path(); + // Creates debug file name from given |document_name| and |extension|. + // |extension| should include '.', example ".pdf" + // Returns empty |base::FilePath| if debug dumps is not enabled. + static base::FilePath CreateDebugDumpPath( + const base::string16& document_name, + const base::FilePath::StringType& extension); + + // Dump data on blocking task runner if debug dumps enabled. + void DebugDumpData(const base::RefCountedMemory* data, + const base::FilePath::StringType& extension); private: friend class base::RefCountedThreadSafe; @@ -143,16 +154,15 @@ class PRINTING_EXPORT PrintedDocument // any lock held. This is because it can't be changed after the object's // construction. struct Immutable { - Immutable(const PrintSettings& settings, PrintedPagesSource* source, - int cookie); + Immutable(const PrintSettings& settings, + PrintedPagesSource* source, + int cookie, + base::TaskRunner* blocking_runner); ~Immutable(); // Print settings used to generate this document. Immutable. PrintSettings settings_; - // Native thread for the render source. - base::MessageLoop* source_message_loop_; - // Document name. Immutable. base::string16 name_; @@ -163,9 +173,10 @@ class PRINTING_EXPORT PrintedDocument // simpler hash of PrintSettings since a new document is made each time the // print settings change. int cookie_; - }; - void DebugDump(const PrintedPage& page); + // Native thread for blocking operations, like file access. + scoped_refptr blocking_runner_; + }; // All writable data member access must be guarded by this lock. Needs to be // mutable since it can be acquired from const member functions. diff --git a/printing/printing.gyp b/printing/printing.gyp index 1b0448ea970c..bfec0fc450a7 100644 --- a/printing/printing.gyp +++ b/printing/printing.gyp @@ -53,7 +53,6 @@ 'page_range.h', 'page_setup.cc', 'page_setup.h', - 'page_size_margins.cc', 'page_size_margins.h', 'pdf_metafile_cg_mac.cc', 'pdf_metafile_cg_mac.h', @@ -66,8 +65,8 @@ 'print_job_constants.h', 'print_settings.cc', 'print_settings.h', - 'print_settings_initializer.cc', - 'print_settings_initializer.h', + 'print_settings_conversion.cc', + 'print_settings_conversion.h', 'print_settings_initializer_mac.cc', 'print_settings_initializer_mac.h', 'print_settings_initializer_win.cc', diff --git a/printing/printing_context.cc b/printing/printing_context.cc index c7cd644c2f7f..bcafb40ad82a 100644 --- a/printing/printing_context.cc +++ b/printing/printing_context.cc @@ -9,7 +9,7 @@ #include "printing/page_setup.h" #include "printing/page_size_margins.h" #include "printing/print_job_constants.h" -#include "printing/print_settings_initializer.h" +#include "printing/print_settings_conversion.h" #include "printing/units.h" namespace printing { @@ -63,16 +63,14 @@ PrintingContext::Result PrintingContext::UsePdfSettings() { pdf_settings->SetBoolean(kSettingPrintToPDF, true); pdf_settings->SetBoolean(kSettingCloudPrintDialog, false); pdf_settings->SetBoolean(kSettingPrintWithPrivet, false); - return UpdatePrintSettings(*pdf_settings, PageRanges()); + return UpdatePrintSettings(*pdf_settings); } PrintingContext::Result PrintingContext::UpdatePrintSettings( - const base::DictionaryValue& job_settings, - const PageRanges& ranges) { + const base::DictionaryValue& job_settings) { ResetSettings(); - if (!PrintSettingsInitializer::InitSettings(job_settings, ranges, - &settings_)) { + if (!PrintSettingsFromJobSettings(job_settings, &settings_)) { NOTREACHED(); return OnError(); } @@ -100,9 +98,9 @@ PrintingContext::Result PrintingContext::UpdatePrintSettings( float deviceMicronsPerDeviceUnit = (kHundrethsMMPerInch * 10.0f) / settings_.device_units_per_inch(); paper_size = gfx::Size(settings_.requested_media().size_microns.width() / - deviceMicronsPerDeviceUnit, + deviceMicronsPerDeviceUnit, settings_.requested_media().size_microns.height() / - deviceMicronsPerDeviceUnit); + deviceMicronsPerDeviceUnit); } gfx::Rect paper_rect(0, 0, paper_size.width(), paper_size.height()); if (print_to_cloud || print_with_privet) { diff --git a/printing/printing_context.h b/printing/printing_context.h index fedf696f4494..823a5af44667 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h @@ -64,8 +64,7 @@ class PRINTING_EXPORT PrintingContext { // Updates Print Settings. |job_settings| contains all print job // settings information. |ranges| has the new page range settings. - Result UpdatePrintSettings(const base::DictionaryValue& job_settings, - const PageRanges& ranges); + Result UpdatePrintSettings(const base::DictionaryValue& job_settings); // Initializes with predefined settings. virtual Result InitWithSettings(const PrintSettings& settings) = 0; diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc index f68482d3a610..6d81cd9c9482 100644 --- a/printing/printing_context_win.cc +++ b/printing/printing_context_win.cc @@ -8,12 +8,9 @@ #include -#include "base/i18n/file_util_icu.h" -#include "base/i18n/time_formatting.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" #include "base/values.h" #include "printing/backend/print_backend.h" #include "printing/backend/printing_info_win.h" @@ -31,8 +28,6 @@ #include "ui/aura/window_event_dispatcher.h" #endif -using base::Time; - namespace { HWND GetRootWindow(gfx::NativeView view) { @@ -408,22 +403,11 @@ PrintingContext::Result PrintingContextWin::NewDocument( di.lpszDocName = document_name.c_str(); // Is there a debug dump directory specified? If so, force to print to a file. - base::FilePath debug_dump_path = PrintedDocument::debug_dump_path(); - if (!debug_dump_path.empty()) { - // Create a filename. - std::wstring filename; - Time now(Time::Now()); - filename = base::TimeFormatShortDateNumeric(now); - filename += L"_"; - filename += base::TimeFormatTimeOfDay(now); - filename += L"_"; - filename += document_name; - filename += L"_"; - filename += L"buffer.prn"; - file_util::ReplaceIllegalCharactersInPath(&filename, '_'); - debug_dump_path = debug_dump_path.Append(filename); - di.lpszOutput = debug_dump_path.value().c_str(); - } + base::string16 debug_dump_path = + PrintedDocument::CreateDebugDumpPath(document_name, + FILE_PATH_LITERAL(".prn")).value(); + if (!debug_dump_path.empty()) + di.lpszOutput = debug_dump_path.c_str(); // No message loop running in unit tests. DCHECK(!base::MessageLoop::current() ||