// 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 <algorithm> #include <cmath> #include <string> #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; 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<DuplexMode>(duplex_mode)); settings->set_color(static_cast<ColorModel>(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