Bug 1663940: Ensure the unwriteable margins are populated in the print settings. r=emilio

This updates the settings with the correct paper ID as well.
It also removes the printable size fields from the Windows settings now that
unwriteable margins are being used consistently.

Differential Revision: https://phabricator.services.mozilla.com/D89911
This commit is contained in:
Bob Owen 2020-09-11 15:00:18 +00:00
parent 315722c21e
commit c6fa9e48a9
15 changed files with 44 additions and 121 deletions

View File

@ -886,6 +886,11 @@ const PrintSettingsViewProxy = {
let paperSize = this.availablePaperSizes[paperName];
target.paperWidth = paperSize.width;
target.paperHeight = paperSize.height;
target.paperData = paperSize.paperId;
target.unwriteableMarginTop = paperSize.unwriteableMarginTop;
target.unwriteableMarginRight = paperSize.unwriteableMarginRight;
target.unwriteableMarginBottom = paperSize.unwriteableMarginBottom;
target.unwriteableMarginLeft = paperSize.unwriteableMarginLeft;
target.paperName = value;
// pull new margin values for the new paperName
this.set(target, "margins", this.get(target, "margins"));

View File

@ -70,8 +70,6 @@ struct PrintData {
/* Windows-specific things */
nsString driverName;
nsString deviceName;
double printableWidthInInches;
double printableHeightInInches;
uint8_t[] devModeData;
/**

View File

@ -32,4 +32,10 @@ interface nsIPaper : nsISupports
* 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;
};

View File

@ -39,18 +39,6 @@ interface nsIPrintSettingsWin : nsISupports
[noscript] attribute nsDevMode devMode;
/**
* On Windows we use the printable width and height for the printing surface.
* We don't want to have to create native print device contexts in the content
* process, so we need to store these in the settings.
* Storing in Inches is most convenient as they are retrieved from the device
* using fields which are in pixels and pixels per inch.
* Note these are stored in portrait format to ensure that we can take account
* of our own changes to the orientation print setting.
*/
[noscript] attribute double printableWidthInInches;
[noscript] attribute double printableHeightInInches;
/**
* Copy relevant print settings from native Windows device.
*

View File

@ -79,3 +79,9 @@ nsPaper::GetUnwriteableMargin(JSContext* aCx, Promise** aPromise) {
promise.forget(aPromise);
return NS_OK;
}
NS_IMETHODIMP
nsPaper::GetPaperId(short* aPaperId) {
*aPaperId = mInfo.mPaperId;
return NS_OK;
}

View File

@ -27,8 +27,7 @@ struct PaperInfo {
PaperInfo() = default;
PaperInfo(const nsAString& aName, const SizeDouble& aSize,
const Maybe<MarginDouble>& aUnwriteableMargin,
uint64_t aPaperId = 0)
const Maybe<MarginDouble>& aUnwriteableMargin, short aPaperId = 0)
: mName(aName),
mSize(aSize),
mUnwriteableMargin(aUnwriteableMargin),
@ -42,7 +41,7 @@ struct PaperInfo {
const Maybe<MarginDouble> mUnwriteableMargin{Nothing()};
// The paper id from the device, this is only useful on Windows, right now.
uint64_t mPaperId{0};
short mPaperId{0};
};
} // namespace mozilla

View File

@ -164,8 +164,6 @@ nsPrintSettingsService::SerializeToPrintData(nsIPrintSettings* aSettings,
// assertions).
// data->driverName() default-initializes
// data->deviceName() default-initializes
data->printableWidthInInches() = 0;
data->printableHeightInInches() = 0;
// data->GTKPrintSettings() default-initializes
// data->printJobName() default-initializes
data->printAllPages() = true;

View File

@ -150,7 +150,7 @@ NS_IMETHODIMP nsPrinterBase::GetPaperList(JSContext* aCx,
&nsPrinterBase::PaperList);
}
void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise, uint64_t aPaperId) {
void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise, short aPaperId) {
return SpawnPrintBackgroundTask(*this, aPromise, "MarginsForPaper"_ns,
&nsPrinterBase::GetMarginsForPaper, aPaperId);
}

View File

@ -45,7 +45,7 @@ class nsPrinterBase : public nsIPrinter {
nsPrinterBase(const nsPrinterBase&) = delete;
nsPrinterBase(nsPrinterBase&&) = delete;
void QueryMarginsForPaper(Promise&, uint64_t aPaperId);
void QueryMarginsForPaper(Promise&, short aPaperId);
/**
* Caches the argument by copying it into mPrintSettingsInitializer.
@ -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(uint64_t aPaperId) const = 0;
virtual MarginDouble GetMarginsForPaper(short aPaperId) const = 0;
private:
mozilla::EnumeratedArray<AsyncAttribute, AsyncAttribute::Last,

View File

@ -26,7 +26,7 @@ class nsPrinterCUPS final : public nsPrinterBase {
bool SupportsMonochrome() const final;
bool SupportsCollation() const final;
nsTArray<mozilla::PaperInfo> PaperList() const final;
MarginDouble GetMarginsForPaper(uint64_t) const final {
MarginDouble GetMarginsForPaper(short) 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");

View File

@ -41,9 +41,6 @@ nsPrintSettingsServiceWin::SerializeToPrintData(nsIPrintSettings* aSettings,
// When creating the print dialog on Windows, we only need to send certain
// print settings information from the parent to the child not vice versa.
if (XRE_IsParentProcess()) {
psWin->GetPrintableWidthInInches(&data->printableWidthInInches());
psWin->GetPrintableHeightInInches(&data->printableHeightInInches());
// A DEVMODE can actually be of arbitrary size. If it turns out that it'll
// make our IPC message larger than the limit, then we'll error out.
LPDEVMODEW devModeRaw;
@ -91,9 +88,6 @@ nsPrintSettingsServiceWin::DeserializeToPrintSettings(
psWin->SetDeviceName(data.deviceName());
psWin->SetDriverName(data.driverName());
psWin->SetPrintableWidthInInches(data.printableWidthInInches());
psWin->SetPrintableHeightInInches(data.printableHeightInInches());
if (data.devModeData().IsEmpty()) {
psWin->SetDevMode(nullptr);
} else {

View File

@ -231,24 +231,6 @@ void nsPrintSettingsWin::InitWithInitializer(
mPaperSizeUnit == kPaperSizeInches ? 1.0 / 72.0 : 25.4 / 72.0;
SetPaperWidth(aSettings.mPaperInfo.mSize.width * pointsToSizeUnit);
SetPaperHeight(aSettings.mPaperInfo.mSize.height * pointsToSizeUnit);
double printableWidthInPoints = aSettings.mPaperInfo.mSize.width;
double printableHeightInPoints = aSettings.mPaperInfo.mSize.height;
if (aSettings.mPaperInfo.mUnwriteableMargin.isSome()) {
const auto& margin = aSettings.mPaperInfo.mUnwriteableMargin.value();
printableWidthInPoints -= (margin.top + margin.bottom);
printableHeightInPoints -= (margin.left + margin.right);
}
// Keep these values in portrait format, so we can reflect our own changes
// to mOrientation.
if (mOrientation == kPortraitOrientation) {
mPrintableWidthInInches = printableWidthInPoints / POINTS_PER_INCH_FLOAT;
mPrintableHeightInInches = printableHeightInPoints / POINTS_PER_INCH_FLOAT;
} else {
mPrintableHeightInInches = printableWidthInPoints / POINTS_PER_INCH_FLOAT;
mPrintableWidthInInches = printableHeightInPoints / POINTS_PER_INCH_FLOAT;
}
}
already_AddRefed<nsIPrintSettings> CreatePlatformPrintSettings(
@ -318,51 +300,6 @@ NS_IMETHODIMP nsPrintSettingsWin::SetDevMode(DEVMODEW* aDevMode) {
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsWin::GetPrintableWidthInInches(double* aPrintableWidthInInches) {
MOZ_ASSERT(aPrintableWidthInInches);
*aPrintableWidthInInches = mPrintableWidthInInches;
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsWin::SetPrintableWidthInInches(double aPrintableWidthInInches) {
mPrintableWidthInInches = aPrintableWidthInInches;
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsWin::GetPrintableHeightInInches(
double* aPrintableHeightInInches) {
MOZ_ASSERT(aPrintableHeightInInches);
*aPrintableHeightInInches = mPrintableHeightInInches;
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsWin::SetPrintableHeightInInches(
double aPrintableHeightInInches) {
mPrintableHeightInInches = aPrintableHeightInInches;
return NS_OK;
}
NS_IMETHODIMP
nsPrintSettingsWin::GetEffectivePageSize(double* aWidth, double* aHeight) {
// If printable page size not set, fall back to nsPrintSettings.
if (mPrintableWidthInInches == 0l || mPrintableHeightInInches == 0l) {
return nsPrintSettings::GetEffectivePageSize(aWidth, aHeight);
}
if (mOrientation == kPortraitOrientation) {
*aWidth = NS_INCHES_TO_TWIPS(mPrintableWidthInInches);
*aHeight = NS_INCHES_TO_TWIPS(mPrintableHeightInInches);
} else {
*aHeight = NS_INCHES_TO_TWIPS(mPrintableWidthInInches);
*aWidth = NS_INCHES_TO_TWIPS(mPrintableHeightInInches);
}
return NS_OK;
}
void nsPrintSettingsWin::InitUnwriteableMargin(HDC aHdc) {
mozilla::gfx::MarginDouble margin =
mozilla::widget::WinUtils::GetUnwriteableMarginsForDeviceInInches(aHdc);
@ -431,39 +368,38 @@ void nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode) {
InitUnwriteableMargin(aHdc);
int pixelsPerInchY = ::GetDeviceCaps(aHdc, LOGPIXELSY);
// The length and width in DEVMODE are always in tenths of a millimeter.
double sizeUnitToTenthsOfAmm =
10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L);
if (aDevMode->dmFields & DM_PAPERLENGTH) {
mPaperHeight = aDevMode->dmPaperLength / sizeUnitToTenthsOfAmm;
} else {
mPaperHeight = -1l;
// We need the paper height to be set, because it is used in the child for
// layout. If it is not set in the DEVMODE, get it from the device context.
int physicalHeight = ::GetDeviceCaps(aHdc, PHYSICALHEIGHT);
double physicalHeightInch = double(physicalHeight) / pixelsPerInchY;
mPaperHeight = mPaperSizeUnit == kPaperSizeInches
? physicalHeightInch
: physicalHeightInch * MM_PER_INCH_FLOAT;
}
if (aDevMode->dmFields & DM_PAPERWIDTH) {
mPaperWidth = aDevMode->dmPaperWidth / sizeUnitToTenthsOfAmm;
} else {
mPaperWidth = -1l;
// We need the paper width to be set, because it is used in the child for
// layout. If it is not set in the DEVMODE, get it from the device context.
int pixelsPerInchX = ::GetDeviceCaps(aHdc, LOGPIXELSX);
int physicalWidth = ::GetDeviceCaps(aHdc, PHYSICALWIDTH);
double physicalWidthInch = double(physicalWidth) / pixelsPerInchX;
mPaperWidth = mPaperSizeUnit == kPaperSizeInches
? physicalWidthInch
: physicalWidthInch * MM_PER_INCH_FLOAT;
}
// Note: we only scale the printing using the LOGPIXELSY, so we use that
// when calculating the surface width as well as the height.
int32_t printableWidthInDots = GetDeviceCaps(aHdc, PHYSICALWIDTH);
int32_t printableHeightInDots = GetDeviceCaps(aHdc, PHYSICALHEIGHT);
int32_t heightDPI = GetDeviceCaps(aHdc, LOGPIXELSY);
// Keep these values in portrait format, so we can reflect our own changes
// to mOrientation.
if (mOrientation == kPortraitOrientation) {
mPrintableWidthInInches = double(printableWidthInDots) / heightDPI;
mPrintableHeightInInches = double(printableHeightInDots) / heightDPI;
} else {
mPrintableHeightInInches = double(printableWidthInDots) / heightDPI;
mPrintableWidthInInches = double(printableHeightInDots) / heightDPI;
}
// Using Y to match existing code for print scaling calculations.
mResolution = heightDPI;
// Using LOGPIXELSY to match existing code for print scaling calculations.
mResolution = pixelsPerInchY;
}
void nsPrintSettingsWin::CopyToNative(DEVMODEW* aDevMode) {
@ -562,9 +498,6 @@ nsPrintSettingsWin& nsPrintSettingsWin::operator=(
mDevMode = nullptr;
}
mPrintableWidthInInches = rhs.mPrintableWidthInInches;
mPrintableHeightInInches = rhs.mPrintableHeightInInches;
return *this;
}

View File

@ -41,8 +41,6 @@ class nsPrintSettingsWin : public nsPrintSettings, public nsIPrintSettingsWin {
*/
nsPrintSettingsWin& operator=(const nsPrintSettingsWin& rhs);
NS_IMETHOD GetEffectivePageSize(double* aWidth, double* aHeight) override;
protected:
void CopyDevMode(DEVMODEW* aInDevMode, DEVMODEW*& aOutDevMode);
void InitUnwriteableMargin(HDC aHdc);
@ -50,8 +48,6 @@ class nsPrintSettingsWin : public nsPrintSettings, public nsIPrintSettingsWin {
nsString mDeviceName;
nsString mDriverName;
LPDEVMODEW mDevMode;
double mPrintableWidthInInches = 0l;
double mPrintableHeightInInches = 0l;
};
#endif /* nsPrintSettingsWin_h__ */

View File

@ -228,7 +228,7 @@ nsTArray<mozilla::PaperInfo> nsPrinterWin::PaperList() const {
}
mozilla::gfx::MarginDouble nsPrinterWin::GetMarginsForPaper(
uint64_t aPaperId) const {
short aPaperId) const {
static const wchar_t kDriverName[] = L"WINSPOOL";
// Now get the margin info.
// We need a DEVMODE to set the paper size on the context.

View File

@ -17,7 +17,7 @@ class nsPrinterWin final : public nsPrinterBase {
bool SupportsMonochrome() const final;
bool SupportsCollation() const final;
nsTArray<mozilla::PaperInfo> PaperList() const final;
MarginDouble GetMarginsForPaper(uint64_t aId) const final;
MarginDouble GetMarginsForPaper(short aPaperId) const final;
nsPrinterWin() = delete;
static already_AddRefed<nsPrinterWin> Create(const nsAString& aName);