Bug 1885489 - Part 5: Add SnapshotIterator::readInt32(). r=iain
[gecko.git] / widget / nsPrinterBase.cpp
blob0c8f71d574c64ee81bd7c4cc65764bbc54b60523
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsPrinterBase.h"
7 #include "nsPaperMargin.h"
8 #include <utility>
9 #include "nsPaper.h"
10 #include "nsIPrintSettings.h"
11 #include "nsPrintSettingsService.h"
12 #include "PrintBackgroundTask.h"
13 #include "mozilla/EnumeratedArrayCycleCollection.h"
14 #include "mozilla/dom/Promise.h"
16 using namespace mozilla;
17 using mozilla::dom::Promise;
18 using mozilla::gfx::MarginDouble;
20 // The maximum error when considering a paper size equal, in points.
21 // There is some variance in the actual sizes returned by printer drivers and
22 // print servers for paper sizes. This is a best-guess based on initial
23 // telemetry which should catch most near-miss dimensions. This should let us
24 // get consistent paper size names even when the size isn't quite exactly the
25 // correct size.
26 static constexpr double kPaperSizePointsEpsilon = 4.0;
28 // Basic implementation of nsIPrinterInfo
29 class nsPrinterInfo : public nsIPrinterInfo {
30 public:
31 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
32 NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterInfo)
33 NS_DECL_NSIPRINTERINFO
34 nsPrinterInfo() = delete;
35 nsPrinterInfo(nsPrinterBase& aPrinter,
36 const nsPrinterBase::PrinterInfo& aPrinterInfo)
37 : mDefaultSettings(
38 CreatePlatformPrintSettings(aPrinterInfo.mDefaultSettings)) {
39 mPaperList.SetCapacity(aPrinterInfo.mPaperList.Length());
40 for (const PaperInfo& info : aPrinterInfo.mPaperList) {
41 mPaperList.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
44 // Update the printer's default settings with the global settings.
45 nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
46 do_GetService("@mozilla.org/gfx/printsettings-service;1");
47 if (printSettingsSvc) {
48 // Passing false as the second parameter means we don't get the printer
49 // specific settings.
50 printSettingsSvc->InitPrintSettingsFromPrefs(
51 mDefaultSettings, false, nsIPrintSettings::kInitSaveAll);
55 private:
56 virtual ~nsPrinterInfo() = default;
58 nsTArray<RefPtr<nsIPaper>> mPaperList;
59 RefPtr<nsIPrintSettings> mDefaultSettings;
62 NS_IMETHODIMP
63 nsPrinterInfo::GetPaperList(nsTArray<RefPtr<nsIPaper>>& aPaperList) {
64 aPaperList = mPaperList.Clone();
65 return NS_OK;
68 NS_IMETHODIMP
69 nsPrinterInfo::GetDefaultSettings(nsIPrintSettings** aDefaultSettings) {
70 NS_ENSURE_ARG_POINTER(aDefaultSettings);
71 MOZ_ASSERT(mDefaultSettings);
72 RefPtr<nsIPrintSettings> settings = mDefaultSettings;
73 settings.forget(aDefaultSettings);
74 return NS_OK;
77 NS_IMPL_CYCLE_COLLECTION(nsPrinterInfo, mPaperList, mDefaultSettings)
79 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterInfo)
80 NS_INTERFACE_MAP_ENTRY(nsIPrinterInfo)
81 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterInfo)
82 NS_INTERFACE_MAP_END
84 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterInfo)
85 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterInfo)
87 namespace mozilla {
89 template <>
90 void ResolveOrReject(Promise& aPromise, nsPrinterBase&,
91 const MarginDouble& aResult) {
92 auto margin = MakeRefPtr<nsPaperMargin>(aResult);
93 aPromise.MaybeResolve(margin);
96 template <>
97 void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
98 const nsTArray<PaperInfo>& aResult) {
99 nsTArray<RefPtr<nsPaper>> result;
100 result.SetCapacity(aResult.Length());
101 for (const PaperInfo& info : aResult) {
102 result.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
104 aPromise.MaybeResolve(result);
107 template <>
108 void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
109 const PrintSettingsInitializer& aResult) {
110 aPromise.MaybeResolve(
111 RefPtr<nsIPrintSettings>(CreatePlatformPrintSettings(aResult)));
114 template <>
115 void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
116 const nsPrinterBase::PrinterInfo& aResult) {
117 aPromise.MaybeResolve(MakeRefPtr<nsPrinterInfo>(aPrinter, aResult));
120 } // namespace mozilla
122 template <typename T, typename... Args>
123 nsresult nsPrinterBase::AsyncPromiseAttributeGetter(
124 JSContext* aCx, Promise** aResultPromise, AsyncAttribute aAttribute,
125 BackgroundTask<T, Args...> aBackgroundTask, Args... aArgs) {
126 MOZ_ASSERT(NS_IsMainThread());
128 static constexpr EnumeratedArray<AsyncAttribute, nsLiteralCString,
129 size_t(AsyncAttribute::Last)>
130 attributeKeys{"SupportsDuplex"_ns, "SupportsColor"_ns,
131 "SupportsMonochrome"_ns, "SupportsCollation"_ns,
132 "PrinterInfo"_ns};
133 return mozilla::AsyncPromiseAttributeGetter(
134 *this, mAsyncAttributePromises[aAttribute], aCx, aResultPromise,
135 attributeKeys[aAttribute], aBackgroundTask, std::forward<Args>(aArgs)...);
138 NS_IMETHODIMP nsPrinterBase::CopyFromWithValidation(
139 nsIPrintSettings* aSettingsToCopyFrom, JSContext* aCx,
140 Promise** aResultPromise) {
141 MOZ_ASSERT(NS_IsMainThread());
142 MOZ_ASSERT(aResultPromise);
144 ErrorResult errorResult;
145 RefPtr<dom::Promise> promise =
146 dom::Promise::Create(xpc::CurrentNativeGlobal(aCx), errorResult);
147 if (MOZ_UNLIKELY(errorResult.Failed())) {
148 return errorResult.StealNSResult();
151 nsCOMPtr<nsIPrintSettings> settings;
152 MOZ_ALWAYS_SUCCEEDS(aSettingsToCopyFrom->Clone(getter_AddRefs(settings)));
153 nsString printerName;
154 MOZ_ALWAYS_SUCCEEDS(GetName(printerName));
155 MOZ_ALWAYS_SUCCEEDS(settings->SetPrinterName(printerName));
156 promise->MaybeResolve(settings);
157 promise.forget(aResultPromise);
159 return NS_OK;
162 NS_IMETHODIMP nsPrinterBase::GetSupportsDuplex(JSContext* aCx,
163 Promise** aResultPromise) {
164 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
165 AsyncAttribute::SupportsDuplex,
166 &nsPrinterBase::SupportsDuplex);
169 NS_IMETHODIMP nsPrinterBase::GetSupportsColor(JSContext* aCx,
170 Promise** aResultPromise) {
171 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
172 AsyncAttribute::SupportsColor,
173 &nsPrinterBase::SupportsColor);
176 NS_IMETHODIMP nsPrinterBase::GetSupportsMonochrome(JSContext* aCx,
177 Promise** aResultPromise) {
178 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
179 AsyncAttribute::SupportsMonochrome,
180 &nsPrinterBase::SupportsMonochrome);
183 NS_IMETHODIMP nsPrinterBase::GetSupportsCollation(JSContext* aCx,
184 Promise** aResultPromise) {
185 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
186 AsyncAttribute::SupportsCollation,
187 &nsPrinterBase::SupportsCollation);
190 NS_IMETHODIMP nsPrinterBase::GetPrinterInfo(JSContext* aCx,
191 Promise** aResultPromise) {
192 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
193 AsyncAttribute::PrinterInfo,
194 &nsPrinterBase::CreatePrinterInfo);
197 void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise,
198 const nsString& aPaperId) {
199 return SpawnPrintBackgroundTask(*this, aPromise, "MarginsForPaper"_ns,
200 &nsPrinterBase::GetMarginsForPaper, aPaperId);
203 NS_IMPL_CYCLE_COLLECTION(nsPrinterBase, mAsyncAttributePromises)
205 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterBase)
206 NS_INTERFACE_MAP_ENTRY(nsIPrinter)
207 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinter)
208 NS_INTERFACE_MAP_END
210 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterBase)
211 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterBase)
213 nsPrinterBase::nsPrinterBase(const CommonPaperInfoArray* aPaperInfoArray)
214 : mCommonPaperInfo(aPaperInfoArray) {
215 MOZ_DIAGNOSTIC_ASSERT(aPaperInfoArray, "Localized paper info was null");
217 nsPrinterBase::~nsPrinterBase() = default;
219 const PaperInfo* nsPrinterBase::FindCommonPaperSize(
220 const gfx::SizeDouble& aSize) const {
221 for (const PaperInfo& paper : *mCommonPaperInfo) {
222 if (std::abs(paper.mSize.width - aSize.width) <= kPaperSizePointsEpsilon &&
223 std::abs(paper.mSize.height - aSize.height) <=
224 kPaperSizePointsEpsilon) {
225 return &paper;
228 return nullptr;