printing_context.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. #include "printing/printing_context.h"
  5. #include <utility>
  6. #include "base/check.h"
  7. #include "base/notreached.h"
  8. #include "build/build_config.h"
  9. #include "printing/buildflags/buildflags.h"
  10. #include "printing/mojom/print.mojom.h"
  11. #include "printing/page_setup.h"
  12. #include "printing/print_job_constants.h"
  13. #include "printing/print_settings_conversion.h"
  14. #include "printing/printing_context_factory_for_test.h"
  15. #include "printing/units.h"
  16. #if BUILDFLAG(ENABLE_OOP_PRINTING)
  17. #include "printing/printing_features.h"
  18. #endif
  19. namespace printing {
  20. namespace {
  21. PrintingContextFactoryForTest* g_printing_context_factory_for_test = nullptr;
  22. } // namespace
  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. PrintingContext::~PrintingContext() = default;
  31. // static
  32. std::unique_ptr<PrintingContext> PrintingContext::Create(
  33. Delegate* delegate,
  34. bool skip_system_calls) {
  35. return g_printing_context_factory_for_test
  36. ? g_printing_context_factory_for_test->CreatePrintingContext(
  37. delegate, skip_system_calls)
  38. : PrintingContext::CreateImpl(delegate, skip_system_calls);
  39. }
  40. // static
  41. void PrintingContext::SetPrintingContextFactoryForTest(
  42. PrintingContextFactoryForTest* factory) {
  43. g_printing_context_factory_for_test = factory;
  44. }
  45. void PrintingContext::set_margin_type(mojom::MarginType type) {
  46. DCHECK(type != mojom::MarginType::kCustomMargins);
  47. settings_->set_margin_type(type);
  48. }
  49. void PrintingContext::set_is_modifiable(bool is_modifiable) {
  50. settings_->set_is_modifiable(is_modifiable);
  51. }
  52. const PrintSettings& PrintingContext::settings() const {
  53. DCHECK(!in_print_job_);
  54. return *settings_;
  55. }
  56. void PrintingContext::ResetSettings() {
  57. ReleaseContext();
  58. settings_->Clear();
  59. in_print_job_ = false;
  60. abort_printing_ = false;
  61. }
  62. std::unique_ptr<PrintSettings> PrintingContext::TakeAndResetSettings() {
  63. std::unique_ptr<PrintSettings> result = std::move(settings_);
  64. settings_ = std::make_unique<PrintSettings>();
  65. return result;
  66. }
  67. mojom::ResultCode PrintingContext::OnError() {
  68. mojom::ResultCode result = abort_printing_ ? mojom::ResultCode::kCanceled
  69. : mojom::ResultCode::kFailed;
  70. ResetSettings();
  71. return result;
  72. }
  73. void PrintingContext::SetDefaultPrintableAreaForVirtualPrinters() {
  74. gfx::Size paper_size(GetPdfPaperSizeDeviceUnits());
  75. if (!settings_->requested_media().size_microns.IsEmpty()) {
  76. float device_microns_per_device_unit = static_cast<float>(kMicronsPerInch) /
  77. settings_->device_units_per_inch();
  78. paper_size = gfx::Size(settings_->requested_media().size_microns.width() /
  79. device_microns_per_device_unit,
  80. settings_->requested_media().size_microns.height() /
  81. device_microns_per_device_unit);
  82. }
  83. gfx::Rect paper_rect(0, 0, paper_size.width(), paper_size.height());
  84. settings_->SetPrinterPrintableArea(paper_size, paper_rect,
  85. /*landscape_needs_flip=*/true);
  86. }
  87. void PrintingContext::UsePdfSettings() {
  88. base::Value::Dict pdf_settings;
  89. pdf_settings.Set(kSettingHeaderFooterEnabled, false);
  90. pdf_settings.Set(kSettingShouldPrintBackgrounds, false);
  91. pdf_settings.Set(kSettingShouldPrintSelectionOnly, false);
  92. pdf_settings.Set(kSettingMarginsType,
  93. static_cast<int>(mojom::MarginType::kNoMargins));
  94. pdf_settings.Set(kSettingCollate, true);
  95. pdf_settings.Set(kSettingCopies, 1);
  96. pdf_settings.Set(kSettingColor, static_cast<int>(mojom::ColorModel::kColor));
  97. // DPI value should match GetPdfCapabilities().
  98. pdf_settings.Set(kSettingDpiHorizontal, kDefaultPdfDpi);
  99. pdf_settings.Set(kSettingDpiVertical, kDefaultPdfDpi);
  100. pdf_settings.Set(kSettingDuplexMode,
  101. static_cast<int>(printing::mojom::DuplexMode::kSimplex));
  102. pdf_settings.Set(kSettingLandscape, false);
  103. pdf_settings.Set(kSettingDeviceName, "");
  104. pdf_settings.Set(kSettingPrinterType,
  105. static_cast<int>(mojom::PrinterType::kPdf));
  106. pdf_settings.Set(kSettingScaleFactor, 100);
  107. pdf_settings.Set(kSettingRasterizePdf, false);
  108. pdf_settings.Set(kSettingPagesPerSheet, 1);
  109. mojom::ResultCode result = UpdatePrintSettings(std::move(pdf_settings));
  110. // TODO(thestig): Downgrade these to DCHECKs after shipping these CHECKs to
  111. // production without any failures.
  112. CHECK_EQ(result, mojom::ResultCode::kSuccess);
  113. // UsePdfSettings() should never fail and the returned DPI should always be a
  114. // well-known value that is safe to use as a divisor.
  115. #if BUILDFLAG(IS_MAC)
  116. CHECK_EQ(settings_->device_units_per_inch(), kPointsPerInch);
  117. #else
  118. CHECK_EQ(settings_->device_units_per_inch(), kDefaultPdfDpi);
  119. #endif
  120. }
  121. mojom::ResultCode PrintingContext::UpdatePrintSettings(
  122. base::Value::Dict job_settings) {
  123. ResetSettings();
  124. {
  125. std::unique_ptr<PrintSettings> settings =
  126. PrintSettingsFromJobSettings(job_settings);
  127. if (!settings) {
  128. NOTREACHED();
  129. return OnError();
  130. }
  131. settings_ = std::move(settings);
  132. }
  133. mojom::PrinterType printer_type = static_cast<mojom::PrinterType>(
  134. job_settings.FindInt(kSettingPrinterType).value());
  135. if (printer_type == mojom::PrinterType::kPrivetDeprecated ||
  136. printer_type == mojom::PrinterType::kCloudDeprecated) {
  137. NOTREACHED();
  138. return OnError();
  139. }
  140. bool open_in_external_preview =
  141. job_settings.contains(kSettingOpenPDFInPreview);
  142. if (!open_in_external_preview &&
  143. (printer_type == mojom::PrinterType::kPdf ||
  144. printer_type == mojom::PrinterType::kExtension)) {
  145. if (settings_->page_setup_device_units().printable_area().IsEmpty())
  146. SetDefaultPrintableAreaForVirtualPrinters();
  147. return mojom::ResultCode::kSuccess;
  148. }
  149. // The `open_in_external_preview` case does not care about the printable area.
  150. // Local printers set their printable area within UpdatePrinterSettings().
  151. DCHECK(open_in_external_preview ||
  152. printer_type == mojom::PrinterType::kLocal);
  153. PrinterSettings printer_settings {
  154. #if BUILDFLAG(IS_MAC)
  155. .external_preview = open_in_external_preview,
  156. #endif
  157. .show_system_dialog =
  158. job_settings.FindBool(kSettingShowSystemDialog).value_or(false),
  159. #if BUILDFLAG(IS_WIN)
  160. .page_count = job_settings.FindInt(kSettingPreviewPageCount).value_or(0)
  161. #endif
  162. };
  163. return UpdatePrinterSettings(printer_settings);
  164. }
  165. #if BUILDFLAG(IS_CHROMEOS)
  166. mojom::ResultCode PrintingContext::UpdatePrintSettingsFromPOD(
  167. std::unique_ptr<PrintSettings> job_settings) {
  168. ResetSettings();
  169. settings_ = std::move(job_settings);
  170. return UpdatePrinterSettings({.show_system_dialog = false});
  171. }
  172. #endif
  173. void PrintingContext::ApplyPrintSettings(const PrintSettings& settings) {
  174. *settings_ = settings;
  175. }
  176. } // namespace printing