Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / printing / print_settings_conversion.cc
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 <stddef.h>
8
9 #include <algorithm>
10 #include <cmath>
11 #include <memory>
12 #include <string>
13 #include <utility>
14
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/time/time.h"
18 #include "base/values.h"
19 #include "build/build_config.h"
20 #include "printing/print_job_constants.h"
21 #include "printing/print_settings.h"
22 #include "printing/units.h"
23
24 namespace printing {
25
26 namespace {
27
28 void GetCustomMarginsFromJobSettings(const base::Value& settings,
29                                      PageMargins* page_size_margins) {
30   const base::Value* custom_margins = settings.FindKey(kSettingMarginsCustom);
31   if (!custom_margins) {
32     NOTREACHED();
33     return;
34   }
35   page_size_margins->top =
36       custom_margins->FindKey(kSettingMarginTop)->GetDouble();
37   page_size_margins->bottom =
38       custom_margins->FindKey(kSettingMarginBottom)->GetDouble();
39   page_size_margins->left =
40       custom_margins->FindKey(kSettingMarginLeft)->GetDouble();
41   page_size_margins->right =
42       custom_margins->FindKey(kSettingMarginRight)->GetDouble();
43 }
44
45 void SetMarginsToJobSettings(const std::string& json_path,
46                              const PageMargins& margins,
47                              base::DictionaryValue* job_settings) {
48   auto dict = std::make_unique<base::DictionaryValue>();
49   dict->SetInteger(kSettingMarginTop, margins.top);
50   dict->SetInteger(kSettingMarginBottom, margins.bottom);
51   dict->SetInteger(kSettingMarginLeft, margins.left);
52   dict->SetInteger(kSettingMarginRight, margins.right);
53   job_settings->Set(json_path, std::move(dict));
54 }
55
56 void SetSizeToJobSettings(const std::string& json_path,
57                           const gfx::Size& size,
58                           base::DictionaryValue* job_settings) {
59   auto dict = std::make_unique<base::DictionaryValue>();
60   dict->SetInteger("width", size.width());
61   dict->SetInteger("height", size.height());
62   job_settings->Set(json_path, std::move(dict));
63 }
64
65 void SetRectToJobSettings(const std::string& json_path,
66                           const gfx::Rect& rect,
67                           base::DictionaryValue* job_settings) {
68   auto dict = std::make_unique<base::DictionaryValue>();
69   dict->SetInteger("x", rect.x());
70   dict->SetInteger("y", rect.y());
71   dict->SetInteger("width", rect.width());
72   dict->SetInteger("height", rect.height());
73   job_settings->Set(json_path, std::move(dict));
74 }
75
76 }  // namespace
77
78 bool PrintSettingsFromJobSettings(const base::Value& job_settings,
79                                   PrintSettings* settings) {
80   base::Optional<bool> display_header_footer =
81       job_settings.FindBoolKey(kSettingHeaderFooterEnabled);
82   if (!display_header_footer.has_value())
83     return false;
84
85   settings->set_display_header_footer(display_header_footer.value());
86   if (settings->display_header_footer()) {
87     const std::string* title =
88         job_settings.FindStringKey(kSettingHeaderFooterTitle);
89     const std::string* url =
90         job_settings.FindStringKey(kSettingHeaderFooterURL);
91     if (!title || !url)
92       return false;
93
94     settings->set_title(base::UTF8ToUTF16(*title));
95     settings->set_url(base::UTF8ToUTF16(*url));
96   }
97
98   base::Optional<bool> backgrounds =
99       job_settings.FindBoolKey(kSettingShouldPrintBackgrounds);
100   base::Optional<bool> selection_only =
101       job_settings.FindBoolKey(kSettingShouldPrintSelectionOnly);
102   if (!backgrounds.has_value() || !selection_only.has_value())
103     return false;
104
105   settings->set_should_print_backgrounds(backgrounds.value());
106   settings->set_selection_only(selection_only.value());
107
108   PrintSettings::RequestedMedia requested_media;
109   const base::Value* media_size_value = job_settings.FindKeyOfType(
110       kSettingMediaSize, base::Value::Type::DICTIONARY);
111   if (media_size_value) {
112     base::Optional<int> width_microns =
113         media_size_value->FindIntKey(kSettingMediaSizeWidthMicrons);
114     base::Optional<int> height_microns =
115         media_size_value->FindIntKey(kSettingMediaSizeHeightMicrons);
116     if (width_microns.has_value() && height_microns.has_value()) {
117       requested_media.size_microns =
118           gfx::Size(width_microns.value(), height_microns.value());
119     }
120
121     const std::string* vendor_id =
122         media_size_value->FindStringKey(kSettingMediaSizeVendorId);
123     if (vendor_id && !vendor_id->empty())
124       requested_media.vendor_id = *vendor_id;
125   }
126   settings->set_requested_media(requested_media);
127
128   int margin_type =
129       job_settings.FindIntKey(kSettingMarginsType).value_or(DEFAULT_MARGINS);
130   if (margin_type != DEFAULT_MARGINS && margin_type != NO_MARGINS &&
131       margin_type != CUSTOM_MARGINS && margin_type != PRINTABLE_AREA_MARGINS) {
132     margin_type = DEFAULT_MARGINS;
133   }
134   settings->set_margin_type(static_cast<MarginType>(margin_type));
135
136   if (margin_type == CUSTOM_MARGINS) {
137     PageMargins margins_in_points;
138     margins_in_points.Clear();
139     GetCustomMarginsFromJobSettings(job_settings, &margins_in_points);
140     settings->SetCustomMargins(margins_in_points);
141   }
142
143   PageRanges new_ranges;
144   const base::Value* page_range_array =
145       job_settings.FindKeyOfType(kSettingPageRange, base::Value::Type::LIST);
146   if (page_range_array) {
147     for (const base::Value& value : page_range_array->GetList()) {
148       if (!value.is_dict())
149         continue;
150
151       base::Optional<int> from = value.FindIntKey(kSettingPageRangeFrom);
152       base::Optional<int> to = value.FindIntKey(kSettingPageRangeTo);
153       if (!from.has_value() || !to.has_value())
154         continue;
155
156       // Page numbers are 1-based in the dictionary.
157       // Page numbers are 0-based for the printing context.
158       new_ranges.push_back(PageRange{from.value() - 1, to.value() - 1});
159     }
160   }
161   settings->set_ranges(new_ranges);
162
163   base::Optional<bool> collate = job_settings.FindBoolKey(kSettingCollate);
164   base::Optional<int> copies = job_settings.FindIntKey(kSettingCopies);
165   base::Optional<int> color = job_settings.FindIntKey(kSettingColor);
166   base::Optional<int> duplex_mode = job_settings.FindIntKey(kSettingDuplexMode);
167   base::Optional<bool> landscape = job_settings.FindBoolKey(kSettingLandscape);
168   const std::string* device_name =
169       job_settings.FindStringKey(kSettingDeviceName);
170   base::Optional<int> scale_factor =
171       job_settings.FindIntKey(kSettingScaleFactor);
172   base::Optional<bool> rasterize_pdf =
173       job_settings.FindBoolKey(kSettingRasterizePdf);
174   base::Optional<int> pages_per_sheet =
175       job_settings.FindIntKey(kSettingPagesPerSheet);
176
177   if (!collate.has_value() || !copies.has_value() || !color.has_value() ||
178       !duplex_mode.has_value() || !landscape.has_value() || !device_name ||
179       !scale_factor.has_value() || !rasterize_pdf.has_value() ||
180       !pages_per_sheet.has_value()) {
181     return false;
182   }
183 #if defined(OS_WIN)
184   base::Optional<int> dpi_horizontal =
185       job_settings.FindIntKey(kSettingDpiHorizontal);
186   base::Optional<int> dpi_vertical =
187       job_settings.FindIntKey(kSettingDpiVertical);
188   if (!dpi_horizontal.has_value() || !dpi_vertical.has_value())
189     return false;
190
191   settings->set_dpi_xy(dpi_horizontal.value(), dpi_vertical.value());
192 #endif
193
194   settings->set_collate(collate.value());
195   settings->set_copies(copies.value());
196   settings->SetOrientation(landscape.value());
197   settings->set_device_name(base::UTF8ToUTF16(*device_name));
198   settings->set_duplex_mode(static_cast<DuplexMode>(duplex_mode.value()));
199   settings->set_color(static_cast<ColorModel>(color.value()));
200   settings->set_scale_factor(static_cast<double>(scale_factor.value()) / 100.0);
201   settings->set_rasterize_pdf(rasterize_pdf.value());
202   settings->set_pages_per_sheet(pages_per_sheet.value());
203   base::Optional<bool> is_modifiable =
204       job_settings.FindBoolKey(kSettingPreviewModifiable);
205   if (is_modifiable.has_value()) {
206     settings->set_is_modifiable(is_modifiable.value());
207 #if defined(OS_WIN)
208     settings->set_print_text_with_gdi(is_modifiable.value());
209 #endif
210   }
211   return true;
212 }
213
214 void PrintSettingsToJobSettingsDebug(const PrintSettings& settings,
215                                      base::DictionaryValue* job_settings) {
216   job_settings->SetBoolean(kSettingHeaderFooterEnabled,
217                            settings.display_header_footer());
218   job_settings->SetString(kSettingHeaderFooterTitle, settings.title());
219   job_settings->SetString(kSettingHeaderFooterURL, settings.url());
220   job_settings->SetBoolean(kSettingShouldPrintBackgrounds,
221                            settings.should_print_backgrounds());
222   job_settings->SetBoolean(kSettingShouldPrintSelectionOnly,
223                            settings.selection_only());
224   job_settings->SetInteger(kSettingMarginsType, settings.margin_type());
225   if (!settings.ranges().empty()) {
226     auto page_range_array = std::make_unique<base::ListValue>();
227     for (size_t i = 0; i < settings.ranges().size(); ++i) {
228       auto dict = std::make_unique<base::DictionaryValue>();
229       dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1);
230       dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1);
231       page_range_array->Append(std::move(dict));
232     }
233     job_settings->Set(kSettingPageRange, std::move(page_range_array));
234   }
235
236   job_settings->SetBoolean(kSettingCollate, settings.collate());
237   job_settings->SetInteger(kSettingCopies, settings.copies());
238   job_settings->SetInteger(kSettingColor, settings.color());
239   job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode());
240   job_settings->SetBoolean(kSettingLandscape, settings.landscape());
241   job_settings->SetString(kSettingDeviceName, settings.device_name());
242   job_settings->SetInteger(kSettingPagesPerSheet, settings.pages_per_sheet());
243
244   // Following values are not read form JSON by InitSettings, so do not have
245   // common public constants. So just serialize in "debug" section.
246   auto debug = std::make_unique<base::DictionaryValue>();
247   debug->SetInteger("dpi", settings.dpi());
248   debug->SetInteger("deviceUnitsPerInch", settings.device_units_per_inch());
249   debug->SetBoolean("support_alpha_blend", settings.should_print_backgrounds());
250   debug->SetString("media_vendor_id", settings.requested_media().vendor_id);
251   SetSizeToJobSettings("media_size", settings.requested_media().size_microns,
252                        debug.get());
253   SetMarginsToJobSettings("requested_custom_margins_in_points",
254                           settings.requested_custom_margins_in_points(),
255                           debug.get());
256   const PageSetup& page_setup = settings.page_setup_device_units();
257   SetMarginsToJobSettings("effective_margins", page_setup.effective_margins(),
258                           debug.get());
259   SetSizeToJobSettings("physical_size", page_setup.physical_size(),
260                        debug.get());
261   SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug.get());
262   SetRectToJobSettings("content_area", page_setup.content_area(), debug.get());
263   SetRectToJobSettings("printable_area", page_setup.printable_area(),
264                        debug.get());
265   job_settings->Set("debug", std::move(debug));
266 }
267
268 }  // namespace printing