зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1667486
part 2 - Use our own localization for nsPrinterCUPS paper sizes when possible r=emilio
This should be able to avoid creating a printer-specific HTTP connection in nsPrinterCUPS::DefaultSettings when the paper size is a PWG-recognized size. The current maximum error when comparing paper sizes is 4 points. This may need to be revised later. Differential Revision: https://phabricator.services.mozilla.com/D91497
This commit is contained in:
Родитель
8202fe3024
Коммит
31f2236856
|
@ -15,6 +15,14 @@ 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;
|
||||
|
||||
void nsPrinterBase::CachePrintSettingsInitializer(
|
||||
const PrintSettingsInitializer& aInitializer) {
|
||||
if (mPrintSettingsInitializer.isNothing()) {
|
||||
|
@ -166,5 +174,20 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterBase)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterBase)
|
||||
|
||||
nsPrinterBase::nsPrinterBase() = default;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@ class nsPrinterBase : public nsIPrinter {
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterBase)
|
||||
|
||||
// We require the paper info array
|
||||
nsPrinterBase() = delete;
|
||||
|
||||
// No copy or move, we're an identity.
|
||||
nsPrinterBase(const nsPrinterBase&) = delete;
|
||||
nsPrinterBase(nsPrinterBase&&) = delete;
|
||||
|
@ -84,7 +87,7 @@ class nsPrinterBase : public nsIPrinter {
|
|||
Maybe<PrintSettingsInitializer> mPrintSettingsInitializer;
|
||||
|
||||
protected:
|
||||
nsPrinterBase();
|
||||
nsPrinterBase(const mozilla::CommonPaperInfoArray* aPaperInfoArray);
|
||||
virtual ~nsPrinterBase();
|
||||
|
||||
// Implementation-specific methods. These must not make assumptions about
|
||||
|
@ -96,11 +99,17 @@ class nsPrinterBase : public nsIPrinter {
|
|||
virtual bool SupportsCollation() const = 0;
|
||||
virtual nsTArray<mozilla::PaperInfo> PaperList() const = 0;
|
||||
virtual MarginDouble GetMarginsForPaper(nsString aPaperId) const = 0;
|
||||
// Searches our built-in list of commonly used PWG paper sizes for a matching,
|
||||
// localized PaperInfo. Returns null if there is no matching size.
|
||||
const mozilla::PaperInfo* FindCommonPaperSize(
|
||||
const mozilla::gfx::SizeDouble& aSize) const;
|
||||
|
||||
private:
|
||||
mozilla::EnumeratedArray<AsyncAttribute, AsyncAttribute::Last,
|
||||
RefPtr<Promise>>
|
||||
mAsyncAttributePromises;
|
||||
// List of built-in, commonly used paper sizes.
|
||||
const RefPtr<const mozilla::CommonPaperInfoArray> mCommonPaperInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,13 +18,14 @@ using namespace mozilla;
|
|||
static constexpr Array<const char* const, 1> requestedAttributes{
|
||||
"cups-version"};
|
||||
|
||||
static PaperInfo MakePaperInfo(const char* aName, const cups_size_t& aMedia) {
|
||||
const double kPointsPerHundredthMillimeter = 72.0 / 2540.0;
|
||||
// XXX Do we actually have the guarantee that these are utf-8?
|
||||
static constexpr double kPointsPerHundredthMillimeter = 72.0 / 2540.0;
|
||||
|
||||
static PaperInfo MakePaperInfo(const nsAString& aName,
|
||||
const cups_size_t& aMedia) {
|
||||
// XXX Do we actually have the guarantee that this is utf-8?
|
||||
NS_ConvertUTF8toUTF16 paperId(aMedia.media); // internal paper name/ID
|
||||
NS_ConvertUTF8toUTF16 paperName(aName); // localized human-friendly name
|
||||
return PaperInfo(
|
||||
paperId, paperName,
|
||||
paperId, aName,
|
||||
{aMedia.width * kPointsPerHundredthMillimeter,
|
||||
aMedia.length * kPointsPerHundredthMillimeter},
|
||||
Some(gfx::MarginDouble{aMedia.top * kPointsPerHundredthMillimeter,
|
||||
|
@ -123,7 +124,18 @@ PrintSettingsInitializer nsPrinterCUPS::DefaultSettings() const {
|
|||
};
|
||||
}
|
||||
|
||||
const char* localizedName = nullptr;
|
||||
// Check if this is a localized fallback paper size, in which case we can
|
||||
// avoid using the CUPS localization methods.
|
||||
const gfx::SizeDouble sizeDouble{
|
||||
media.width * kPointsPerHundredthMillimeter,
|
||||
media.length * kPointsPerHundredthMillimeter};
|
||||
if (const PaperInfo* const paperInfo = FindCommonPaperSize(sizeDouble)) {
|
||||
return PrintSettingsInitializer{
|
||||
std::move(printerName),
|
||||
MakePaperInfo(paperInfo->mName, media),
|
||||
SupportsColor(),
|
||||
};
|
||||
}
|
||||
|
||||
// blocking call
|
||||
http_t* connection = mShim.cupsConnectDest(mPrinter, CUPS_DEST_FLAGS_NONE,
|
||||
|
@ -134,8 +146,11 @@ PrintSettingsInitializer nsPrinterCUPS::DefaultSettings() const {
|
|||
/* callback */ nullptr,
|
||||
/* user_data */ nullptr);
|
||||
|
||||
// XXX Do we actually have the guarantee that this is utf-8?
|
||||
NS_ConvertUTF8toUTF16 localizedName{
|
||||
connection ? LocalizeMediaName(*connection, media) : ""};
|
||||
|
||||
if (connection) {
|
||||
localizedName = LocalizeMediaName(*connection, media);
|
||||
mShim.httpClose(connection);
|
||||
}
|
||||
|
||||
|
@ -281,18 +296,28 @@ nsTArray<PaperInfo> nsPrinterCUPS::PaperList() const {
|
|||
nsTArray<PaperInfo> paperList;
|
||||
nsTHashtable<nsCharPtrHashKey> paperSet(std::max(paperCount, 0));
|
||||
|
||||
paperList.SetCapacity(paperCount);
|
||||
for (int i = 0; i < paperCount; ++i) {
|
||||
cups_size_t media;
|
||||
int getInfoSucceeded = mShim.cupsGetDestMediaByIndex(
|
||||
const int getInfoSucceeded = mShim.cupsGetDestMediaByIndex(
|
||||
connection, mPrinter, printerInfo, i, CUPS_MEDIA_FLAGS_DEFAULT, &media);
|
||||
|
||||
if (!getInfoSucceeded || !paperSet.EnsureInserted(media.media)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* mediaName =
|
||||
connection ? LocalizeMediaName(*connection, media) : media.media;
|
||||
paperList.AppendElement(MakePaperInfo(mediaName, media));
|
||||
// Check if this is a PWG paper size, in which case we can avoid using the
|
||||
// CUPS localization methods.
|
||||
const gfx::SizeDouble sizeDouble{
|
||||
media.width * kPointsPerHundredthMillimeter,
|
||||
media.length * kPointsPerHundredthMillimeter};
|
||||
if (const PaperInfo* const paperInfo = FindCommonPaperSize(sizeDouble)) {
|
||||
paperList.AppendElement(MakePaperInfo(paperInfo->mName, media));
|
||||
} else {
|
||||
const char* const mediaName =
|
||||
connection ? LocalizeMediaName(*connection, media) : media.media;
|
||||
paperList.AppendElement(
|
||||
MakePaperInfo(NS_ConvertUTF8toUTF16(mediaName), media));
|
||||
}
|
||||
}
|
||||
|
||||
if (connection) {
|
||||
|
|
|
@ -36,9 +36,11 @@ class nsPrinterCUPS final : public nsPrinterBase {
|
|||
|
||||
nsPrinterCUPS() = delete;
|
||||
|
||||
nsPrinterCUPS(const nsCUPSShim& aShim, nsString aDisplayName,
|
||||
nsPrinterCUPS(const mozilla::CommonPaperInfoArray* aArray,
|
||||
const nsCUPSShim& aShim, nsString aDisplayName,
|
||||
cups_dest_t* aPrinter)
|
||||
: mShim(aShim),
|
||||
: nsPrinterBase(aArray),
|
||||
mShim(aShim),
|
||||
mDisplayName(std::move(aDisplayName)),
|
||||
mPrinter(aPrinter),
|
||||
mPrinterInfoMutex("nsPrinterCUPS::mPrinterInfoMutex") {}
|
||||
|
|
|
@ -53,6 +53,7 @@ void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
|
|||
|
||||
NS_IMETHODIMP nsPrinterListBase::GetPrinters(JSContext* aCx,
|
||||
Promise** aResult) {
|
||||
EnsureCommonPaperInfo(aCx);
|
||||
return mozilla::AsyncPromiseAttributeGetter(*this, mPrintersPromise, aCx,
|
||||
aResult, "Printers"_ns,
|
||||
&nsPrinterListBase::Printers);
|
||||
|
@ -61,6 +62,7 @@ NS_IMETHODIMP nsPrinterListBase::GetPrinters(JSContext* aCx,
|
|||
NS_IMETHODIMP nsPrinterListBase::GetPrinterByName(const nsAString& aPrinterName,
|
||||
JSContext* aCx,
|
||||
Promise** aResult) {
|
||||
EnsureCommonPaperInfo(aCx);
|
||||
return PrintBackgroundTaskPromise(*this, aCx, aResult, "PrinterByName"_ns,
|
||||
&nsPrinterListBase::PrinterByName,
|
||||
nsString{aPrinterName});
|
||||
|
@ -68,6 +70,7 @@ NS_IMETHODIMP nsPrinterListBase::GetPrinterByName(const nsAString& aPrinterName,
|
|||
|
||||
NS_IMETHODIMP nsPrinterListBase::GetPrinterBySystemName(
|
||||
const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
|
||||
EnsureCommonPaperInfo(aCx);
|
||||
return PrintBackgroundTaskPromise(
|
||||
*this, aCx, aResult, "PrinterBySystemName"_ns,
|
||||
&nsPrinterListBase::PrinterBySystemName, nsString{aPrinterName});
|
||||
|
@ -75,6 +78,7 @@ NS_IMETHODIMP nsPrinterListBase::GetPrinterBySystemName(
|
|||
|
||||
NS_IMETHODIMP nsPrinterListBase::GetNamedOrDefaultPrinter(
|
||||
const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
|
||||
EnsureCommonPaperInfo(aCx);
|
||||
return PrintBackgroundTaskPromise(
|
||||
*this, aCx, aResult, "NamedOrDefaultPrinter"_ns,
|
||||
&nsPrinterListBase::NamedOrDefaultPrinter, nsString{aPrinterName});
|
||||
|
|
|
@ -108,7 +108,7 @@ nsTArray<PrinterInfo> nsPrinterListCUPS::Printers() const {
|
|||
|
||||
RefPtr<nsIPrinter> nsPrinterListCUPS::CreatePrinter(PrinterInfo aInfo) const {
|
||||
return mozilla::MakeRefPtr<nsPrinterCUPS>(
|
||||
sCupsShim, std::move(aInfo.mName),
|
||||
mCommonPaperInfo, sCupsShim, std::move(aInfo.mName),
|
||||
static_cast<cups_dest_t*>(aInfo.mCupsHandle));
|
||||
}
|
||||
|
||||
|
|
|
@ -586,7 +586,7 @@ Maybe<nsPrinterListBase::PrinterInfo> nsPrinterListWin::PrinterBySystemName(
|
|||
}
|
||||
|
||||
RefPtr<nsIPrinter> nsPrinterListWin::CreatePrinter(PrinterInfo aInfo) const {
|
||||
return nsPrinterWin::Create(std::move(aInfo.mName));
|
||||
return nsPrinterWin::Create(mCommonPaperInfo, std::move(aInfo.mName));
|
||||
}
|
||||
|
||||
nsresult nsPrinterListWin::SystemDefaultPrinterName(nsAString& aName) const {
|
||||
|
|
|
@ -22,13 +22,16 @@ using namespace mozilla::widget;
|
|||
static const double kPointsPerTenthMM = 72.0 / 254.0;
|
||||
static const double kPointsPerInch = 72.0;
|
||||
|
||||
nsPrinterWin::nsPrinterWin(const nsAString& aName)
|
||||
: mName(aName),
|
||||
nsPrinterWin::nsPrinterWin(const CommonPaperInfoArray* aArray,
|
||||
const nsAString& aName)
|
||||
: nsPrinterBase(aArray),
|
||||
mName(aName),
|
||||
mDefaultDevmodeWStorage("nsPrinterWin::mDefaultDevmodeWStorage") {}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsPrinterWin> nsPrinterWin::Create(const nsAString& aName) {
|
||||
return do_AddRef(new nsPrinterWin(aName));
|
||||
already_AddRefed<nsPrinterWin> nsPrinterWin::Create(
|
||||
const CommonPaperInfoArray* aArray, const nsAString& aName) {
|
||||
return do_AddRef(new nsPrinterWin(aArray, aName));
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> nsPrinterWin::CopyDefaultDevmodeW() const {
|
||||
|
|
|
@ -23,10 +23,13 @@ class nsPrinterWin final : public nsPrinterBase {
|
|||
MarginDouble GetMarginsForPaper(nsString aPaperId) const final;
|
||||
|
||||
nsPrinterWin() = delete;
|
||||
static already_AddRefed<nsPrinterWin> Create(const nsAString& aName);
|
||||
static already_AddRefed<nsPrinterWin> Create(
|
||||
const mozilla::CommonPaperInfoArray* aPaperInfoArray,
|
||||
const nsAString& aName);
|
||||
|
||||
private:
|
||||
explicit nsPrinterWin(const nsAString& aName);
|
||||
nsPrinterWin(const mozilla::CommonPaperInfoArray* aPaperInfoArray,
|
||||
const nsAString& aName);
|
||||
~nsPrinterWin() = default;
|
||||
|
||||
nsTArray<uint8_t> CopyDefaultDevmodeW() const;
|
||||
|
|
Загрузка…
Ссылка в новой задаче