зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1669905 part 2: Add nsIPrintSettings APIs to handle the possibility that pages and sheets may have orthogonal orientation, in pages-per-sheet printouts. r=jfkthame
This patch does three things, all centered around these new APIs: (1) Add the APIs themselves -- some nsIPrintSettings methods to reason about the sheet-orientation being potentially flipped to accomodate 2 and 6 pages-per-sheet. (2) Use these new APIs, where appropriate, in places where we previously used the page-orientation to set up the platform-native print-settings objects and print-target. Now, we'll use the *sheet* orientation instead of the page orientation, to be sure we produce the appropriately-oriented platform-native surfaces. Also, for symmetry, this patch adds similar logic to the reverse codepaths, where we update an existing nsIPrintSettings object based on a platform-native print-settings object. (3) Update nsPrintJob's code that informs nsPresContext about the page-size. This patch makes sure that this code uses the *page* size, rather than the *sheet* size, in cases where they differ. (The code that consumes this nsPresContext::GetPageSize API, e.g. our CSS media-query code, really does want the page size, not the sheet size.) Differential Revision: https://phabricator.services.mozilla.com/D100372
This commit is contained in:
Родитель
130ac8226e
Коммит
2cedf5494d
|
@ -1823,7 +1823,19 @@ nsresult nsPrintJob::ReflowPrintObject(const UniquePtr<nsPrintObject>& aPO) {
|
|||
adjSize.width, adjSize.height));
|
||||
|
||||
aPO->mPresShell->BeginObservingDocument();
|
||||
aPO->mPresContext->SetPageSize(adjSize);
|
||||
|
||||
// Here, we inform nsPresContext of the page size. Note that 'adjSize' is
|
||||
// *usually* the page size, but we need to check. Strictly speaking, adjSize
|
||||
// is the *device output size*, which is really the dimensions of a "sheet"
|
||||
// rather than a "page" (an important distinction in an N-pages-per-sheet
|
||||
// scenario). For some pages-per-sheet values, the pages are orthogonal to
|
||||
// the sheet; we adjust for that here by swapping the width with the height.
|
||||
nsSize pageSize = adjSize;
|
||||
if (printData->mPrintSettings->HasOrthogonalSheetsAndPages()) {
|
||||
std::swap(pageSize.width, pageSize.height);
|
||||
}
|
||||
|
||||
aPO->mPresContext->SetPageSize(pageSize);
|
||||
|
||||
int32_t p2a = aPO->mPresContext->DeviceContext()->AppUnitsPerDevPixel();
|
||||
if (documentIsTopLevel && mIsCreatingPrintPreview) {
|
||||
|
|
|
@ -194,7 +194,7 @@ NSPrintInfo* nsPrintSettingsX::CreateOrCopyPrintInfo(bool aWithScaling) {
|
|||
NSPrintInfo* printInfo = [[NSPrintInfo sharedPrintInfo] copy];
|
||||
|
||||
NSSize paperSize;
|
||||
if (mOrientation == kPortraitOrientation) {
|
||||
if (GetSheetOrientation() == kPortraitOrientation) {
|
||||
[printInfo setOrientation:NSPaperOrientationPortrait];
|
||||
paperSize.width = CocoaPointsFromPaperSize(mPaperWidth);
|
||||
paperSize.height = CocoaPointsFromPaperSize(mPaperHeight);
|
||||
|
@ -309,7 +309,16 @@ NSPrintInfo* nsPrintSettingsX::CreateOrCopyPrintInfo(bool aWithScaling) {
|
|||
|
||||
void nsPrintSettingsX::SetPageFormatFromPrintInfo(const NSPrintInfo* aPrintInfo) {
|
||||
NSSize paperSize = [aPrintInfo paperSize];
|
||||
if ([aPrintInfo orientation] == NSPaperOrientationPortrait) {
|
||||
const bool areSheetsOfPaperPortraitMode =
|
||||
([aPrintInfo orientation] == NSPaperOrientationPortrait);
|
||||
|
||||
// If our MacOS print settings say that we're producing portrait-mode sheets
|
||||
// of paper, then our page format must also be portrait-mode; unless we've
|
||||
// got a pages-per-sheet value with orthogonal pages/sheets, in which case
|
||||
// it's reversed.
|
||||
const bool arePagesPortraitMode = (areSheetsOfPaperPortraitMode != HasOrthogonalSheetsAndPages());
|
||||
|
||||
if (arePagesPortraitMode) {
|
||||
mOrientation = nsIPrintSettings::kPortraitOrientation;
|
||||
SetPaperWidth(PaperSizeFromCocoaPoints(paperSize.width));
|
||||
SetPaperHeight(PaperSizeFromCocoaPoints(paperSize.height));
|
||||
|
|
|
@ -67,7 +67,7 @@ NS_IMPL_ISUPPORTS(nsDeviceContextSpecGTK, nsIDeviceContextSpec)
|
|||
|
||||
already_AddRefed<PrintTarget> nsDeviceContextSpecGTK::MakePrintTarget() {
|
||||
double width, height;
|
||||
mPrintSettings->GetEffectivePageSize(&width, &height);
|
||||
mPrintSettings->GetEffectiveSheetSize(&width, &height);
|
||||
|
||||
// convert twips to points
|
||||
width /= TWIPS_PER_POINT_FLOAT;
|
||||
|
@ -117,8 +117,7 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecGTK::MakePrintTarget() {
|
|||
return PrintTargetPDF::CreateOrNull(stream, size);
|
||||
}
|
||||
|
||||
int32_t orientation;
|
||||
mPrintSettings->GetOrientation(&orientation);
|
||||
int32_t orientation = mPrintSettings->GetSheetOrientation();
|
||||
return PrintTargetPS::CreateOrNull(
|
||||
stream, size,
|
||||
orientation == nsIPrintSettings::kPortraitOrientation
|
||||
|
|
|
@ -71,8 +71,8 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecProxy::MakePrintTarget() {
|
|||
MOZ_ASSERT(mRealDeviceContextSpec);
|
||||
|
||||
double width, height;
|
||||
nsresult rv = mPrintSettings->GetEffectivePageSize(&width, &height);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || width <= 0 || height <= 0) {
|
||||
mPrintSettings->GetEffectiveSheetSize(&width, &height);
|
||||
if (width <= 0 || height <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,41 @@ interface nsIPrintSettings : nsISupports
|
|||
*/
|
||||
void GetEffectivePageSize(out double aWidth, out double aHeight);
|
||||
|
||||
/**
|
||||
* Get the printed sheet size in twips, considering both the user-specified
|
||||
* orientation (portrait or landscape) *as well as* the fact that we might be
|
||||
* inverting the orientation to account for 2 or 6 pages-per-sheet.
|
||||
*
|
||||
* This API will usually behave the same (& return the same thing) as
|
||||
* GetEffectivePageSize, *except for* when we are printing with 2 or 6
|
||||
* pages-per-sheet, in which case the return values (aWidth & aHeight) will
|
||||
* be swapped with respect to what GetEffectivePageSize would return.
|
||||
*
|
||||
* Callers should use this method rather than GetEffectivePageSize when they
|
||||
* really do want the size of the sheet of paper to be printed, rather than
|
||||
* the possibly-"virtualized"-via-pages-per-sheet page size.
|
||||
*/
|
||||
[noscript, notxpcom, nostdcall] void GetEffectiveSheetSize(out double aWidth,
|
||||
out double aHeight);
|
||||
|
||||
/**
|
||||
* Get the orientation of a printed sheet. This is usually the same as the
|
||||
* 'orientation' attribute (which is the orientation of individual pages),
|
||||
* except when we're printing with 2 or 6 pages-per-sheet, in which case
|
||||
* it'll be the opposite value.
|
||||
*
|
||||
* Note that this value is not independently settable. Its value is fully
|
||||
* determined by the 'orientation' and 'numPagesPerSheet' attributes.
|
||||
*/
|
||||
[noscript, notxpcom, nostdcall] long GetSheetOrientation();
|
||||
|
||||
/**
|
||||
* Convenience getter, which returns true IFF the sheet orientation and the
|
||||
* page orientation are orthogonal. (In other words, returns true IFF we
|
||||
* are printing with 2 or 6 pages-per-sheet.)
|
||||
*/
|
||||
[noscript, notxpcom, nostdcall] bool HasOrthogonalSheetsAndPages();
|
||||
|
||||
/**
|
||||
* Makes a new copy
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsPaper.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIPrintSession.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
#define DEFAULT_MARGIN_WIDTH 0.5
|
||||
|
@ -697,6 +698,32 @@ nsPrintSettings::GetEffectivePageSize(double* aWidth, double* aHeight) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsPrintSettings::HasOrthogonalSheetsAndPages() {
|
||||
return mNumPagesPerSheet == 2 || mNumPagesPerSheet == 6;
|
||||
}
|
||||
|
||||
void nsPrintSettings::GetEffectiveSheetSize(double* aWidth, double* aHeight) {
|
||||
mozilla::DebugOnly<nsresult> rv = GetEffectivePageSize(aWidth, aHeight);
|
||||
|
||||
// Our GetEffectivePageSize impls only return NS_OK, so this should hold:
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Uh oh, GetEffectivePageSize failed");
|
||||
|
||||
if (HasOrthogonalSheetsAndPages()) {
|
||||
std::swap(*aWidth, *aHeight);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t nsPrintSettings::GetSheetOrientation() {
|
||||
if (HasOrthogonalSheetsAndPages()) {
|
||||
// Sheet orientation is rotated with respect to the page orientation.
|
||||
return kLandscapeOrientation == mOrientation ? kPortraitOrientation
|
||||
: kLandscapeOrientation;
|
||||
}
|
||||
|
||||
// Sheet orientation is the same as the page orientation.
|
||||
return mOrientation;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettings::SetPageRanges(const nsTArray<int32_t>& aPages) {
|
||||
// Needs to be a set of (start, end) pairs.
|
||||
|
|
|
@ -277,7 +277,7 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecWin::MakePrintTarget() {
|
|||
mPrintSettings->GetToFileName(filename);
|
||||
|
||||
double width, height;
|
||||
mPrintSettings->GetEffectivePageSize(&width, &height);
|
||||
mPrintSettings->GetEffectiveSheetSize(&width, &height);
|
||||
if (width <= 0 || height <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -176,9 +176,18 @@ void nsPrintSettingsWin::InitWithInitializer(
|
|||
aSettings.mDevmodeWStorage.Elements())));
|
||||
|
||||
if (mDevMode->dmFields & DM_ORIENTATION) {
|
||||
SetOrientation(mDevMode->dmOrientation == DMORIENT_PORTRAIT
|
||||
? kPortraitOrientation
|
||||
: kLandscapeOrientation);
|
||||
const bool areSheetsOfPaperPortraitMode =
|
||||
(mDevMode->dmOrientation == DMORIENT_PORTRAIT);
|
||||
|
||||
// If our Windows print settings say that we're producing portrait-mode
|
||||
// sheets of paper, then our page format must also be portrait-mode; unless
|
||||
// we've got a pages-per-sheet value with orthogonal pages/sheets, in which
|
||||
// case it's reversed.
|
||||
const bool arePagesPortraitMode =
|
||||
(areSheetsOfPaperPortraitMode != HasOrthogonalSheetsAndPages());
|
||||
|
||||
SetOrientation(arePagesPortraitMode ? kPortraitOrientation
|
||||
: kLandscapeOrientation);
|
||||
}
|
||||
|
||||
if (mDevMode->dmFields & DM_COPIES) {
|
||||
|
@ -315,9 +324,18 @@ void nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode) {
|
|||
|
||||
mIsInitedFromPrinter = true;
|
||||
if (aDevMode->dmFields & DM_ORIENTATION) {
|
||||
mOrientation = int32_t(aDevMode->dmOrientation == DMORIENT_PORTRAIT
|
||||
? kPortraitOrientation
|
||||
: kLandscapeOrientation);
|
||||
const bool areSheetsOfPaperPortraitMode =
|
||||
(aDevMode->dmOrientation == DMORIENT_PORTRAIT);
|
||||
|
||||
// If our Windows print settings say that we're producing portrait-mode
|
||||
// sheets of paper, then our page format must also be portrait-mode; unless
|
||||
// we've got a pages-per-sheet value with orthogonal pages/sheets, in which
|
||||
// case it's reversed.
|
||||
const bool arePagesPortraitMode =
|
||||
(areSheetsOfPaperPortraitMode != HasOrthogonalSheetsAndPages());
|
||||
|
||||
mOrientation = int32_t(arePagesPortraitMode ? kLandscapeOrientation
|
||||
: kPortraitOrientation);
|
||||
}
|
||||
|
||||
if (aDevMode->dmFields & DM_COPIES) {
|
||||
|
@ -447,7 +465,7 @@ void nsPrintSettingsWin::CopyToNative(DEVMODEW* aDevMode) {
|
|||
}
|
||||
|
||||
// Setup Orientation
|
||||
aDevMode->dmOrientation = mOrientation == kPortraitOrientation
|
||||
aDevMode->dmOrientation = GetSheetOrientation() == kPortraitOrientation
|
||||
? DMORIENT_PORTRAIT
|
||||
: DMORIENT_LANDSCAPE;
|
||||
aDevMode->dmFields |= DM_ORIENTATION;
|
||||
|
|
Загрузка…
Ссылка в новой задаче