1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "printing/printing_context.h"
9 #include "base/check.h"
10 #include "base/notreached.h"
11 #include "build/build_config.h"
12 #include "printing/buildflags/buildflags.h"
13 #include "printing/mojom/print.mojom.h"
14 #include "printing/page_setup.h"
15 #include "printing/print_job_constants.h"
16 #include "printing/print_settings_conversion.h"
17 #include "printing/printing_context_factory_for_test.h"
18 #include "printing/units.h"
20 #if BUILDFLAG(ENABLE_OOP_PRINTING)
21 #include "printing/printing_features.h"
28 PrintingContextFactoryForTest* g_printing_context_factory_for_test = nullptr;
32 PrintingContext::PrintingContext(Delegate* delegate)
33 : settings_(std::make_unique<PrintSettings>()),
36 abort_printing_(false) {
40 PrintingContext::~PrintingContext() = default;
43 std::unique_ptr<PrintingContext> PrintingContext::Create(
45 bool skip_system_calls) {
46 return g_printing_context_factory_for_test
47 ? g_printing_context_factory_for_test->CreatePrintingContext(
48 delegate, skip_system_calls)
49 : PrintingContext::CreateImpl(delegate, skip_system_calls);
53 void PrintingContext::SetPrintingContextFactoryForTest(
54 PrintingContextFactoryForTest* factory) {
55 g_printing_context_factory_for_test = factory;
58 void PrintingContext::set_margin_type(mojom::MarginType type) {
59 DCHECK(type != mojom::MarginType::kCustomMargins);
60 settings_->set_margin_type(type);
63 void PrintingContext::set_is_modifiable(bool is_modifiable) {
64 settings_->set_is_modifiable(is_modifiable);
67 const PrintSettings& PrintingContext::settings() const {
68 DCHECK(!in_print_job_);
72 void PrintingContext::ResetSettings() {
77 in_print_job_ = false;
78 abort_printing_ = false;
81 std::unique_ptr<PrintSettings> PrintingContext::TakeAndResetSettings() {
82 std::unique_ptr<PrintSettings> result = std::move(settings_);
83 settings_ = std::make_unique<PrintSettings>();
87 mojom::ResultCode PrintingContext::OnError() {
88 mojom::ResultCode result = abort_printing_ ? mojom::ResultCode::kCanceled
89 : mojom::ResultCode::kFailed;
94 void PrintingContext::SetDefaultPrintableAreaForVirtualPrinters() {
95 gfx::Size paper_size(GetPdfPaperSizeDeviceUnits());
96 if (!settings_->requested_media().size_microns.IsEmpty()) {
97 float device_microns_per_device_unit = static_cast<float>(kMicronsPerInch) /
98 settings_->device_units_per_inch();
99 paper_size = gfx::Size(settings_->requested_media().size_microns.width() /
100 device_microns_per_device_unit,
101 settings_->requested_media().size_microns.height() /
102 device_microns_per_device_unit);
104 gfx::Rect paper_rect(0, 0, paper_size.width(), paper_size.height());
105 settings_->SetPrinterPrintableArea(paper_size, paper_rect,
106 /*landscape_needs_flip=*/true);
109 void PrintingContext::UsePdfSettings() {
110 base::Value::Dict pdf_settings;
111 pdf_settings.Set(kSettingHeaderFooterEnabled, false);
112 pdf_settings.Set(kSettingShouldPrintBackgrounds, false);
113 pdf_settings.Set(kSettingShouldPrintSelectionOnly, false);
114 pdf_settings.Set(kSettingMarginsType,
115 static_cast<int>(mojom::MarginType::kNoMargins));
116 pdf_settings.Set(kSettingCollate, true);
117 pdf_settings.Set(kSettingCopies, 1);
118 pdf_settings.Set(kSettingColor, static_cast<int>(mojom::ColorModel::kColor));
119 // DPI value should match GetPdfCapabilities().
120 pdf_settings.Set(kSettingDpiHorizontal, kDefaultPdfDpi);
121 pdf_settings.Set(kSettingDpiVertical, kDefaultPdfDpi);
122 pdf_settings.Set(kSettingDuplexMode,
123 static_cast<int>(printing::mojom::DuplexMode::kSimplex));
124 pdf_settings.Set(kSettingLandscape, false);
125 pdf_settings.Set(kSettingDeviceName, "");
126 pdf_settings.Set(kSettingPrinterType,
127 static_cast<int>(mojom::PrinterType::kPdf));
128 pdf_settings.Set(kSettingScaleFactor, 100);
129 pdf_settings.Set(kSettingRasterizePdf, false);
130 pdf_settings.Set(kSettingPagesPerSheet, 1);
131 mojom::ResultCode result = UpdatePrintSettings(std::move(pdf_settings));
132 // TODO(thestig): Downgrade these to DCHECKs after shipping these CHECKs to
133 // production without any failures.
134 CHECK_EQ(result, mojom::ResultCode::kSuccess);
135 // UsePdfSettings() should never fail and the returned DPI should always be a
136 // well-known value that is safe to use as a divisor.
137 #if BUILDFLAG(IS_MAC)
138 CHECK_EQ(settings_->device_units_per_inch(), kPointsPerInch);
140 CHECK_EQ(settings_->device_units_per_inch(), kDefaultPdfDpi);
144 mojom::ResultCode PrintingContext::UpdatePrintSettings(
145 base::Value::Dict job_settings) {
148 std::unique_ptr<PrintSettings> settings =
149 PrintSettingsFromJobSettings(job_settings);
154 settings_ = std::move(settings);
157 mojom::PrinterType printer_type = static_cast<mojom::PrinterType>(
158 job_settings.FindInt(kSettingPrinterType).value());
159 if (printer_type == mojom::PrinterType::kPrivetDeprecated ||
160 printer_type == mojom::PrinterType::kCloudDeprecated) {
165 bool open_in_external_preview =
166 job_settings.contains(kSettingOpenPDFInPreview);
168 if (!open_in_external_preview &&
169 (printer_type == mojom::PrinterType::kPdf ||
170 printer_type == mojom::PrinterType::kExtension)) {
171 if (settings_->page_setup_device_units().printable_area().IsEmpty())
172 SetDefaultPrintableAreaForVirtualPrinters();
173 return mojom::ResultCode::kSuccess;
176 // The `open_in_external_preview` case does not care about the printable area.
177 // Local printers set their printable area within UpdatePrinterSettings().
178 DCHECK(open_in_external_preview ||
179 printer_type == mojom::PrinterType::kLocal);
181 PrinterSettings printer_settings {
182 #if BUILDFLAG(IS_MAC)
183 .external_preview = open_in_external_preview,
185 .show_system_dialog =
186 job_settings.FindBool(kSettingShowSystemDialog).value_or(false),
187 #if BUILDFLAG(IS_WIN)
188 .page_count = job_settings.FindInt(kSettingPreviewPageCount).value_or(0)
191 return UpdatePrinterSettings(printer_settings);
194 #if BUILDFLAG(IS_CHROMEOS)
195 mojom::ResultCode PrintingContext::UpdatePrintSettingsFromPOD(
196 std::unique_ptr<PrintSettings> job_settings) {
198 settings_ = std::move(job_settings);
200 return UpdatePrinterSettings({.show_system_dialog = false});
204 void PrintingContext::SetPrintSettings(const PrintSettings& settings) {
205 *settings_ = settings;
208 } // namespace printing