| // 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 <stddef.h> |
| |
| #include <algorithm> |
| #include <cmath> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #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<MarginType>(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; |
| int scale_factor = 100; |
| bool rasterize_pdf = false; |
| |
| 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) || |
| !job_settings.GetInteger(kSettingScaleFactor, &scale_factor) || |
| !job_settings.GetBoolean(kSettingRasterizePdf, &rasterize_pdf)) { |
| return false; |
| } |
| #if defined(OS_WIN) |
| int dpi_horizontal = 0; |
| int dpi_vertical = 0; |
| if (!job_settings.GetInteger(kSettingDpiHorizontal, &dpi_horizontal) || |
| !job_settings.GetInteger(kSettingDpiVertical, &dpi_vertical)) { |
| return false; |
| } |
| #endif |
| |
| settings->set_collate(collate); |
| settings->set_copies(copies); |
| settings->SetOrientation(landscape); |
| settings->set_device_name(device_name); |
| settings->set_duplex_mode(static_cast<DuplexMode>(duplex_mode)); |
| settings->set_color(static_cast<ColorModel>(color)); |
| settings->set_scale_factor(static_cast<double>(scale_factor) / 100.0); |
| settings->set_rasterize_pdf(rasterize_pdf); |
| #if defined(OS_WIN) |
| // Modifiable implies HTML and not other formats like PDF. |
| bool can_modify = false; |
| if (job_settings.GetBoolean(kSettingPreviewModifiable, &can_modify)) |
| settings->set_print_text_with_gdi(can_modify); |
| settings->set_dpi_xy(dpi_horizontal, dpi_vertical); |
| #endif |
| |
| 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) { |
| std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); |
| dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1); |
| dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1); |
| page_range_array->Append(std::move(dict)); |
| } |
| } |
| |
| 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->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_id", 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 |