1 // Copyright (c) 2011 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/printing_context.h"
6 
7 #include <utility>
8 
9 #include "base/check.h"
10 #include "base/notreached.h"
11 #include "build/chromeos_buildflags.h"
12 #include "printing/page_setup.h"
13 #include "printing/print_job_constants.h"
14 #include "printing/print_settings_conversion.h"
15 #include "printing/units.h"
16 
17 namespace printing {
18 
19 namespace {
20 const float kCloudPrintMarginInch = 0.25;
21 }
22 
PrintingContext(Delegate * delegate)23 PrintingContext::PrintingContext(Delegate* delegate)
24     : settings_(std::make_unique<PrintSettings>()),
25       delegate_(delegate),
26       in_print_job_(false),
27       abort_printing_(false) {
28   DCHECK(delegate_);
29 }
30 
31 PrintingContext::~PrintingContext() = default;
32 
set_margin_type(mojom::MarginType type)33 void PrintingContext::set_margin_type(mojom::MarginType type) {
34   DCHECK(type != mojom::MarginType::kCustomMargins);
35   settings_->set_margin_type(type);
36 }
37 
set_is_modifiable(bool is_modifiable)38 void PrintingContext::set_is_modifiable(bool is_modifiable) {
39   settings_->set_is_modifiable(is_modifiable);
40 #if defined(OS_WIN)
41   settings_->set_print_text_with_gdi(is_modifiable);
42 #endif
43 }
44 
settings() const45 const PrintSettings& PrintingContext::settings() const {
46   DCHECK(!in_print_job_);
47   return *settings_;
48 }
49 
ResetSettings()50 void PrintingContext::ResetSettings() {
51   ReleaseContext();
52 
53   settings_->Clear();
54 
55   in_print_job_ = false;
56   abort_printing_ = false;
57 }
58 
TakeAndResetSettings()59 std::unique_ptr<PrintSettings> PrintingContext::TakeAndResetSettings() {
60   std::unique_ptr<PrintSettings> result = std::move(settings_);
61   settings_ = std::make_unique<PrintSettings>();
62   return result;
63 }
64 
OnError()65 PrintingContext::Result PrintingContext::OnError() {
66   Result result = abort_printing_ ? CANCEL : FAILED;
67   ResetSettings();
68   return result;
69 }
70 
UsePdfSettings()71 PrintingContext::Result PrintingContext::UsePdfSettings() {
72   base::Value pdf_settings(base::Value::Type::DICTIONARY);
73   pdf_settings.SetBoolKey(kSettingHeaderFooterEnabled, false);
74   pdf_settings.SetBoolKey(kSettingShouldPrintBackgrounds, false);
75   pdf_settings.SetBoolKey(kSettingShouldPrintSelectionOnly, false);
76   pdf_settings.SetIntKey(kSettingMarginsType,
77                          static_cast<int>(mojom::MarginType::kNoMargins));
78   pdf_settings.SetBoolKey(kSettingCollate, true);
79   pdf_settings.SetIntKey(kSettingCopies, 1);
80   pdf_settings.SetIntKey(kSettingColor,
81                          static_cast<int>(mojom::ColorModel::kColor));
82   pdf_settings.SetIntKey(kSettingDpiHorizontal, kPointsPerInch);
83   pdf_settings.SetIntKey(kSettingDpiVertical, kPointsPerInch);
84   pdf_settings.SetIntKey(
85       kSettingDuplexMode,
86       static_cast<int>(printing::mojom::DuplexMode::kSimplex));
87   pdf_settings.SetBoolKey(kSettingLandscape, false);
88   pdf_settings.SetStringKey(kSettingDeviceName, "");
89   pdf_settings.SetIntKey(kSettingPrinterType,
90                          static_cast<int>(PrinterType::kPdf));
91   pdf_settings.SetIntKey(kSettingScaleFactor, 100);
92   pdf_settings.SetBoolKey(kSettingRasterizePdf, false);
93   pdf_settings.SetIntKey(kSettingPagesPerSheet, 1);
94   return UpdatePrintSettings(std::move(pdf_settings));
95 }
96 
UpdatePrintSettings(base::Value job_settings)97 PrintingContext::Result PrintingContext::UpdatePrintSettings(
98     base::Value job_settings) {
99   ResetSettings();
100   {
101     std::unique_ptr<PrintSettings> settings =
102         PrintSettingsFromJobSettings(job_settings);
103     if (!settings) {
104       NOTREACHED();
105       return OnError();
106     }
107     settings_ = std::move(settings);
108   }
109 
110   PrinterType printer_type = static_cast<PrinterType>(
111       job_settings.FindIntKey(kSettingPrinterType).value());
112   bool print_with_privet = printer_type == PrinterType::kPrivet;
113   bool print_to_cloud = !!job_settings.FindKey(kSettingCloudPrintId);
114   bool open_in_external_preview =
115       !!job_settings.FindKey(kSettingOpenPDFInPreview);
116 
117   if (!open_in_external_preview && (print_to_cloud || print_with_privet ||
118                                     printer_type == PrinterType::kPdf ||
119                                     printer_type == PrinterType::kCloud ||
120                                     printer_type == PrinterType::kExtension)) {
121     settings_->set_dpi(kDefaultPdfDpi);
122     gfx::Size paper_size(GetPdfPaperSizeDeviceUnits());
123     if (!settings_->requested_media().size_microns.IsEmpty()) {
124       float device_microns_per_device_unit =
125           static_cast<float>(kMicronsPerInch) /
126           settings_->device_units_per_inch();
127       paper_size =
128           gfx::Size(settings_->requested_media().size_microns.width() /
129                         device_microns_per_device_unit,
130                     settings_->requested_media().size_microns.height() /
131                         device_microns_per_device_unit);
132     }
133     gfx::Rect paper_rect(0, 0, paper_size.width(), paper_size.height());
134     if (print_to_cloud || print_with_privet) {
135       paper_rect.Inset(
136           kCloudPrintMarginInch * settings_->device_units_per_inch(),
137           kCloudPrintMarginInch * settings_->device_units_per_inch());
138     }
139     settings_->SetPrinterPrintableArea(paper_size, paper_rect, true);
140     return OK;
141   }
142 
143   return UpdatePrinterSettings(
144       open_in_external_preview,
145       job_settings.FindBoolKey(kSettingShowSystemDialog).value_or(false),
146       job_settings.FindIntKey(kSettingPreviewPageCount).value_or(0));
147 }
148 
149 #if BUILDFLAG(IS_ASH)
UpdatePrintSettingsFromPOD(std::unique_ptr<PrintSettings> job_settings)150 PrintingContext::Result PrintingContext::UpdatePrintSettingsFromPOD(
151     std::unique_ptr<PrintSettings> job_settings) {
152   ResetSettings();
153   settings_ = std::move(job_settings);
154 
155   return UpdatePrinterSettings(false /* external_preview */,
156                                false /* show_system_dialog */,
157                                0 /* page_count is only used on Android */);
158 }
159 #endif
160 
161 }  // namespace printing
162