blob: e01d195261a4c993dddb77d7a355481bf02067cc [file] [log] [blame]
[email protected]c95198b2014-06-12 16:56:551// 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
avi126e93c2015-12-21 21:48:167#include <stddef.h>
8
[email protected]c95198b2014-06-12 16:56:559#include <algorithm>
10#include <cmath>
dcheng031a8f82016-09-08 21:04:3311#include <memory>
[email protected]c95198b2014-06-12 16:56:5512#include <string>
dcheng031a8f82016-09-08 21:04:3313#include <utility>
[email protected]c95198b2014-06-12 16:56:5514
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"
Wei Li02720a42017-10-25 22:06:4819#include "build/build_config.h"
[email protected]c95198b2014-06-12 16:56:5520#include "printing/print_job_constants.h"
21#include "printing/print_settings.h"
22#include "printing/units.h"
23
24namespace printing {
25
26namespace {
27
Lei Zhangc8553b42019-08-07 19:13:4628// Note: If this code crashes, then the caller has passed in invalid |settings|.
29// Fix the caller, instead of trying to avoid the crash here.
30PageMargins GetCustomMarginsFromJobSettings(const base::Value& settings) {
31 PageMargins margins_in_points;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:5732 const base::Value* custom_margins = settings.FindKey(kSettingMarginsCustom);
Lei Zhangc8553b42019-08-07 19:13:4633 margins_in_points.top = custom_margins->FindIntKey(kSettingMarginTop).value();
34 margins_in_points.bottom =
35 custom_margins->FindIntKey(kSettingMarginBottom).value();
36 margins_in_points.left =
37 custom_margins->FindIntKey(kSettingMarginLeft).value();
38 margins_in_points.right =
39 custom_margins->FindIntKey(kSettingMarginRight).value();
40 return margins_in_points;
[email protected]c95198b2014-06-12 16:56:5541}
42
43void SetMarginsToJobSettings(const std::string& json_path,
44 const PageMargins& margins,
45 base::DictionaryValue* job_settings) {
Gyuyoung Kimb480aba2018-01-27 07:00:0446 auto dict = std::make_unique<base::DictionaryValue>();
[email protected]c95198b2014-06-12 16:56:5547 dict->SetInteger(kSettingMarginTop, margins.top);
48 dict->SetInteger(kSettingMarginBottom, margins.bottom);
49 dict->SetInteger(kSettingMarginLeft, margins.left);
50 dict->SetInteger(kSettingMarginRight, margins.right);
jdoerriecb205a52017-06-08 16:16:4451 job_settings->Set(json_path, std::move(dict));
[email protected]c95198b2014-06-12 16:56:5552}
53
54void SetSizeToJobSettings(const std::string& json_path,
55 const gfx::Size& size,
56 base::DictionaryValue* job_settings) {
Gyuyoung Kimb480aba2018-01-27 07:00:0457 auto dict = std::make_unique<base::DictionaryValue>();
[email protected]c95198b2014-06-12 16:56:5558 dict->SetInteger("width", size.width());
59 dict->SetInteger("height", size.height());
jdoerriecb205a52017-06-08 16:16:4460 job_settings->Set(json_path, std::move(dict));
[email protected]c95198b2014-06-12 16:56:5561}
62
63void SetRectToJobSettings(const std::string& json_path,
64 const gfx::Rect& rect,
65 base::DictionaryValue* job_settings) {
Gyuyoung Kimb480aba2018-01-27 07:00:0466 auto dict = std::make_unique<base::DictionaryValue>();
[email protected]c95198b2014-06-12 16:56:5567 dict->SetInteger("x", rect.x());
68 dict->SetInteger("y", rect.y());
69 dict->SetInteger("width", rect.width());
70 dict->SetInteger("height", rect.height());
jdoerriecb205a52017-06-08 16:16:4471 job_settings->Set(json_path, std::move(dict));
[email protected]c95198b2014-06-12 16:56:5572}
73
74} // namespace
75
Jesse Schettlera092a99c2019-11-06 15:21:2776PageRanges GetPageRangesFromJobSettings(const base::Value& job_settings) {
77 PageRanges page_ranges;
78 const base::Value* page_range_array =
79 job_settings.FindListKey(kSettingPageRange);
80 if (page_range_array) {
81 for (const base::Value& page_range : page_range_array->GetList()) {
82 if (!page_range.is_dict())
83 continue;
84
85 base::Optional<int> from = page_range.FindIntKey(kSettingPageRangeFrom);
86 base::Optional<int> to = page_range.FindIntKey(kSettingPageRangeTo);
87 if (!from.has_value() || !to.has_value())
88 continue;
89
90 // Page numbers are 1-based in the dictionary.
91 // Page numbers are 0-based for the printing context.
92 page_ranges.push_back(PageRange{from.value() - 1, to.value() - 1});
93 }
94 }
95 return page_ranges;
96}
97
Vladislav Kuzkokov490ab0c2019-01-16 11:21:5798bool PrintSettingsFromJobSettings(const base::Value& job_settings,
[email protected]c95198b2014-06-12 16:56:5599 PrintSettings* settings) {
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57100 base::Optional<bool> display_header_footer =
101 job_settings.FindBoolKey(kSettingHeaderFooterEnabled);
102 if (!display_header_footer.has_value())
[email protected]c95198b2014-06-12 16:56:55103 return false;
[email protected]c95198b2014-06-12 16:56:55104
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57105 settings->set_display_header_footer(display_header_footer.value());
[email protected]c95198b2014-06-12 16:56:55106 if (settings->display_header_footer()) {
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57107 const std::string* title =
108 job_settings.FindStringKey(kSettingHeaderFooterTitle);
109 const std::string* url =
110 job_settings.FindStringKey(kSettingHeaderFooterURL);
111 if (!title || !url)
[email protected]c95198b2014-06-12 16:56:55112 return false;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57113
114 settings->set_title(base::UTF8ToUTF16(*title));
115 settings->set_url(base::UTF8ToUTF16(*url));
[email protected]c95198b2014-06-12 16:56:55116 }
117
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57118 base::Optional<bool> backgrounds =
119 job_settings.FindBoolKey(kSettingShouldPrintBackgrounds);
120 base::Optional<bool> selection_only =
121 job_settings.FindBoolKey(kSettingShouldPrintSelectionOnly);
122 if (!backgrounds.has_value() || !selection_only.has_value())
[email protected]c95198b2014-06-12 16:56:55123 return false;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57124
125 settings->set_should_print_backgrounds(backgrounds.value());
126 settings->set_selection_only(selection_only.value());
[email protected]c95198b2014-06-12 16:56:55127
128 PrintSettings::RequestedMedia requested_media;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57129 const base::Value* media_size_value = job_settings.FindKeyOfType(
130 kSettingMediaSize, base::Value::Type::DICTIONARY);
131 if (media_size_value) {
132 base::Optional<int> width_microns =
133 media_size_value->FindIntKey(kSettingMediaSizeWidthMicrons);
134 base::Optional<int> height_microns =
135 media_size_value->FindIntKey(kSettingMediaSizeHeightMicrons);
136 if (width_microns.has_value() && height_microns.has_value()) {
137 requested_media.size_microns =
138 gfx::Size(width_microns.value(), height_microns.value());
[email protected]c95198b2014-06-12 16:56:55139 }
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57140
141 const std::string* vendor_id =
142 media_size_value->FindStringKey(kSettingMediaSizeVendorId);
143 if (vendor_id && !vendor_id->empty())
144 requested_media.vendor_id = *vendor_id;
[email protected]c95198b2014-06-12 16:56:55145 }
146 settings->set_requested_media(requested_media);
147
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57148 int margin_type =
149 job_settings.FindIntKey(kSettingMarginsType).value_or(DEFAULT_MARGINS);
150 if (margin_type != DEFAULT_MARGINS && margin_type != NO_MARGINS &&
151 margin_type != CUSTOM_MARGINS && margin_type != PRINTABLE_AREA_MARGINS) {
[email protected]c95198b2014-06-12 16:56:55152 margin_type = DEFAULT_MARGINS;
153 }
154 settings->set_margin_type(static_cast<MarginType>(margin_type));
155
Lei Zhangc8553b42019-08-07 19:13:46156 if (margin_type == CUSTOM_MARGINS)
157 settings->SetCustomMargins(GetCustomMarginsFromJobSettings(job_settings));
[email protected]c95198b2014-06-12 16:56:55158
Jesse Schettlera092a99c2019-11-06 15:21:27159 settings->set_ranges(GetPageRangesFromJobSettings(job_settings));
[email protected]c95198b2014-06-12 16:56:55160
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57161 base::Optional<bool> collate = job_settings.FindBoolKey(kSettingCollate);
162 base::Optional<int> copies = job_settings.FindIntKey(kSettingCopies);
163 base::Optional<int> color = job_settings.FindIntKey(kSettingColor);
164 base::Optional<int> duplex_mode = job_settings.FindIntKey(kSettingDuplexMode);
165 base::Optional<bool> landscape = job_settings.FindBoolKey(kSettingLandscape);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57166 base::Optional<int> scale_factor =
167 job_settings.FindIntKey(kSettingScaleFactor);
168 base::Optional<bool> rasterize_pdf =
169 job_settings.FindBoolKey(kSettingRasterizePdf);
170 base::Optional<int> pages_per_sheet =
171 job_settings.FindIntKey(kSettingPagesPerSheet);
[email protected]c95198b2014-06-12 16:56:55172
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57173 if (!collate.has_value() || !copies.has_value() || !color.has_value() ||
Lei Zhangdfe53f92019-10-11 05:41:07174 !duplex_mode.has_value() || !landscape.has_value() ||
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57175 !scale_factor.has_value() || !rasterize_pdf.has_value() ||
176 !pages_per_sheet.has_value()) {
[email protected]c95198b2014-06-12 16:56:55177 return false;
178 }
rbpotter116c2e12017-04-04 19:21:28179#if defined(OS_WIN)
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57180 base::Optional<int> dpi_horizontal =
181 job_settings.FindIntKey(kSettingDpiHorizontal);
182 base::Optional<int> dpi_vertical =
183 job_settings.FindIntKey(kSettingDpiVertical);
184 if (!dpi_horizontal.has_value() || !dpi_vertical.has_value())
rbpotter116c2e12017-04-04 19:21:28185 return false;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57186
187 settings->set_dpi_xy(dpi_horizontal.value(), dpi_vertical.value());
rbpotter116c2e12017-04-04 19:21:28188#endif
[email protected]c95198b2014-06-12 16:56:55189
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57190 settings->set_collate(collate.value());
191 settings->set_copies(copies.value());
192 settings->SetOrientation(landscape.value());
Lei Zhangdfe53f92019-10-11 05:41:07193 settings->set_device_name(
194 base::UTF8ToUTF16(*job_settings.FindStringKey(kSettingDeviceName)));
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57195 settings->set_duplex_mode(static_cast<DuplexMode>(duplex_mode.value()));
196 settings->set_color(static_cast<ColorModel>(color.value()));
197 settings->set_scale_factor(static_cast<double>(scale_factor.value()) / 100.0);
198 settings->set_rasterize_pdf(rasterize_pdf.value());
199 settings->set_pages_per_sheet(pages_per_sheet.value());
200 base::Optional<bool> is_modifiable =
201 job_settings.FindBoolKey(kSettingPreviewModifiable);
202 if (is_modifiable.has_value()) {
203 settings->set_is_modifiable(is_modifiable.value());
thestige85e6b62016-08-25 00:00:06204#if defined(OS_WIN)
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57205 settings->set_print_text_with_gdi(is_modifiable.value());
thestige85e6b62016-08-25 00:00:06206#endif
Wei Li02720a42017-10-25 22:06:48207 }
Vladislav Kuzkokov48b15002019-01-30 17:13:35208
209#if defined(OS_CHROMEOS)
210 bool send_user_info =
211 job_settings.FindBoolKey(kSettingSendUserInfo).value_or(false);
212 settings->set_send_user_info(send_user_info);
213 if (send_user_info) {
214 const std::string* username = job_settings.FindStringKey(kSettingUsername);
215 if (username)
216 settings->set_username(*username);
217 }
Nikita Podguzovc1bf3f82019-03-19 15:23:23218
219 const std::string* pin_value = job_settings.FindStringKey(kSettingPinValue);
220 if (pin_value)
221 settings->set_pin_value(*pin_value);
Vladislav Kuzkokovd4e4ff32019-09-13 11:55:56222
223 const base::Value* advanced_settings =
224 job_settings.FindDictKey(kSettingAdvancedSettings);
225 if (advanced_settings) {
226 for (const auto& item : advanced_settings->DictItems())
227 settings->advanced_settings().emplace(item.first, item.second.Clone());
228 }
Vladislav Kuzkokov48b15002019-01-30 17:13:35229#endif
230
[email protected]c95198b2014-06-12 16:56:55231 return true;
232}
233
234void PrintSettingsToJobSettingsDebug(const PrintSettings& settings,
235 base::DictionaryValue* job_settings) {
236 job_settings->SetBoolean(kSettingHeaderFooterEnabled,
237 settings.display_header_footer());
238 job_settings->SetString(kSettingHeaderFooterTitle, settings.title());
239 job_settings->SetString(kSettingHeaderFooterURL, settings.url());
240 job_settings->SetBoolean(kSettingShouldPrintBackgrounds,
241 settings.should_print_backgrounds());
242 job_settings->SetBoolean(kSettingShouldPrintSelectionOnly,
243 settings.selection_only());
244 job_settings->SetInteger(kSettingMarginsType, settings.margin_type());
245 if (!settings.ranges().empty()) {
Gyuyoung Kimb480aba2018-01-27 07:00:04246 auto page_range_array = std::make_unique<base::ListValue>();
[email protected]c95198b2014-06-12 16:56:55247 for (size_t i = 0; i < settings.ranges().size(); ++i) {
Gyuyoung Kimb480aba2018-01-27 07:00:04248 auto dict = std::make_unique<base::DictionaryValue>();
[email protected]c95198b2014-06-12 16:56:55249 dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1);
250 dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1);
dcheng031a8f82016-09-08 21:04:33251 page_range_array->Append(std::move(dict));
[email protected]c95198b2014-06-12 16:56:55252 }
jdoerriecb205a52017-06-08 16:16:44253 job_settings->Set(kSettingPageRange, std::move(page_range_array));
[email protected]c95198b2014-06-12 16:56:55254 }
255
256 job_settings->SetBoolean(kSettingCollate, settings.collate());
257 job_settings->SetInteger(kSettingCopies, settings.copies());
258 job_settings->SetInteger(kSettingColor, settings.color());
259 job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode());
260 job_settings->SetBoolean(kSettingLandscape, settings.landscape());
261 job_settings->SetString(kSettingDeviceName, settings.device_name());
xlou6bd7c2d2018-07-10 01:35:40262 job_settings->SetInteger(kSettingPagesPerSheet, settings.pages_per_sheet());
[email protected]c95198b2014-06-12 16:56:55263
264 // Following values are not read form JSON by InitSettings, so do not have
265 // common public constants. So just serialize in "debug" section.
Gyuyoung Kimb480aba2018-01-27 07:00:04266 auto debug = std::make_unique<base::DictionaryValue>();
[email protected]c95198b2014-06-12 16:56:55267 debug->SetInteger("dpi", settings.dpi());
268 debug->SetInteger("deviceUnitsPerInch", settings.device_units_per_inch());
269 debug->SetBoolean("support_alpha_blend", settings.should_print_backgrounds());
rbpotterde174102017-04-03 20:47:03270 debug->SetString("media_vendor_id", settings.requested_media().vendor_id);
jdoerriecb205a52017-06-08 16:16:44271 SetSizeToJobSettings("media_size", settings.requested_media().size_microns,
272 debug.get());
[email protected]c95198b2014-06-12 16:56:55273 SetMarginsToJobSettings("requested_custom_margins_in_points",
274 settings.requested_custom_margins_in_points(),
jdoerriecb205a52017-06-08 16:16:44275 debug.get());
[email protected]c95198b2014-06-12 16:56:55276 const PageSetup& page_setup = settings.page_setup_device_units();
jdoerriecb205a52017-06-08 16:16:44277 SetMarginsToJobSettings("effective_margins", page_setup.effective_margins(),
278 debug.get());
279 SetSizeToJobSettings("physical_size", page_setup.physical_size(),
280 debug.get());
281 SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug.get());
282 SetRectToJobSettings("content_area", page_setup.content_area(), debug.get());
283 SetRectToJobSettings("printable_area", page_setup.printable_area(),
284 debug.get());
285 job_settings->Set("debug", std::move(debug));
[email protected]c95198b2014-06-12 16:56:55286}
287
288} // namespace printing