Home | History | Annotate | Download | only in printing
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "printing/print_settings_conversion.h"
      6 
      7 #include <algorithm>
      8 #include <cmath>
      9 #include <string>
     10 
     11 #include "base/strings/string_number_conversions.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "base/time/time.h"
     14 #include "base/values.h"
     15 #include "printing/page_size_margins.h"
     16 #include "printing/print_job_constants.h"
     17 #include "printing/print_settings.h"
     18 #include "printing/units.h"
     19 
     20 namespace printing {
     21 
     22 namespace {
     23 
     24 void GetCustomMarginsFromJobSettings(const base::DictionaryValue& settings,
     25                                      PageSizeMargins* page_size_margins) {
     26   const base::DictionaryValue* custom_margins;
     27   if (!settings.GetDictionary(kSettingMarginsCustom, &custom_margins) ||
     28       !custom_margins->GetDouble(kSettingMarginTop,
     29                                  &page_size_margins->margin_top) ||
     30       !custom_margins->GetDouble(kSettingMarginBottom,
     31                                  &page_size_margins->margin_bottom) ||
     32       !custom_margins->GetDouble(kSettingMarginLeft,
     33                                  &page_size_margins->margin_left) ||
     34       !custom_margins->GetDouble(kSettingMarginRight,
     35                                  &page_size_margins->margin_right)) {
     36     NOTREACHED();
     37   }
     38 }
     39 
     40 void SetMarginsToJobSettings(const std::string& json_path,
     41                              const PageMargins& margins,
     42                              base::DictionaryValue* job_settings) {
     43   base::DictionaryValue* dict = new base::DictionaryValue;
     44   job_settings->Set(json_path, dict);
     45   dict->SetInteger(kSettingMarginTop, margins.top);
     46   dict->SetInteger(kSettingMarginBottom, margins.bottom);
     47   dict->SetInteger(kSettingMarginLeft, margins.left);
     48   dict->SetInteger(kSettingMarginRight, margins.right);
     49 }
     50 
     51 void SetSizeToJobSettings(const std::string& json_path,
     52                           const gfx::Size& size,
     53                           base::DictionaryValue* job_settings) {
     54   base::DictionaryValue* dict = new base::DictionaryValue;
     55   job_settings->Set(json_path, dict);
     56   dict->SetInteger("width", size.width());
     57   dict->SetInteger("height", size.height());
     58 }
     59 
     60 void SetRectToJobSettings(const std::string& json_path,
     61                           const gfx::Rect& rect,
     62                           base::DictionaryValue* job_settings) {
     63   base::DictionaryValue* dict = new base::DictionaryValue;
     64   job_settings->Set(json_path, dict);
     65   dict->SetInteger("x", rect.x());
     66   dict->SetInteger("y", rect.y());
     67   dict->SetInteger("width", rect.width());
     68   dict->SetInteger("height", rect.height());
     69 }
     70 
     71 }  // namespace
     72 
     73 bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings,
     74                                   PrintSettings* settings) {
     75   bool display_header_footer = false;
     76   if (!job_settings.GetBoolean(kSettingHeaderFooterEnabled,
     77                                &display_header_footer)) {
     78     return false;
     79   }
     80   settings->set_display_header_footer(display_header_footer);
     81 
     82   if (settings->display_header_footer()) {
     83     base::string16 title;
     84     base::string16 url;
     85     if (!job_settings.GetString(kSettingHeaderFooterTitle, &title) ||
     86         !job_settings.GetString(kSettingHeaderFooterURL, &url)) {
     87       return false;
     88     }
     89     settings->set_title(title);
     90     settings->set_url(url);
     91   }
     92 
     93   bool backgrounds = false;
     94   bool selection_only = false;
     95   if (!job_settings.GetBoolean(kSettingShouldPrintBackgrounds, &backgrounds) ||
     96       !job_settings.GetBoolean(kSettingShouldPrintSelectionOnly,
     97                                &selection_only)) {
     98     return false;
     99   }
    100   settings->set_should_print_backgrounds(backgrounds);
    101   settings->set_selection_only(selection_only);
    102 
    103   PrintSettings::RequestedMedia requested_media;
    104   const base::DictionaryValue* media_size_value = NULL;
    105   if (job_settings.GetDictionary(kSettingMediaSize, &media_size_value)) {
    106     int width_microns = 0;
    107     int height_microns = 0;
    108     if (media_size_value->GetInteger(kSettingMediaSizeWidthMicrons,
    109                                      &width_microns) &&
    110         media_size_value->GetInteger(kSettingMediaSizeHeightMicrons,
    111                                      &height_microns)) {
    112       requested_media.size_microns = gfx::Size(width_microns, height_microns);
    113     }
    114     std::string vendor_id;
    115     if (media_size_value->GetString(kSettingMediaSizeVendorId, &vendor_id) &&
    116         !vendor_id.empty()) {
    117       requested_media.vendor_id = vendor_id;
    118     }
    119   }
    120   settings->set_requested_media(requested_media);
    121 
    122   int margin_type = DEFAULT_MARGINS;
    123   if (!job_settings.GetInteger(kSettingMarginsType, &margin_type) ||
    124       (margin_type != DEFAULT_MARGINS &&
    125        margin_type != NO_MARGINS &&
    126        margin_type != CUSTOM_MARGINS &&
    127        margin_type != PRINTABLE_AREA_MARGINS)) {
    128     margin_type = DEFAULT_MARGINS;
    129   }
    130   settings->set_margin_type(static_cast<MarginType>(margin_type));
    131 
    132   if (margin_type == CUSTOM_MARGINS) {
    133     PageSizeMargins page_size_margins;
    134     GetCustomMarginsFromJobSettings(job_settings, &page_size_margins);
    135 
    136     PageMargins margins_in_points;
    137     margins_in_points.Clear();
    138     margins_in_points.top = page_size_margins.margin_top;
    139     margins_in_points.bottom = page_size_margins.margin_bottom;
    140     margins_in_points.left = page_size_margins.margin_left;
    141     margins_in_points.right = page_size_margins.margin_right;
    142 
    143     settings->SetCustomMargins(margins_in_points);
    144   }
    145 
    146   PageRanges new_ranges;
    147   const base::ListValue* page_range_array = NULL;
    148   if (job_settings.GetList(kSettingPageRange, &page_range_array)) {
    149     for (size_t index = 0; index < page_range_array->GetSize(); ++index) {
    150       const base::DictionaryValue* dict;
    151       if (!page_range_array->GetDictionary(index, &dict))
    152         continue;
    153 
    154       PageRange range;
    155       if (!dict->GetInteger(kSettingPageRangeFrom, &range.from) ||
    156           !dict->GetInteger(kSettingPageRangeTo, &range.to)) {
    157         continue;
    158       }
    159 
    160       // Page numbers are 1-based in the dictionary.
    161       // Page numbers are 0-based for the printing context.
    162       range.from--;
    163       range.to--;
    164       new_ranges.push_back(range);
    165     }
    166   }
    167   settings->set_ranges(new_ranges);
    168 
    169   int color = 0;
    170   bool landscape = false;
    171   int duplex_mode = 0;
    172   base::string16 device_name;
    173   bool collate = false;
    174   int copies = 1;
    175 
    176   if (!job_settings.GetBoolean(kSettingCollate, &collate) ||
    177       !job_settings.GetInteger(kSettingCopies, &copies) ||
    178       !job_settings.GetInteger(kSettingColor, &color) ||
    179       !job_settings.GetInteger(kSettingDuplexMode, &duplex_mode) ||
    180       !job_settings.GetBoolean(kSettingLandscape, &landscape) ||
    181       !job_settings.GetString(kSettingDeviceName, &device_name)) {
    182     return false;
    183   }
    184 
    185   settings->set_collate(collate);
    186   settings->set_copies(copies);
    187   settings->SetOrientation(landscape);
    188   settings->set_device_name(device_name);
    189   settings->set_duplex_mode(static_cast<DuplexMode>(duplex_mode));
    190   settings->set_color(static_cast<ColorModel>(color));
    191 
    192   return true;
    193 }
    194 
    195 void PrintSettingsToJobSettingsDebug(const PrintSettings& settings,
    196                                      base::DictionaryValue* job_settings) {
    197   job_settings->SetBoolean(kSettingHeaderFooterEnabled,
    198                            settings.display_header_footer());
    199   job_settings->SetString(kSettingHeaderFooterTitle, settings.title());
    200   job_settings->SetString(kSettingHeaderFooterURL, settings.url());
    201   job_settings->SetBoolean(kSettingShouldPrintBackgrounds,
    202                            settings.should_print_backgrounds());
    203   job_settings->SetBoolean(kSettingShouldPrintSelectionOnly,
    204                            settings.selection_only());
    205   job_settings->SetInteger(kSettingMarginsType, settings.margin_type());
    206   if (!settings.ranges().empty()) {
    207     base::ListValue* page_range_array = new base::ListValue;
    208     job_settings->Set(kSettingPageRange, page_range_array);
    209     for (size_t i = 0; i < settings.ranges().size(); ++i) {
    210       base::DictionaryValue* dict = new base::DictionaryValue;
    211       page_range_array->Append(dict);
    212       dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1);
    213       dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1);
    214     }
    215   }
    216 
    217   job_settings->SetBoolean(kSettingCollate, settings.collate());
    218   job_settings->SetInteger(kSettingCopies, settings.copies());
    219   job_settings->SetInteger(kSettingColor, settings.color());
    220   job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode());
    221   job_settings->SetBoolean(kSettingLandscape, settings.landscape());
    222   job_settings->SetString(kSettingDeviceName, settings.device_name());
    223 
    224   // Following values are not read form JSON by InitSettings, so do not have
    225   // common public constants. So just serialize in "debug" section.
    226   base::DictionaryValue* debug = new base::DictionaryValue;
    227   job_settings->Set("debug", debug);
    228   debug->SetDouble("minShrink", settings.min_shrink());
    229   debug->SetDouble("maxShrink", settings.max_shrink());
    230   debug->SetInteger("desiredDpi", settings.desired_dpi());
    231   debug->SetInteger("dpi", settings.dpi());
    232   debug->SetInteger("deviceUnitsPerInch", settings.device_units_per_inch());
    233   debug->SetBoolean("support_alpha_blend", settings.should_print_backgrounds());
    234   debug->SetString("media_vendor_od", settings.requested_media().vendor_id);
    235   SetSizeToJobSettings(
    236       "media_size", settings.requested_media().size_microns, debug);
    237   SetMarginsToJobSettings("requested_custom_margins_in_points",
    238                           settings.requested_custom_margins_in_points(),
    239                           debug);
    240   const PageSetup& page_setup = settings.page_setup_device_units();
    241   SetMarginsToJobSettings(
    242       "effective_margins", page_setup.effective_margins(), debug);
    243   SetSizeToJobSettings("physical_size", page_setup.physical_size(), debug);
    244   SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug);
    245   SetRectToJobSettings("content_area", page_setup.content_area(), debug);
    246   SetRectToJobSettings("printable_area", page_setup.printable_area(), debug);
    247 }
    248 
    249 }  // namespace printing
    250