Skip to content

Commit

Permalink
Bug 1662538 - patch 1 - Make nsIPaper expose a non-localizable .id in…
Browse files Browse the repository at this point in the history
… addition to a localizable .name attribute. r=jwatt

Differential Revision: https://phabricator.services.mozilla.com/D90073
  • Loading branch information
jfkthame committed Sep 17, 2020
1 parent d9a9639 commit 3e9e3d8
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 81 deletions.
17 changes: 9 additions & 8 deletions widget/nsIPaper.idl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
interface nsIPaper : nsISupports
{
/**
* The name of the paper.
* The internal name of the paper (a fixed, non-localized ID).
* (For CUPS, this is the PWG-standardized name as used internally by CUPS;
* on Windows, it is the integer paper ID as a string.)
*/
readonly attribute AString id;

/**
* The human-readable (potentially localized) name of the paper.
*/
readonly attribute AString name;

Expand All @@ -28,14 +35,8 @@ interface nsIPaper : nsISupports
/**
* The Promise resolves with an nsIPaperMargin object. The margin widths contained
* in that object's top/bottom/left/right properties are relative to the paper in
* portrait oriantation. That is, top and bottom are the margins for the short edges,
* portrait orientation. That is, top and bottom are the margins for the short edges,
* and left and right are the margins for the long edges.
*/
[implicit_jscontext] readonly attribute Promise unwriteableMargin;

/**
* Windows only.
* An ID that if non-zero uniquely identifies the paper.
*/
readonly attribute short paperId;
};
16 changes: 8 additions & 8 deletions widget/nsPaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@ nsPaper::nsPaper(nsPrinterBase& aPrinter, const mozilla::PaperInfo& aInfo)

nsPaper::~nsPaper() = default;

NS_IMETHODIMP
nsPaper::GetId(nsAString& aId) {
aId = mInfo.mId;
return NS_OK;
}

NS_IMETHODIMP
nsPaper::GetName(nsAString& aName) {
aName = mInfo.mName;
aName = mInfo.mName.IsEmpty() ? mInfo.mId : mInfo.mName;
return NS_OK;
}

Expand Down Expand Up @@ -69,7 +75,7 @@ nsPaper::GetUnwriteableMargin(JSContext* aCx, Promise** aPromise) {
mMarginPromise->MaybeResolve(margin);
} else {
if (mPrinter) {
mPrinter->QueryMarginsForPaper(*mMarginPromise, mInfo.mPaperId);
mPrinter->QueryMarginsForPaper(*mMarginPromise, mInfo.mId);
} else {
MOZ_ASSERT_UNREACHABLE("common paper sizes should know their margins");
mMarginPromise->MaybeRejectWithNotSupportedError("Margins unavailable");
Expand All @@ -79,9 +85,3 @@ nsPaper::GetUnwriteableMargin(JSContext* aCx, Promise** aPromise) {
promise.forget(aPromise);
return NS_OK;
}

NS_IMETHODIMP
nsPaper::GetPaperId(short* aPaperId) {
*aPaperId = mInfo.mPaperId;
return NS_OK;
}
15 changes: 7 additions & 8 deletions widget/nsPaper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,21 @@ struct PaperInfo {
using SizeDouble = mozilla::gfx::SizeDouble;

PaperInfo() = default;
PaperInfo(const nsAString& aName, const SizeDouble& aSize,
const Maybe<MarginDouble>& aUnwriteableMargin, short aPaperId = 0)
: mName(aName),
PaperInfo(const nsAString& aId, const nsAString& aName,
const SizeDouble& aSize,
const Maybe<MarginDouble>& aUnwriteableMargin)
: mId(aId),
mName(aName),
mSize(aSize),
mUnwriteableMargin(aUnwriteableMargin),
mPaperId(aPaperId) {}
mUnwriteableMargin(aUnwriteableMargin) {}

const nsString mId;
const nsString mName;

SizeDouble mSize;

// The margins may not be known by some back-ends.
const Maybe<MarginDouble> mUnwriteableMargin{Nothing()};

// The paper id from the device, this is only useful on Windows, right now.
short mPaperId{0};
};

} // namespace mozilla
Expand Down
5 changes: 4 additions & 1 deletion widget/nsPrintSettingsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ void nsPrintSettings::InitWithInitializer(
SetPrinterName(aSettings.mPrinter);
SetPrintInColor(aSettings.mPrintInColor);
SetResolution(aSettings.mResolution);
SetPaperName(aSettings.mPaperInfo.mName);
// The paper "name" used by nsPrintSettings is the non-localizable identifier
// exposed as "id" by the paper, not the potentially localized human-friendly
// "name", which could change, e.g. if the user changes their system locale.
SetPaperName(aSettings.mPaperInfo.mId);
SetPaperWidth(aSettings.mPaperInfo.mSize.Width() * kInchesPerPoint);
SetPaperHeight(aSettings.mPaperInfo.mSize.Height() * kInchesPerPoint);
SetPaperSizeUnit(nsIPrintSettings::kPaperSizeInches);
Expand Down
3 changes: 2 additions & 1 deletion widget/nsPrinterBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ NS_IMETHODIMP nsPrinterBase::GetPaperList(JSContext* aCx,
&nsPrinterBase::PaperList);
}

void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise, short aPaperId) {
void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise,
const nsString& aPaperId) {
return SpawnPrintBackgroundTask(*this, aPromise, "MarginsForPaper"_ns,
&nsPrinterBase::GetMarginsForPaper, aPaperId);
}
Expand Down
4 changes: 2 additions & 2 deletions widget/nsPrinterBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class nsPrinterBase : public nsIPrinter {
nsPrinterBase(const nsPrinterBase&) = delete;
nsPrinterBase(nsPrinterBase&&) = delete;

void QueryMarginsForPaper(Promise&, short aPaperId);
void QueryMarginsForPaper(Promise&, const nsString& aPaperId);

/**
* Caches the argument by copying it into mPrintSettingsInitializer.
Expand Down Expand Up @@ -95,7 +95,7 @@ class nsPrinterBase : public nsIPrinter {
virtual bool SupportsMonochrome() const = 0;
virtual bool SupportsCollation() const = 0;
virtual nsTArray<mozilla::PaperInfo> PaperList() const = 0;
virtual MarginDouble GetMarginsForPaper(short aPaperId) const = 0;
virtual MarginDouble GetMarginsForPaper(nsString aPaperId) const = 0;

private:
mozilla::EnumeratedArray<AsyncAttribute, AsyncAttribute::Last,
Expand Down
14 changes: 5 additions & 9 deletions widget/nsPrinterCUPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ static constexpr Array<const char* const, 1> requestedAttributes{
"cups-version"};

static PaperInfo MakePaperInfo(const char* aName, const cups_size_t& aMedia) {
// XXX Do we actually have the guarantee that this is utf-8?
NS_ConvertUTF8toUTF16 name(aName ? aName : aMedia.media);
const double kPointsPerHundredthMillimeter = 0.0283465;
const double kPointsPerHundredthMillimeter = 72.0 / 2540.0;
// XXX Do we actually have the guarantee that these are utf-8?
NS_ConvertUTF8toUTF16 paperId(aMedia.media); // internal paper name/ID
NS_ConvertUTF8toUTF16 paperName(aName); // localized human-friendly name
return PaperInfo(
name,
paperId, paperName,
{aMedia.width * kPointsPerHundredthMillimeter,
aMedia.length * kPointsPerHundredthMillimeter},
Some(gfx::MarginDouble{aMedia.top * kPointsPerHundredthMillimeter,
Expand Down Expand Up @@ -154,18 +155,13 @@ void nsPrinterCUPS::GetPrinterName(nsAString& aName) const {

const char* nsPrinterCUPS::LocalizeMediaName(http_t& aConnection,
cups_size_t& aMedia) const {
// We want to localize the name on macOS, but not on Linux.
#ifdef XP_MACOSX
// The returned string is owned by mPrinterInfo.
// https://www.cups.org/doc/cupspm.html#cupsLocalizeDestMedia
auto printerInfoLock = mPrinterInfoMutex.Lock();
EnsurePrinterInfo(*printerInfoLock);
cups_dinfo_t* const printerInfo = printerInfoLock->mPrinterInfo;
return mShim.cupsLocalizeDestMedia(&aConnection, mPrinter, printerInfo,
CUPS_MEDIA_FLAGS_DEFAULT, &aMedia);
#else
return nullptr;
#endif
}

bool nsPrinterCUPS::SupportsDuplex() const {
Expand Down
2 changes: 1 addition & 1 deletion widget/nsPrinterCUPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class nsPrinterCUPS final : public nsPrinterBase {
bool SupportsMonochrome() const final;
bool SupportsCollation() const final;
nsTArray<mozilla::PaperInfo> PaperList() const final;
MarginDouble GetMarginsForPaper(short) const final {
MarginDouble GetMarginsForPaper(nsString aPaperId) const final {
MOZ_ASSERT_UNREACHABLE(
"The CUPS API requires us to always get the margin when fetching the "
"paper list so there should be no need to query it separately");
Expand Down
40 changes: 11 additions & 29 deletions widget/nsPrinterListBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,19 @@ NS_IMETHODIMP nsPrinterListBase::GetFallbackPaperList(JSContext* aCx,
nsTArray<RefPtr<nsPaper>> nsPrinterListBase::FallbackPaperList() const {
#define mm *72.0 / 25.4
#define in *72.0

#ifdef MOZ_WIDGET_GTK
// For GTK we want to use the PWG standardized names.
static const mozilla::PaperInfo kPapers[] = {
{u"iso_a5"_ns, {148 mm, 210 mm}, Some(MarginDouble{})},
{u"iso_a4"_ns, {210 mm, 297 mm}, Some(MarginDouble{})},
{u"iso_a3"_ns, {297 mm, 420 mm}, Some(MarginDouble{})},
{u"iso_b5"_ns, {176 mm, 250 mm}, Some(MarginDouble{})},
{u"iso_b4"_ns, {250 mm, 353 mm}, Some(MarginDouble{})},
{u"jis_b5"_ns, {182 mm, 257 mm}, Some(MarginDouble{})},
{u"jis_b4"_ns, {257 mm, 364 mm}, Some(MarginDouble{})},
{u"na_letter"_ns, {8.5 in, 11 in}, Some(MarginDouble{})},
{u"na_legal"_ns, {8.5 in, 14 in}, Some(MarginDouble{})},
{u"na_ledger"_ns, {11 in, 17 in}, Some(MarginDouble{})},
};
#else
// Otherwise we want to use the localized name versions.
// As paper IDs, we use the PWG standardized names.
static const mozilla::PaperInfo kPapers[] = {
{u"A5"_ns, {148 mm, 210 mm}, Some(MarginDouble{})},
{u"A4"_ns, {210 mm, 297 mm}, Some(MarginDouble{})},
{u"A3"_ns, {297 mm, 420 mm}, Some(MarginDouble{})},
{u"B5"_ns, {176 mm, 250 mm}, Some(MarginDouble{})},
{u"B4"_ns, {250 mm, 353 mm}, Some(MarginDouble{})},
{u"JIS-B5"_ns, {182 mm, 257 mm}, Some(MarginDouble{})},
{u"JIS-B4"_ns, {257 mm, 364 mm}, Some(MarginDouble{})},
{u"US Letter"_ns, {8.5 in, 11 in}, Some(MarginDouble{})},
{u"US Legal"_ns, {8.5 in, 14 in}, Some(MarginDouble{})},
{u"Tabloid"_ns, {11 in, 17 in}, Some(MarginDouble{})},
{u"iso_a5"_ns, u"A5"_ns, {148 mm, 210 mm}, Some(MarginDouble{})},
{u"iso_a4"_ns, u"A4"_ns, {210 mm, 297 mm}, Some(MarginDouble{})},
{u"iso_a3"_ns, u"A3"_ns, {297 mm, 420 mm}, Some(MarginDouble{})},
{u"iso_b5"_ns, u"B5"_ns, {176 mm, 250 mm}, Some(MarginDouble{})},
{u"iso_b4"_ns, u"B4"_ns, {250 mm, 353 mm}, Some(MarginDouble{})},
{u"jis_b5"_ns, u"JIS-B5"_ns, {182 mm, 257 mm}, Some(MarginDouble{})},
{u"jis_b4"_ns, u"JIS-B4"_ns, {257 mm, 364 mm}, Some(MarginDouble{})},
{u"na_letter"_ns, u"US Letter"_ns, {8.5 in, 11 in}, Some(MarginDouble{})},
{u"na_legal"_ns, u"US Legal"_ns, {8.5 in, 14 in}, Some(MarginDouble{})},
{u"na_ledger"_ns, u"Tabloid"_ns, {11 in, 17 in}, Some(MarginDouble{})},
};
#endif // MOZ_WIDGET_GTK

#undef mm
#undef in

Expand Down
40 changes: 27 additions & 13 deletions widget/windows/nsPrinterWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,29 @@ static bool WithDefaultDevMode(const nsString& aName,
}

PrintSettingsInitializer nsPrinterWin::DefaultSettings() const {
nsString paperName;
SizeDouble paperSize;
// Initialize to something reasonable, in case we fail to get usable data
// from the devmode below.
nsString paperName(u"Letter");
nsString paperIdString(u"1"); // DMPAPER_LETTER
SizeDouble paperSize{8.5 * 72.0, 11.0 * 72.0};
gfx::MarginDouble margin;
int resolution = 0;
bool color = false;

nsTArray<uint8_t> devmodeWStorage;
bool success = WithDefaultDevMode(
mName, devmodeWStorage, [&](HANDLE, DEVMODEW* devmode) {
for (auto paperInfo : PaperList()) {
if (paperInfo.mPaperId == devmode->dmPaperSize) {
paperName.Assign(paperInfo.mName);
paperSize = paperInfo.mSize;
break;
// XXX If DM_PAPERSIZE is not set, or is not a known value, should we
// be returning a "Custom" name of some kind?
if (devmode->dmFields & DM_PAPERSIZE) {
paperIdString.Truncate(0);
paperIdString.AppendInt(devmode->dmPaperSize);
for (auto paperInfo : PaperList()) {
if (paperIdString.Equals(paperInfo.mId)) {
paperName.Assign(paperInfo.mName);
paperSize = paperInfo.mSize;
break;
}
}
}

Expand Down Expand Up @@ -106,8 +115,8 @@ PrintSettingsInitializer nsPrinterWin::DefaultSettings() const {
}

return PrintSettingsInitializer{
mName, PaperInfo(paperName, paperSize, Some(margin)), color, resolution,
std::move(devmodeWStorage)};
mName, PaperInfo(paperIdString, paperName, paperSize, Some(margin)),
color, resolution, std::move(devmodeWStorage)};
}

template <class T>
Expand Down Expand Up @@ -242,25 +251,30 @@ nsTArray<mozilla::PaperInfo> nsPrinterWin::PaperList() const {
continue;
}

// Windows paper IDs are 16-bit integers; we stringify them to store in the
// PaperInfo.mId field.
nsString paperIdString;
paperIdString.AppendInt(paperIds[i]);

// We don't resolve the margins eagerly because they're really expensive (on
// the order of seconds for some drivers).
nsDependentSubstring name(paperNames[i].cbegin(), nameLength);
paperList.AppendElement(mozilla::PaperInfo(nsString(name), {width, height},
Nothing(), paperIds[i]));
paperList.AppendElement(mozilla::PaperInfo(paperIdString, nsString(name),
{width, height}, Nothing()));
}

return paperList;
}

mozilla::gfx::MarginDouble nsPrinterWin::GetMarginsForPaper(
short aPaperId) const {
nsString aPaperId) const {
gfx::MarginDouble margin;

nsTArray<uint8_t> storage;
bool success =
WithDefaultDevMode(mName, storage, [&](HANDLE, DEVMODEW* devmode) {
devmode->dmFields = DM_PAPERSIZE;
devmode->dmPaperSize = aPaperId;
devmode->dmPaperSize = _wtoi((const wchar_t*)aPaperId.BeginReading());
nsAutoHDC printerDc(
::CreateICW(nullptr, mName.get(), nullptr, devmode));
MOZ_DIAGNOSTIC_ASSERT(printerDc, "CreateICW failed");
Expand Down
2 changes: 1 addition & 1 deletion widget/windows/nsPrinterWin.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class nsPrinterWin final : public nsPrinterBase {
bool SupportsMonochrome() const final;
bool SupportsCollation() const final;
nsTArray<mozilla::PaperInfo> PaperList() const final;
MarginDouble GetMarginsForPaper(short aPaperId) const final;
MarginDouble GetMarginsForPaper(nsString aPaperId) const final;

nsPrinterWin() = delete;
static already_AddRefed<nsPrinterWin> Create(const nsAString& aName);
Expand Down

0 comments on commit 3e9e3d8

Please sign in to comment.