Bug 1688354 [wpt PR 27298] - Treat 'rem' as an absolute unit for font size, a=testonly
[gecko.git] / widget / nsPrinterBase.cpp
blobd86f30c4a0534e99a792fcc8f32559b8630cfc09
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 "PrintBackgroundTask.h"
12 #include "mozilla/dom/Promise.h"
14 using namespace mozilla;
15 using mozilla::dom::Promise;
16 using mozilla::gfx::MarginDouble;
18 // The maximum error when considering a paper size equal, in points.
19 // There is some variance in the actual sizes returned by printer drivers and
20 // print servers for paper sizes. This is a best-guess based on initial
21 // telemetry which should catch most near-miss dimensions. This should let us
22 // get consistent paper size names even when the size isn't quite exactly the
23 // correct size.
24 static constexpr double kPaperSizePointsEpsilon = 4.0;
26 // Basic implementation of nsIPrinterInfo
27 class nsPrinterInfo : public nsIPrinterInfo {
28 public:
29 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
30 NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterInfo)
31 NS_DECL_NSIPRINTERINFO
32 nsPrinterInfo() = delete;
33 nsPrinterInfo(nsPrinterBase& aPrinter,
34 const nsPrinterBase::PrinterInfo& aPrinterInfo)
35 : mDefaultSettings(
36 CreatePlatformPrintSettings(aPrinterInfo.mDefaultSettings)) {
37 mPaperList.SetCapacity(aPrinterInfo.mPaperList.Length());
38 for (const PaperInfo& info : aPrinterInfo.mPaperList) {
39 mPaperList.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
43 private:
44 virtual ~nsPrinterInfo() = default;
46 nsTArray<RefPtr<nsIPaper>> mPaperList;
47 RefPtr<nsIPrintSettings> mDefaultSettings;
50 NS_IMETHODIMP
51 nsPrinterInfo::GetPaperList(nsTArray<RefPtr<nsIPaper>>& aPaperList) {
52 aPaperList = mPaperList.Clone();
53 return NS_OK;
56 NS_IMETHODIMP
57 nsPrinterInfo::GetDefaultSettings(nsIPrintSettings** aDefaultSettings) {
58 NS_ENSURE_ARG_POINTER(aDefaultSettings);
59 MOZ_ASSERT(mDefaultSettings);
60 RefPtr<nsIPrintSettings> settings = mDefaultSettings;
61 settings.forget(aDefaultSettings);
62 return NS_OK;
65 NS_IMPL_CYCLE_COLLECTION(nsPrinterInfo, mPaperList, mDefaultSettings)
67 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterInfo)
68 NS_INTERFACE_MAP_ENTRY(nsIPrinterInfo)
69 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterInfo)
70 NS_INTERFACE_MAP_END
72 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterInfo)
73 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterInfo)
75 template <typename Index, Index Size, typename Value>
76 inline void ImplCycleCollectionTraverse(
77 nsCycleCollectionTraversalCallback& aCallback,
78 EnumeratedArray<Index, Size, Value>& aArray, const char* aName,
79 uint32_t aFlags = 0) {
80 aFlags |= CycleCollectionEdgeNameArrayFlag;
81 for (Value& element : aArray) {
82 ImplCycleCollectionTraverse(aCallback, element, aName, aFlags);
86 template <typename Index, Index Size, typename Value>
87 inline void ImplCycleCollectionUnlink(
88 EnumeratedArray<Index, Size, Value>& aArray) {
89 for (Value& element : aArray) {
90 ImplCycleCollectionUnlink(element);
94 namespace mozilla {
96 template <>
97 void ResolveOrReject(Promise& aPromise, nsPrinterBase&,
98 const MarginDouble& aResult) {
99 auto margin = MakeRefPtr<nsPaperMargin>(aResult);
100 aPromise.MaybeResolve(margin);
103 template <>
104 void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
105 const nsTArray<PaperInfo>& aResult) {
106 nsTArray<RefPtr<nsPaper>> result;
107 result.SetCapacity(aResult.Length());
108 for (const PaperInfo& info : aResult) {
109 result.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
111 aPromise.MaybeResolve(result);
114 template <>
115 void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
116 const PrintSettingsInitializer& aResult) {
117 aPromise.MaybeResolve(
118 RefPtr<nsIPrintSettings>(CreatePlatformPrintSettings(aResult)));
121 template <>
122 void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
123 const nsPrinterBase::PrinterInfo& aResult) {
124 aPromise.MaybeResolve(MakeRefPtr<nsPrinterInfo>(aPrinter, aResult));
127 } // namespace mozilla
129 template <typename T, typename... Args>
130 nsresult nsPrinterBase::AsyncPromiseAttributeGetter(
131 JSContext* aCx, Promise** aResultPromise, AsyncAttribute aAttribute,
132 BackgroundTask<T, Args...> aBackgroundTask, Args... aArgs) {
133 MOZ_ASSERT(NS_IsMainThread());
135 static constexpr EnumeratedArray<AsyncAttribute, AsyncAttribute::Last,
136 nsLiteralCString>
137 attributeKeys{"SupportsDuplex"_ns, "SupportsColor"_ns,
138 "SupportsMonochrome"_ns, "SupportsCollation"_ns,
139 "PrinterInfo"_ns};
140 return mozilla::AsyncPromiseAttributeGetter(
141 *this, mAsyncAttributePromises[aAttribute], aCx, aResultPromise,
142 attributeKeys[aAttribute], aBackgroundTask, std::forward<Args>(aArgs)...);
145 NS_IMETHODIMP nsPrinterBase::GetSupportsDuplex(JSContext* aCx,
146 Promise** aResultPromise) {
147 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
148 AsyncAttribute::SupportsDuplex,
149 &nsPrinterBase::SupportsDuplex);
152 NS_IMETHODIMP nsPrinterBase::GetSupportsColor(JSContext* aCx,
153 Promise** aResultPromise) {
154 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
155 AsyncAttribute::SupportsColor,
156 &nsPrinterBase::SupportsColor);
159 NS_IMETHODIMP nsPrinterBase::GetSupportsMonochrome(JSContext* aCx,
160 Promise** aResultPromise) {
161 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
162 AsyncAttribute::SupportsMonochrome,
163 &nsPrinterBase::SupportsMonochrome);
166 NS_IMETHODIMP nsPrinterBase::GetSupportsCollation(JSContext* aCx,
167 Promise** aResultPromise) {
168 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
169 AsyncAttribute::SupportsCollation,
170 &nsPrinterBase::SupportsCollation);
173 NS_IMETHODIMP nsPrinterBase::GetPrinterInfo(JSContext* aCx,
174 Promise** aResultPromise) {
175 return AsyncPromiseAttributeGetter(aCx, aResultPromise,
176 AsyncAttribute::PrinterInfo,
177 &nsPrinterBase::CreatePrinterInfo);
180 void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise,
181 const nsString& aPaperId) {
182 return SpawnPrintBackgroundTask(*this, aPromise, "MarginsForPaper"_ns,
183 &nsPrinterBase::GetMarginsForPaper, aPaperId);
186 NS_IMPL_CYCLE_COLLECTION(nsPrinterBase, mAsyncAttributePromises)
188 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterBase)
189 NS_INTERFACE_MAP_ENTRY(nsIPrinter)
190 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinter)
191 NS_INTERFACE_MAP_END
193 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterBase)
194 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterBase)
196 nsPrinterBase::nsPrinterBase(const CommonPaperInfoArray* aPaperInfoArray)
197 : mCommonPaperInfo(aPaperInfoArray) {
198 MOZ_DIAGNOSTIC_ASSERT(aPaperInfoArray, "Localized paper info was null");
200 nsPrinterBase::~nsPrinterBase() = default;
202 const PaperInfo* nsPrinterBase::FindCommonPaperSize(
203 const gfx::SizeDouble& aSize) const {
204 for (const PaperInfo& paper : *mCommonPaperInfo) {
205 if (std::abs(paper.mSize.width - aSize.width) <= kPaperSizePointsEpsilon &&
206 std::abs(paper.mSize.height - aSize.height) <=
207 kPaperSizePointsEpsilon) {
208 return &paper;
211 return nullptr;