mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
6635212e1a
Since we no longer are using the PaperList or CreateDefaultSettings methods on nsPrinterBase, and we can remove them from nsPrinterBase. This should dramatically improve latency when the remote printer is not available, or when the print server is slower. In the best-case scenario it may increase the latency to displaying the print preview somewhat. Differential Revision: https://phabricator.services.mozilla.com/D94482
213 lines
7.8 KiB
C++
213 lines
7.8 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsPrinterBase.h"
|
|
#include "nsPaperMargin.h"
|
|
#include <utility>
|
|
#include "nsPaper.h"
|
|
#include "nsIPrintSettings.h"
|
|
#include "PrintBackgroundTask.h"
|
|
#include "mozilla/dom/Promise.h"
|
|
|
|
using namespace mozilla;
|
|
using mozilla::dom::Promise;
|
|
using mozilla::gfx::MarginDouble;
|
|
|
|
// The maximum error when considering a paper size equal, in points.
|
|
// There is some variance in the actual sizes returned by printer drivers and
|
|
// print servers for paper sizes. This is a best-guess based on initial
|
|
// telemetry which should catch most near-miss dimensions. This should let us
|
|
// get consistent paper size names even when the size isn't quite exactly the
|
|
// correct size.
|
|
static constexpr double kPaperSizePointsEpsilon = 4.0;
|
|
|
|
// Basic implementation of nsIPrinterInfo
|
|
class nsPrinterInfo : public nsIPrinterInfo {
|
|
public:
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterInfo)
|
|
NS_DECL_NSIPRINTERINFO
|
|
nsPrinterInfo() = delete;
|
|
nsPrinterInfo(nsPrinterBase& aPrinter,
|
|
const nsPrinterBase::PrinterInfo& aPrinterInfo)
|
|
: mDefaultSettings(
|
|
CreatePlatformPrintSettings(aPrinterInfo.mDefaultSettings)) {
|
|
mPaperList.SetCapacity(aPrinterInfo.mPaperList.Length());
|
|
for (const PaperInfo& info : aPrinterInfo.mPaperList) {
|
|
mPaperList.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
|
|
}
|
|
}
|
|
|
|
private:
|
|
virtual ~nsPrinterInfo() = default;
|
|
|
|
nsTArray<RefPtr<nsIPaper>> mPaperList;
|
|
RefPtr<nsIPrintSettings> mDefaultSettings;
|
|
};
|
|
|
|
NS_IMETHODIMP
|
|
nsPrinterInfo::GetPaperList(nsTArray<RefPtr<nsIPaper>>& aPaperList) {
|
|
aPaperList = mPaperList.Clone();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrinterInfo::GetDefaultSettings(nsIPrintSettings** aDefaultSettings) {
|
|
NS_ENSURE_ARG_POINTER(aDefaultSettings);
|
|
MOZ_ASSERT(mDefaultSettings);
|
|
RefPtr<nsIPrintSettings> settings = mDefaultSettings;
|
|
settings.forget(aDefaultSettings);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTION(nsPrinterInfo, mPaperList, mDefaultSettings)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterInfo)
|
|
NS_INTERFACE_MAP_ENTRY(nsIPrinterInfo)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterInfo)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterInfo)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterInfo)
|
|
|
|
template <typename Index, Index Size, typename Value>
|
|
inline void ImplCycleCollectionTraverse(
|
|
nsCycleCollectionTraversalCallback& aCallback,
|
|
EnumeratedArray<Index, Size, Value>& aArray, const char* aName,
|
|
uint32_t aFlags = 0) {
|
|
aFlags |= CycleCollectionEdgeNameArrayFlag;
|
|
for (Value& element : aArray) {
|
|
ImplCycleCollectionTraverse(aCallback, element, aName, aFlags);
|
|
}
|
|
}
|
|
|
|
template <typename Index, Index Size, typename Value>
|
|
inline void ImplCycleCollectionUnlink(
|
|
EnumeratedArray<Index, Size, Value>& aArray) {
|
|
for (Value& element : aArray) {
|
|
ImplCycleCollectionUnlink(element);
|
|
}
|
|
}
|
|
|
|
namespace mozilla {
|
|
|
|
template <>
|
|
void ResolveOrReject(Promise& aPromise, nsPrinterBase&,
|
|
const MarginDouble& aResult) {
|
|
auto margin = MakeRefPtr<nsPaperMargin>(aResult);
|
|
aPromise.MaybeResolve(margin);
|
|
}
|
|
|
|
template <>
|
|
void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
|
|
const nsTArray<PaperInfo>& aResult) {
|
|
nsTArray<RefPtr<nsPaper>> result;
|
|
result.SetCapacity(aResult.Length());
|
|
for (const PaperInfo& info : aResult) {
|
|
result.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
|
|
}
|
|
aPromise.MaybeResolve(result);
|
|
}
|
|
|
|
template <>
|
|
void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
|
|
const PrintSettingsInitializer& aResult) {
|
|
aPromise.MaybeResolve(
|
|
RefPtr<nsIPrintSettings>(CreatePlatformPrintSettings(aResult)));
|
|
}
|
|
|
|
template <>
|
|
void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
|
|
const nsPrinterBase::PrinterInfo& aResult) {
|
|
aPromise.MaybeResolve(MakeRefPtr<nsPrinterInfo>(aPrinter, aResult));
|
|
}
|
|
|
|
} // namespace mozilla
|
|
|
|
template <typename T, typename... Args>
|
|
nsresult nsPrinterBase::AsyncPromiseAttributeGetter(
|
|
JSContext* aCx, Promise** aResultPromise, AsyncAttribute aAttribute,
|
|
BackgroundTask<T, Args...> aBackgroundTask, Args... aArgs) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
static constexpr EnumeratedArray<AsyncAttribute, AsyncAttribute::Last,
|
|
nsLiteralCString>
|
|
attributeKeys{"SupportsDuplex"_ns, "SupportsColor"_ns,
|
|
"SupportsMonochrome"_ns, "SupportsCollation"_ns,
|
|
"PrinterInfo"_ns};
|
|
return mozilla::AsyncPromiseAttributeGetter(
|
|
*this, mAsyncAttributePromises[aAttribute], aCx, aResultPromise,
|
|
attributeKeys[aAttribute], aBackgroundTask, std::forward<Args>(aArgs)...);
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrinterBase::GetSupportsDuplex(JSContext* aCx,
|
|
Promise** aResultPromise) {
|
|
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
|
AsyncAttribute::SupportsDuplex,
|
|
&nsPrinterBase::SupportsDuplex);
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrinterBase::GetSupportsColor(JSContext* aCx,
|
|
Promise** aResultPromise) {
|
|
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
|
AsyncAttribute::SupportsColor,
|
|
&nsPrinterBase::SupportsColor);
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrinterBase::GetSupportsMonochrome(JSContext* aCx,
|
|
Promise** aResultPromise) {
|
|
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
|
AsyncAttribute::SupportsMonochrome,
|
|
&nsPrinterBase::SupportsMonochrome);
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrinterBase::GetSupportsCollation(JSContext* aCx,
|
|
Promise** aResultPromise) {
|
|
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
|
AsyncAttribute::SupportsCollation,
|
|
&nsPrinterBase::SupportsCollation);
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrinterBase::GetPrinterInfo(JSContext* aCx,
|
|
Promise** aResultPromise) {
|
|
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
|
AsyncAttribute::PrinterInfo,
|
|
&nsPrinterBase::CreatePrinterInfo);
|
|
}
|
|
|
|
void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise,
|
|
const nsString& aPaperId) {
|
|
return SpawnPrintBackgroundTask(*this, aPromise, "MarginsForPaper"_ns,
|
|
&nsPrinterBase::GetMarginsForPaper, aPaperId);
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTION(nsPrinterBase, mAsyncAttributePromises)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterBase)
|
|
NS_INTERFACE_MAP_ENTRY(nsIPrinter)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinter)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterBase)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterBase)
|
|
|
|
nsPrinterBase::nsPrinterBase(const CommonPaperInfoArray* aPaperInfoArray)
|
|
: mCommonPaperInfo(aPaperInfoArray) {
|
|
MOZ_DIAGNOSTIC_ASSERT(aPaperInfoArray, "Localized paper info was null");
|
|
}
|
|
nsPrinterBase::~nsPrinterBase() = default;
|
|
|
|
const PaperInfo* nsPrinterBase::FindCommonPaperSize(
|
|
const gfx::SizeDouble& aSize) const {
|
|
for (const PaperInfo& paper : *mCommonPaperInfo) {
|
|
if (std::abs(paper.mSize.width - aSize.width) <= kPaperSizePointsEpsilon &&
|
|
std::abs(paper.mSize.height - aSize.height) <=
|
|
kPaperSizePointsEpsilon) {
|
|
return &paper;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|