blob: 1c7afa9a563fde33479d0e27aeab73813660d9c5 [file] [log] [blame]
Avi Drissmandb497b32022-09-15 19:47:281// Copyright 2014 The Chromium Authors
[email protected]c95198b2014-06-12 16:56:552// 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
Daniel Hosseinianfc4d8252021-09-03 21:44:1615#include "base/containers/contains.h"
16#include "base/containers/fixed_flat_set.h"
[email protected]c95198b2014-06-12 16:56:5517#include "base/strings/string_number_conversions.h"
Daniel Hosseinianfc4d8252021-09-03 21:44:1618#include "base/strings/string_piece.h"
[email protected]c95198b2014-06-12 16:56:5519#include "base/strings/utf_string_conversions.h"
20#include "base/time/time.h"
21#include "base/values.h"
Wei Li02720a42017-10-25 22:06:4822#include "build/build_config.h"
Julie Jeongeun Kime454f2602020-04-30 05:20:0723#include "printing/mojom/print.mojom.h"
[email protected]c95198b2014-06-12 16:56:5524#include "printing/print_job_constants.h"
25#include "printing/print_settings.h"
26#include "printing/units.h"
Lei Zhang48502cb82022-07-20 22:48:4627#include "ui/gfx/geometry/rect.h"
28#include "ui/gfx/geometry/size.h"
[email protected]c95198b2014-06-12 16:56:5529
30namespace printing {
31
32namespace {
33
Daniel Hosseinian3553e272021-04-24 00:51:1834// Note: If this code crashes, then the caller has passed in invalid `settings`.
Lei Zhangc8553b42019-08-07 19:13:4635// Fix the caller, instead of trying to avoid the crash here.
Lei Zhang38408e82022-04-08 03:06:0036PageMargins GetCustomMarginsFromJobSettings(const base::Value::Dict& settings) {
Lei Zhangc8553b42019-08-07 19:13:4637 PageMargins margins_in_points;
Lei Zhang38408e82022-04-08 03:06:0038 const base::Value::Dict* custom_margins =
39 settings.FindDict(kSettingMarginsCustom);
40 margins_in_points.top = custom_margins->FindInt(kSettingMarginTop).value();
Lei Zhangc8553b42019-08-07 19:13:4641 margins_in_points.bottom =
Lei Zhang38408e82022-04-08 03:06:0042 custom_margins->FindInt(kSettingMarginBottom).value();
43 margins_in_points.left = custom_margins->FindInt(kSettingMarginLeft).value();
Lei Zhangc8553b42019-08-07 19:13:4644 margins_in_points.right =
Lei Zhang38408e82022-04-08 03:06:0045 custom_margins->FindInt(kSettingMarginRight).value();
Lei Zhangc8553b42019-08-07 19:13:4646 return margins_in_points;
[email protected]c95198b2014-06-12 16:56:5547}
48
49void SetMarginsToJobSettings(const std::string& json_path,
50 const PageMargins& margins,
Lei Zhang4bc852972022-04-12 20:22:1951 base::Value::Dict& job_settings) {
52 base::Value::Dict dict;
53 dict.Set(kSettingMarginTop, margins.top);
54 dict.Set(kSettingMarginBottom, margins.bottom);
55 dict.Set(kSettingMarginLeft, margins.left);
56 dict.Set(kSettingMarginRight, margins.right);
57 job_settings.Set(json_path, std::move(dict));
[email protected]c95198b2014-06-12 16:56:5558}
59
60void SetSizeToJobSettings(const std::string& json_path,
61 const gfx::Size& size,
Lei Zhang4bc852972022-04-12 20:22:1962 base::Value::Dict& job_settings) {
63 base::Value::Dict dict;
64 dict.Set("width", size.width());
65 dict.Set("height", size.height());
66 job_settings.Set(json_path, std::move(dict));
[email protected]c95198b2014-06-12 16:56:5567}
68
69void SetRectToJobSettings(const std::string& json_path,
70 const gfx::Rect& rect,
Lei Zhang4bc852972022-04-12 20:22:1971 base::Value::Dict& job_settings) {
72 base::Value::Dict dict;
73 dict.Set("x", rect.x());
74 dict.Set("y", rect.y());
75 dict.Set("width", rect.width());
76 dict.Set("height", rect.height());
77 job_settings.Set(json_path, std::move(dict));
[email protected]c95198b2014-06-12 16:56:5578}
79
Lei Zhang48502cb82022-07-20 22:48:4680void SetPrintableAreaIfValid(PrintSettings& settings,
81 const gfx::Size& size_microns,
82 const base::Value::Dict& media_size) {
83 absl::optional<int> left_microns =
84 media_size.FindInt(kSettingsImageableAreaLeftMicrons);
85 absl::optional<int> bottom_microns =
86 media_size.FindInt(kSettingsImageableAreaBottomMicrons);
87 absl::optional<int> right_microns =
88 media_size.FindInt(kSettingsImageableAreaRightMicrons);
89 absl::optional<int> top_microns =
90 media_size.FindInt(kSettingsImageableAreaTopMicrons);
91 if (!bottom_microns.has_value() || !left_microns.has_value() ||
92 !right_microns.has_value() || !top_microns.has_value()) {
93 return;
94 }
95
96 // Scale the page size and printable area to device units.
97 float x_scale =
98 static_cast<float>(settings.dpi_horizontal()) / kMicronsPerInch;
99 float y_scale = static_cast<float>(settings.dpi_vertical()) / kMicronsPerInch;
100 gfx::Size page_size = gfx::ScaleToRoundedSize(size_microns, x_scale, y_scale);
101 // Flip the y-axis since the imageable area origin is at the bottom-left,
102 // while the gfx::Rect origin is at the top-left.
103 gfx::Rect printable_area = gfx::ScaleToRoundedRect(
104 {left_microns.value(), size_microns.height() - top_microns.value(),
105 right_microns.value() - left_microns.value(),
106 top_microns.value() - bottom_microns.value()},
107 x_scale, y_scale);
108 // Sanity check that the printable area makes sense.
109 if (printable_area.IsEmpty() ||
110 !gfx::Rect(page_size).Contains(printable_area)) {
111 return;
112 }
113 settings.SetPrinterPrintableArea(page_size, printable_area,
114 /*landscape_needs_flip=*/true);
115}
116
[email protected]c95198b2014-06-12 16:56:55117} // namespace
118
Lei Zhang38408e82022-04-08 03:06:00119PageRanges GetPageRangesFromJobSettings(const base::Value::Dict& job_settings) {
Jesse Schettlera092a99c2019-11-06 15:21:27120 PageRanges page_ranges;
Lei Zhang38408e82022-04-08 03:06:00121 const base::Value::List* page_range_array =
122 job_settings.FindList(kSettingPageRange);
123 if (!page_range_array)
124 return page_ranges;
Jesse Schettlera092a99c2019-11-06 15:21:27125
Lei Zhang38408e82022-04-08 03:06:00126 for (const base::Value& page_range : *page_range_array) {
127 if (!page_range.is_dict())
128 continue;
Jesse Schettlera092a99c2019-11-06 15:21:27129
Lei Zhang38408e82022-04-08 03:06:00130 const auto& dict = page_range.GetDict();
131 absl::optional<int> from = dict.FindInt(kSettingPageRangeFrom);
132 absl::optional<int> to = dict.FindInt(kSettingPageRangeTo);
133 if (!from.has_value() || !to.has_value())
134 continue;
135
136 // Page numbers are 1-based in the dictionary.
137 // Page numbers are 0-based for the printing context.
138 page_ranges.push_back(PageRange{static_cast<uint32_t>(from.value() - 1),
139 static_cast<uint32_t>(to.value() - 1)});
Jesse Schettlera092a99c2019-11-06 15:21:27140 }
141 return page_ranges;
142}
143
Pranav Batra636e2042020-09-03 03:35:05144std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings(
Lei Zhang38408e82022-04-08 03:06:00145 const base::Value::Dict& job_settings) {
Pranav Batra636e2042020-09-03 03:35:05146 auto settings = std::make_unique<PrintSettings>();
Anton Bikineev11eb7ff2021-05-15 18:21:28147 absl::optional<bool> display_header_footer =
Lei Zhang38408e82022-04-08 03:06:00148 job_settings.FindBool(kSettingHeaderFooterEnabled);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57149 if (!display_header_footer.has_value())
Pranav Batra636e2042020-09-03 03:35:05150 return nullptr;
[email protected]c95198b2014-06-12 16:56:55151
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57152 settings->set_display_header_footer(display_header_footer.value());
[email protected]c95198b2014-06-12 16:56:55153 if (settings->display_header_footer()) {
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57154 const std::string* title =
Lei Zhang38408e82022-04-08 03:06:00155 job_settings.FindString(kSettingHeaderFooterTitle);
156 const std::string* url = job_settings.FindString(kSettingHeaderFooterURL);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57157 if (!title || !url)
Pranav Batra636e2042020-09-03 03:35:05158 return nullptr;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57159
160 settings->set_title(base::UTF8ToUTF16(*title));
161 settings->set_url(base::UTF8ToUTF16(*url));
[email protected]c95198b2014-06-12 16:56:55162 }
163
Anton Bikineev11eb7ff2021-05-15 18:21:28164 absl::optional<bool> backgrounds =
Lei Zhang38408e82022-04-08 03:06:00165 job_settings.FindBool(kSettingShouldPrintBackgrounds);
Anton Bikineev11eb7ff2021-05-15 18:21:28166 absl::optional<bool> selection_only =
Lei Zhang38408e82022-04-08 03:06:00167 job_settings.FindBool(kSettingShouldPrintSelectionOnly);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57168 if (!backgrounds.has_value() || !selection_only.has_value())
Pranav Batra636e2042020-09-03 03:35:05169 return nullptr;
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57170
171 settings->set_should_print_backgrounds(backgrounds.value());
172 settings->set_selection_only(selection_only.value());
[email protected]c95198b2014-06-12 16:56:55173
Lei Zhangb1687602022-05-11 22:36:15174 absl::optional<bool> collate = job_settings.FindBool(kSettingCollate);
175 absl::optional<int> copies = job_settings.FindInt(kSettingCopies);
176 absl::optional<int> color = job_settings.FindInt(kSettingColor);
177 absl::optional<int> duplex_mode = job_settings.FindInt(kSettingDuplexMode);
178 absl::optional<bool> landscape = job_settings.FindBool(kSettingLandscape);
Lei Zhang857709b2022-07-19 18:50:28179 const std::string* device_name = job_settings.FindString(kSettingDeviceName);
Lei Zhangb1687602022-05-11 22:36:15180 absl::optional<int> scale_factor = job_settings.FindInt(kSettingScaleFactor);
181 absl::optional<bool> rasterize_pdf =
182 job_settings.FindBool(kSettingRasterizePdf);
183 absl::optional<int> pages_per_sheet =
184 job_settings.FindInt(kSettingPagesPerSheet);
185 if (!collate.has_value() || !copies.has_value() || !color.has_value() ||
Lei Zhang857709b2022-07-19 18:50:28186 !duplex_mode.has_value() || !landscape.has_value() || !device_name ||
Lei Zhangb1687602022-05-11 22:36:15187 !scale_factor.has_value() || !rasterize_pdf.has_value() ||
188 !pages_per_sheet.has_value()) {
189 return nullptr;
190 }
191 settings->set_collate(collate.value());
192 settings->set_copies(copies.value());
193 settings->SetOrientation(landscape.value());
Lei Zhang857709b2022-07-19 18:50:28194 settings->set_device_name(base::UTF8ToUTF16(*device_name));
Lei Zhangb1687602022-05-11 22:36:15195 settings->set_duplex_mode(
196 static_cast<mojom::DuplexMode>(duplex_mode.value()));
197 settings->set_color(static_cast<mojom::ColorModel>(color.value()));
198 settings->set_scale_factor(static_cast<double>(scale_factor.value()) / 100.0);
199 settings->set_rasterize_pdf(rasterize_pdf.value());
200 settings->set_pages_per_sheet(pages_per_sheet.value());
201
202 absl::optional<int> dpi_horizontal =
203 job_settings.FindInt(kSettingDpiHorizontal);
204 absl::optional<int> dpi_vertical = job_settings.FindInt(kSettingDpiVertical);
205 if (!dpi_horizontal.has_value() || !dpi_vertical.has_value())
206 return nullptr;
207
208 settings->set_dpi_xy(dpi_horizontal.value(), dpi_vertical.value());
209
210 absl::optional<int> rasterize_pdf_dpi =
211 job_settings.FindInt(kSettingRasterizePdfDpi);
212 if (rasterize_pdf_dpi.has_value())
213 settings->set_rasterize_pdf_dpi(rasterize_pdf_dpi.value());
214
[email protected]c95198b2014-06-12 16:56:55215 PrintSettings::RequestedMedia requested_media;
Lei Zhang38408e82022-04-08 03:06:00216 const base::Value::Dict* media_size_value =
217 job_settings.FindDict(kSettingMediaSize);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57218 if (media_size_value) {
Anton Bikineev11eb7ff2021-05-15 18:21:28219 absl::optional<int> width_microns =
Lei Zhang38408e82022-04-08 03:06:00220 media_size_value->FindInt(kSettingMediaSizeWidthMicrons);
Anton Bikineev11eb7ff2021-05-15 18:21:28221 absl::optional<int> height_microns =
Lei Zhang38408e82022-04-08 03:06:00222 media_size_value->FindInt(kSettingMediaSizeHeightMicrons);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57223 if (width_microns.has_value() && height_microns.has_value()) {
224 requested_media.size_microns =
225 gfx::Size(width_microns.value(), height_microns.value());
Lei Zhang48502cb82022-07-20 22:48:46226 SetPrintableAreaIfValid(*settings, requested_media.size_microns,
227 *media_size_value);
[email protected]c95198b2014-06-12 16:56:55228 }
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57229
230 const std::string* vendor_id =
Lei Zhang38408e82022-04-08 03:06:00231 media_size_value->FindString(kSettingMediaSizeVendorId);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57232 if (vendor_id && !vendor_id->empty())
233 requested_media.vendor_id = *vendor_id;
[email protected]c95198b2014-06-12 16:56:55234 }
235 settings->set_requested_media(requested_media);
236
Julie Jeongeun Kimcb00d1ab2020-08-14 07:43:32237 mojom::MarginType margin_type = static_cast<mojom::MarginType>(
Lei Zhang38408e82022-04-08 03:06:00238 job_settings.FindInt(kSettingMarginsType)
Julie Jeongeun Kimcb00d1ab2020-08-14 07:43:32239 .value_or(static_cast<int>(mojom::MarginType::kDefaultMargins)));
240 if (margin_type != mojom::MarginType::kDefaultMargins &&
241 margin_type != mojom::MarginType::kNoMargins &&
242 margin_type != mojom::MarginType::kCustomMargins &&
243 margin_type != mojom::MarginType::kPrintableAreaMargins) {
244 margin_type = mojom::MarginType::kDefaultMargins;
[email protected]c95198b2014-06-12 16:56:55245 }
Julie Jeongeun Kimcb00d1ab2020-08-14 07:43:32246 settings->set_margin_type(margin_type);
[email protected]c95198b2014-06-12 16:56:55247
Julie Jeongeun Kimcb00d1ab2020-08-14 07:43:32248 if (margin_type == mojom::MarginType::kCustomMargins)
Lei Zhangc8553b42019-08-07 19:13:46249 settings->SetCustomMargins(GetCustomMarginsFromJobSettings(job_settings));
[email protected]c95198b2014-06-12 16:56:55250
Jesse Schettlera092a99c2019-11-06 15:21:27251 settings->set_ranges(GetPageRangesFromJobSettings(job_settings));
[email protected]c95198b2014-06-12 16:56:55252
Anton Bikineev11eb7ff2021-05-15 18:21:28253 absl::optional<bool> is_modifiable =
Lei Zhang38408e82022-04-08 03:06:00254 job_settings.FindBool(kSettingPreviewModifiable);
Vladislav Kuzkokov490ab0c2019-01-16 11:21:57255 if (is_modifiable.has_value()) {
256 settings->set_is_modifiable(is_modifiable.value());
Wei Li02720a42017-10-25 22:06:48257 }
Vladislav Kuzkokov48b15002019-01-30 17:13:35258
Xiaohan Wange3d00dd62022-01-08 02:33:28259#if BUILDFLAG(IS_CHROMEOS) || (BUILDFLAG(IS_LINUX) && defined(USE_CUPS))
Lei Zhang38408e82022-04-08 03:06:00260 const base::Value::Dict* advanced_settings =
261 job_settings.FindDict(kSettingAdvancedSettings);
Daniel Hosseinianc3db7f4c2020-06-25 02:09:52262 if (advanced_settings) {
Lei Zhang38408e82022-04-08 03:06:00263 for (const auto item : *advanced_settings) {
Daniel Hosseinianfc4d8252021-09-03 21:44:16264 static constexpr auto kNonJobAttributes =
265 base::MakeFixedFlatSet<base::StringPiece>(
266 {"printer-info", "printer-make-and-model", "system_driverinfo"});
267 if (!base::Contains(kNonJobAttributes, item.first))
268 settings->advanced_settings().emplace(item.first, item.second.Clone());
269 }
Daniel Hosseinianc3db7f4c2020-06-25 02:09:52270 }
Xiaohan Wange3d00dd62022-01-08 02:33:28271#endif // BUILDFLAG(IS_CHROMEOS) || (BUILDFLAG(IS_LINUX) && defined(USE_CUPS))
Daniel Hosseinianc3db7f4c2020-06-25 02:09:52272
Xiaohan Wange3d00dd62022-01-08 02:33:28273#if BUILDFLAG(IS_CHROMEOS)
Vladislav Kuzkokov48b15002019-01-30 17:13:35274 bool send_user_info =
Lei Zhang38408e82022-04-08 03:06:00275 job_settings.FindBool(kSettingSendUserInfo).value_or(false);
Vladislav Kuzkokov48b15002019-01-30 17:13:35276 settings->set_send_user_info(send_user_info);
277 if (send_user_info) {
Lei Zhang38408e82022-04-08 03:06:00278 const std::string* username = job_settings.FindString(kSettingUsername);
Vladislav Kuzkokov48b15002019-01-30 17:13:35279 if (username)
280 settings->set_username(*username);
281 }
Nikita Podguzovc1bf3f82019-03-19 15:23:23282
Piotr Pawliczeka7b35342022-11-01 18:18:50283 const std::string* oauth_token =
284 job_settings.FindString(kSettingChromeOSAccessOAuthToken);
285 if (oauth_token) {
286 settings->set_oauth_token(*oauth_token);
287 }
288
Lei Zhang38408e82022-04-08 03:06:00289 const std::string* pin_value = job_settings.FindString(kSettingPinValue);
Nikita Podguzovc1bf3f82019-03-19 15:23:23290 if (pin_value)
291 settings->set_pin_value(*pin_value);
Xiaohan Wange3d00dd62022-01-08 02:33:28292#endif // BUILDFLAG(IS_CHROMEOS)
Vladislav Kuzkokov48b15002019-01-30 17:13:35293
Pranav Batra636e2042020-09-03 03:35:05294 return settings;
[email protected]c95198b2014-06-12 16:56:55295}
296
Lei Zhang4bc852972022-04-12 20:22:19297base::Value::Dict PrintSettingsToJobSettingsDebug(
298 const PrintSettings& settings) {
299 base::Value::Dict job_settings;
Alan Screen3c25f8e2021-08-04 17:41:51300
Lei Zhang4bc852972022-04-12 20:22:19301 job_settings.Set(kSettingHeaderFooterEnabled,
302 settings.display_header_footer());
303 job_settings.Set(kSettingHeaderFooterTitle, settings.title());
304 job_settings.Set(kSettingHeaderFooterURL, settings.url());
305 job_settings.Set(kSettingShouldPrintBackgrounds,
306 settings.should_print_backgrounds());
307 job_settings.Set(kSettingShouldPrintSelectionOnly, settings.selection_only());
308 job_settings.Set(kSettingMarginsType,
309 static_cast<int>(settings.margin_type()));
[email protected]c95198b2014-06-12 16:56:55310 if (!settings.ranges().empty()) {
Lei Zhang4bc852972022-04-12 20:22:19311 base::Value::List page_range_array;
Alan Screen3c25f8e2021-08-04 17:41:51312 for (const auto& range : settings.ranges()) {
Lei Zhang4bc852972022-04-12 20:22:19313 base::Value::Dict dict;
314 dict.Set(kSettingPageRangeFrom, static_cast<int>(range.from + 1));
315 dict.Set(kSettingPageRangeTo, static_cast<int>(range.to + 1));
Song Fangzhen6ff811d2021-06-29 08:35:43316 page_range_array.Append(std::move(dict));
[email protected]c95198b2014-06-12 16:56:55317 }
Lei Zhang4bc852972022-04-12 20:22:19318 job_settings.Set(kSettingPageRange, std::move(page_range_array));
[email protected]c95198b2014-06-12 16:56:55319 }
320
Lei Zhang4bc852972022-04-12 20:22:19321 job_settings.Set(kSettingCollate, settings.collate());
322 job_settings.Set(kSettingCopies, settings.copies());
323 job_settings.Set(kSettingColor, static_cast<int>(settings.color()));
324 job_settings.Set(kSettingDuplexMode,
325 static_cast<int>(settings.duplex_mode()));
326 job_settings.Set(kSettingLandscape, settings.landscape());
327 job_settings.Set(kSettingDeviceName, settings.device_name());
328 job_settings.Set(kSettingDpiHorizontal, settings.dpi_horizontal());
329 job_settings.Set(kSettingDpiVertical, settings.dpi_vertical());
330 job_settings.Set(kSettingScaleFactor,
331 static_cast<int>((settings.scale_factor() * 100.0) + 0.5));
332 job_settings.Set(kSettingRasterizePdf, settings.rasterize_pdf());
333 job_settings.Set(kSettingPagesPerSheet, settings.pages_per_sheet());
[email protected]c95198b2014-06-12 16:56:55334
335 // Following values are not read form JSON by InitSettings, so do not have
336 // common public constants. So just serialize in "debug" section.
Lei Zhang4bc852972022-04-12 20:22:19337 base::Value::Dict debug;
338 debug.Set("dpi", settings.dpi());
339 debug.Set("deviceUnitsPerInch", settings.device_units_per_inch());
340 debug.Set("support_alpha_blend", settings.should_print_backgrounds());
341 debug.Set("media_vendor_id", settings.requested_media().vendor_id);
jdoerriecb205a52017-06-08 16:16:44342 SetSizeToJobSettings("media_size", settings.requested_media().size_microns,
Alan Screen3c25f8e2021-08-04 17:41:51343 debug);
[email protected]c95198b2014-06-12 16:56:55344 SetMarginsToJobSettings("requested_custom_margins_in_points",
Alan Screen3c25f8e2021-08-04 17:41:51345 settings.requested_custom_margins_in_points(), debug);
[email protected]c95198b2014-06-12 16:56:55346 const PageSetup& page_setup = settings.page_setup_device_units();
jdoerriecb205a52017-06-08 16:16:44347 SetMarginsToJobSettings("effective_margins", page_setup.effective_margins(),
Alan Screen3c25f8e2021-08-04 17:41:51348 debug);
349 SetSizeToJobSettings("physical_size", page_setup.physical_size(), debug);
350 SetRectToJobSettings("overlay_area", page_setup.overlay_area(), debug);
351 SetRectToJobSettings("content_area", page_setup.content_area(), debug);
352 SetRectToJobSettings("printable_area", page_setup.printable_area(), debug);
Lei Zhang4bc852972022-04-12 20:22:19353 job_settings.Set("debug", std::move(debug));
Alan Screen3c25f8e2021-08-04 17:41:51354
355 return job_settings;
[email protected]c95198b2014-06-12 16:56:55356}
357
358} // namespace printing