mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
50f811aef5
The old name is potentially misleading now that we implement 'page-orientation' since that provides a new mechanism by which pages could end up orthoganal to the sheet, but this method is very specifically about pages-per-sheet induced rotation. Differential Revision: https://phabricator.services.mozilla.com/D193989
478 lines
19 KiB
C++
478 lines
19 KiB
C++
/* -*- Mode: C++; tab-width: 2; 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 "nsPrintSettingsWin.h"
|
|
|
|
#include "mozilla/ArrayUtils.h"
|
|
#include "nsCRT.h"
|
|
#include "nsDeviceContextSpecWin.h"
|
|
#include "nsPrintSettingsImpl.h"
|
|
#include "WinUtils.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
// Using paper sizes from wingdi.h and the units given there, plus a little
|
|
// extra research for the ones it doesn't give. Looks like the list hasn't
|
|
// changed since Windows 2000, so should be fairly stable now.
|
|
const short kPaperSizeUnits[] = {
|
|
nsIPrintSettings::kPaperSizeMillimeters, // Not Used default to mm as
|
|
// DEVMODE uses tenths of mm, just
|
|
// in case
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTERSMALL
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_TABLOID
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LEDGER
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LEGAL
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_STATEMENT
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_EXECUTIVE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4SMALL
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_FOLIO
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_QUARTO
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_10X14
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_11X17
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_NOTE
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_9
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_10
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_11
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_12
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_14
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_CSHEET
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_DSHEET
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ESHEET
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_DL
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C5
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C3
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C6
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C65
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_B4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_B5
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_B6
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_ITALY
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_MONARCH
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_PERSONAL
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_FANFOLD_US
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_FANFOLD_STD_GERMAN
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_FANFOLD_LGL_GERMAN
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ISO_B4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JAPANESE_POSTCARD
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_9X11
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_10X11
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_15X11
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_INVITE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_RESERVED_48
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_RESERVED_49
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_EXTRA
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LEGAL_EXTRA
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_TABLOID_EXTRA
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_A4_EXTRA
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_EXTRA_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A_PLUS
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B_PLUS
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_PLUS
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4_PLUS
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_EXTRA
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5_EXTRA
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5_EXTRA
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A2
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_EXTRA_TRANSVERSE
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_DBL_JAPANESE_POSTCARD
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A6
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU2
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU3
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU3
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU4
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B4_JIS_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5_JIS_ROTATED
|
|
nsIPrintSettings::
|
|
kPaperSizeMillimeters, // DMPAPER_JAPANESE_POSTCARD_ROTATED
|
|
nsIPrintSettings::
|
|
kPaperSizeMillimeters, // DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A6_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU2_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU3_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU3_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU4_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B6_JIS
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B6_JIS_ROTATED
|
|
nsIPrintSettings::kPaperSizeInches, // DMPAPER_12X11
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_YOU4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_YOU4_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P16K
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32K
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32KBIG
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_1
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_2
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_3
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_4
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_5
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_6
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_7
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_8
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_9
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_10
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P16K_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32K_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32KBIG_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_1_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_2_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_3_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_4_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_5_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_6_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_7_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_8_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_9_ROTATED
|
|
nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_10_ROTATED
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsWin, nsPrintSettings,
|
|
nsIPrintSettingsWin)
|
|
|
|
/** ---------------------------------------------------
|
|
* See documentation in nsPrintSettingsWin.h
|
|
* @update
|
|
*/
|
|
nsPrintSettingsWin::nsPrintSettingsWin()
|
|
: nsPrintSettings(),
|
|
mDeviceName(nullptr),
|
|
mDriverName(nullptr),
|
|
mDevMode(nullptr) {}
|
|
|
|
/** ---------------------------------------------------
|
|
* See documentation in nsPrintSettingsWin.h
|
|
* @update
|
|
*/
|
|
nsPrintSettingsWin::nsPrintSettingsWin(const nsPrintSettingsWin& aPS)
|
|
: mDevMode(nullptr) {
|
|
*this = aPS;
|
|
}
|
|
|
|
/* static */
|
|
void nsPrintSettingsWin::PaperSizeUnitFromDmPaperSize(short aPaperSize,
|
|
int16_t& aPaperSizeUnit) {
|
|
if (aPaperSize > 0 && aPaperSize < int32_t(ArrayLength(kPaperSizeUnits))) {
|
|
aPaperSizeUnit = kPaperSizeUnits[aPaperSize];
|
|
}
|
|
}
|
|
|
|
void nsPrintSettingsWin::InitWithInitializer(
|
|
const PrintSettingsInitializer& aSettings) {
|
|
nsPrintSettings::InitWithInitializer(aSettings);
|
|
|
|
if (aSettings.mDevmodeWStorage.Length() < sizeof(DEVMODEW)) {
|
|
return;
|
|
}
|
|
|
|
auto* devmode =
|
|
reinterpret_cast<const DEVMODEW*>(aSettings.mDevmodeWStorage.Elements());
|
|
if (devmode->dmSize != sizeof(DEVMODEW) ||
|
|
devmode->dmSize + devmode->dmDriverExtra >
|
|
aSettings.mDevmodeWStorage.Length()) {
|
|
return;
|
|
}
|
|
|
|
// SetDevMode copies the DEVMODE.
|
|
SetDevMode(const_cast<DEVMODEW*>(devmode));
|
|
|
|
if (mDevMode->dmFields & DM_SCALE) {
|
|
// Since we do the scaling, grab the DEVMODE value and reset it back to 100.
|
|
double scale = double(mDevMode->dmScale) / 100.0f;
|
|
if (mScaling == 1.0 || scale != 1.0) {
|
|
SetScaling(scale);
|
|
}
|
|
mDevMode->dmScale = 100;
|
|
}
|
|
}
|
|
|
|
already_AddRefed<nsIPrintSettings> CreatePlatformPrintSettings(
|
|
const PrintSettingsInitializer& aSettings) {
|
|
RefPtr<nsPrintSettings> settings = aSettings.mPrintSettings.get();
|
|
if (!settings) {
|
|
settings = MakeRefPtr<nsPrintSettingsWin>();
|
|
}
|
|
settings->InitWithInitializer(aSettings);
|
|
return settings.forget();
|
|
}
|
|
|
|
/** ---------------------------------------------------
|
|
* See documentation in nsPrintSettingsWin.h
|
|
* @update
|
|
*/
|
|
nsPrintSettingsWin::~nsPrintSettingsWin() {
|
|
if (mDevMode) ::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrintSettingsWin::SetDeviceName(const nsAString& aDeviceName) {
|
|
mDeviceName = aDeviceName;
|
|
return NS_OK;
|
|
}
|
|
NS_IMETHODIMP nsPrintSettingsWin::GetDeviceName(nsAString& aDeviceName) {
|
|
aDeviceName = mDeviceName;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrintSettingsWin::SetDriverName(const nsAString& aDriverName) {
|
|
mDriverName = aDriverName;
|
|
return NS_OK;
|
|
}
|
|
NS_IMETHODIMP nsPrintSettingsWin::GetDriverName(nsAString& aDriverName) {
|
|
aDriverName = mDriverName;
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsPrintSettingsWin::CopyDevMode(DEVMODEW* aInDevMode,
|
|
DEVMODEW*& aOutDevMode) {
|
|
aOutDevMode = nullptr;
|
|
size_t size = aInDevMode->dmSize + aInDevMode->dmDriverExtra;
|
|
aOutDevMode =
|
|
(LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
|
if (aOutDevMode) {
|
|
memcpy(aOutDevMode, aInDevMode, size);
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrintSettingsWin::GetDevMode(DEVMODEW** aDevMode) {
|
|
NS_ENSURE_ARG_POINTER(aDevMode);
|
|
|
|
if (mDevMode) {
|
|
CopyDevMode(mDevMode, *aDevMode);
|
|
} else {
|
|
*aDevMode = nullptr;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsPrintSettingsWin::SetDevMode(DEVMODEW* aDevMode) {
|
|
if (mDevMode) {
|
|
::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
|
mDevMode = nullptr;
|
|
}
|
|
|
|
if (aDevMode) {
|
|
CopyDevMode(aDevMode, mDevMode);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsPrintSettingsWin::InitUnwriteableMargin(HDC aHdc) {
|
|
mozilla::gfx::MarginDouble margin =
|
|
mozilla::widget::WinUtils::GetUnwriteableMarginsForDeviceInInches(aHdc);
|
|
|
|
mUnwriteableMargin.SizeTo(NS_INCHES_TO_INT_TWIPS(margin.top),
|
|
NS_INCHES_TO_INT_TWIPS(margin.right),
|
|
NS_INCHES_TO_INT_TWIPS(margin.bottom),
|
|
NS_INCHES_TO_INT_TWIPS(margin.left));
|
|
}
|
|
|
|
void nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode) {
|
|
MOZ_ASSERT(aHdc);
|
|
MOZ_ASSERT(aDevMode);
|
|
|
|
mIsInitedFromPrinter = true;
|
|
if (aDevMode->dmFields & DM_ORIENTATION) {
|
|
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 != HasOrthogonalPagesPerSheet());
|
|
|
|
// Record the orientation of the pages (determined above) in mOrientation:
|
|
mOrientation = int32_t(arePagesPortraitMode ? kPortraitOrientation
|
|
: kLandscapeOrientation);
|
|
}
|
|
|
|
if (aDevMode->dmFields & DM_COPIES) {
|
|
mNumCopies = aDevMode->dmCopies;
|
|
}
|
|
|
|
if (aDevMode->dmFields & DM_DUPLEX) {
|
|
switch (aDevMode->dmDuplex) {
|
|
default:
|
|
MOZ_FALLTHROUGH_ASSERT("bad value for dmDuplex field");
|
|
case DMDUP_SIMPLEX:
|
|
mDuplex = kDuplexNone;
|
|
break;
|
|
case DMDUP_VERTICAL:
|
|
mDuplex = kDuplexFlipOnLongEdge;
|
|
break;
|
|
case DMDUP_HORIZONTAL:
|
|
mDuplex = kDuplexFlipOnShortEdge;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Since we do the scaling, grab their value and reset back to 100.
|
|
if (aDevMode->dmFields & DM_SCALE) {
|
|
double scale = double(aDevMode->dmScale) / 100.0f;
|
|
if (mScaling == 1.0 || scale != 1.0) {
|
|
mScaling = scale;
|
|
}
|
|
aDevMode->dmScale = 100;
|
|
}
|
|
|
|
if (aDevMode->dmFields & DM_PAPERSIZE) {
|
|
mPaperId.Truncate(0);
|
|
mPaperId.AppendInt(aDevMode->dmPaperSize);
|
|
// If it is not a paper size we know about, the unit will remain unchanged.
|
|
PaperSizeUnitFromDmPaperSize(aDevMode->dmPaperSize, mPaperSizeUnit);
|
|
}
|
|
|
|
if (aDevMode->dmFields & DM_COLOR) {
|
|
mPrintInColor = aDevMode->dmColor == DMCOLOR_COLOR;
|
|
}
|
|
|
|
InitUnwriteableMargin(aHdc);
|
|
|
|
int pixelsPerInchY = ::GetDeviceCaps(aHdc, LOGPIXELSY);
|
|
int physicalHeight = ::GetDeviceCaps(aHdc, PHYSICALHEIGHT);
|
|
double physicalHeightInch = double(physicalHeight) / pixelsPerInchY;
|
|
int pixelsPerInchX = ::GetDeviceCaps(aHdc, LOGPIXELSX);
|
|
int physicalWidth = ::GetDeviceCaps(aHdc, PHYSICALWIDTH);
|
|
double physicalWidthInch = double(physicalWidth) / pixelsPerInchX;
|
|
|
|
// Get the paper size from the device context rather than the DEVMODE, because
|
|
// it is always available.
|
|
double paperHeightInch = mOrientation == kPortraitOrientation
|
|
? physicalHeightInch
|
|
: physicalWidthInch;
|
|
mPaperHeight = mPaperSizeUnit == kPaperSizeInches
|
|
? paperHeightInch
|
|
: paperHeightInch * MM_PER_INCH_FLOAT;
|
|
|
|
double paperWidthInch = mOrientation == kPortraitOrientation
|
|
? physicalWidthInch
|
|
: physicalHeightInch;
|
|
mPaperWidth = mPaperSizeUnit == kPaperSizeInches
|
|
? paperWidthInch
|
|
: paperWidthInch * MM_PER_INCH_FLOAT;
|
|
|
|
// Using LOGPIXELSY to match existing code for print scaling calculations.
|
|
mResolution = pixelsPerInchY;
|
|
}
|
|
|
|
void nsPrintSettingsWin::CopyToNative(DEVMODEW* aDevMode) {
|
|
MOZ_ASSERT(aDevMode);
|
|
|
|
if (!mPaperId.IsEmpty()) {
|
|
aDevMode->dmPaperSize = _wtoi((const wchar_t*)mPaperId.BeginReading());
|
|
aDevMode->dmFields |= DM_PAPERSIZE;
|
|
} else {
|
|
aDevMode->dmPaperSize = 0;
|
|
aDevMode->dmFields &= ~DM_PAPERSIZE;
|
|
}
|
|
|
|
aDevMode->dmFields |= DM_COLOR;
|
|
aDevMode->dmColor = mPrintInColor ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME;
|
|
|
|
// The length and width in DEVMODE are always in tenths of a millimeter.
|
|
double tenthsOfAmmPerSizeUnit =
|
|
mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT * 10.0 : 10.0;
|
|
|
|
// Note: small page sizes can be required here for sticker, label and slide
|
|
// printers etc. see bug 1271900.
|
|
if (mPaperHeight > 0) {
|
|
aDevMode->dmPaperLength = std::round(mPaperHeight * tenthsOfAmmPerSizeUnit);
|
|
aDevMode->dmFields |= DM_PAPERLENGTH;
|
|
} else {
|
|
aDevMode->dmPaperLength = 0;
|
|
aDevMode->dmFields &= ~DM_PAPERLENGTH;
|
|
}
|
|
|
|
if (mPaperWidth > 0) {
|
|
aDevMode->dmPaperWidth = std::round(mPaperWidth * tenthsOfAmmPerSizeUnit);
|
|
aDevMode->dmFields |= DM_PAPERWIDTH;
|
|
} else {
|
|
aDevMode->dmPaperWidth = 0;
|
|
aDevMode->dmFields &= ~DM_PAPERWIDTH;
|
|
}
|
|
|
|
// Setup Orientation
|
|
aDevMode->dmOrientation = GetSheetOrientation() == kPortraitOrientation
|
|
? DMORIENT_PORTRAIT
|
|
: DMORIENT_LANDSCAPE;
|
|
aDevMode->dmFields |= DM_ORIENTATION;
|
|
|
|
// Setup Number of Copies
|
|
aDevMode->dmCopies = mNumCopies;
|
|
aDevMode->dmFields |= DM_COPIES;
|
|
|
|
// Setup Simplex/Duplex mode
|
|
switch (mDuplex) {
|
|
case kDuplexNone:
|
|
aDevMode->dmDuplex = DMDUP_SIMPLEX;
|
|
aDevMode->dmFields |= DM_DUPLEX;
|
|
break;
|
|
case kDuplexFlipOnLongEdge:
|
|
aDevMode->dmDuplex = DMDUP_VERTICAL;
|
|
aDevMode->dmFields |= DM_DUPLEX;
|
|
break;
|
|
case kDuplexFlipOnShortEdge:
|
|
aDevMode->dmDuplex = DMDUP_HORIZONTAL;
|
|
aDevMode->dmFields |= DM_DUPLEX;
|
|
break;
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("bad value for duplex option");
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------
|
|
nsresult nsPrintSettingsWin::_Clone(nsIPrintSettings** _retval) {
|
|
RefPtr<nsPrintSettingsWin> printSettings = new nsPrintSettingsWin(*this);
|
|
printSettings.forget(_retval);
|
|
return NS_OK;
|
|
}
|
|
|
|
//-------------------------------------------
|
|
nsPrintSettingsWin& nsPrintSettingsWin::operator=(
|
|
const nsPrintSettingsWin& rhs) {
|
|
if (this == &rhs) {
|
|
return *this;
|
|
}
|
|
|
|
((nsPrintSettings&)*this) = rhs;
|
|
|
|
// Use free because we used the native malloc to create the memory
|
|
if (mDevMode) {
|
|
::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
|
}
|
|
|
|
mDeviceName = rhs.mDeviceName;
|
|
mDriverName = rhs.mDriverName;
|
|
|
|
if (rhs.mDevMode) {
|
|
CopyDevMode(rhs.mDevMode, mDevMode);
|
|
} else {
|
|
mDevMode = nullptr;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
//-------------------------------------------
|
|
nsresult nsPrintSettingsWin::_Assign(nsIPrintSettings* aPS) {
|
|
nsPrintSettingsWin* psWin = static_cast<nsPrintSettingsWin*>(aPS);
|
|
*this = *psWin;
|
|
return NS_OK;
|
|
}
|