Bug 1238964 Part 2: Move separate DEVMODE to nsIPrintSettings copying into nsPrintSettingsWin. r=jimm

This also corrects what I think are long standing issues with the mapping to and
from print settings on Windows.
Firstly it only uses the DEVMODE flags to decide what should get stored, in the
old code if paper size was not set, it would then use that possibly invalid
paper size to map to length and width. Paper setting prefs are mapped back if
they were stored or if they have been manually set to something sane.
Secondly it corrects the calculation that was used to convert from millimeters
to tenths of millimeters.
It also gets rid of the paperSizeType field, which was only used on Windows and
doesn't actually make sense according to the DEVMODE documentation as the
dmPaperLength and dmPaperWidth fields override the dmPaperSize, but can in
theory be specified at the same time.
This commit is contained in:
Bob Owen 2016-01-12 17:40:07 +00:00
parent 6f2e4eeae8
commit 0def9af60a
11 changed files with 115 additions and 507 deletions

View File

@ -51,7 +51,6 @@ struct PrintData {
bool showPrintProgress;
nsString paperName;
short paperSizeType;
short paperData;
double paperWidth;
double paperHeight;

View File

@ -74,224 +74,6 @@ static bool gDialogWasExtended = false;
static HWND gParentWnd = nullptr;
//******************************************************
// Define native paper sizes
//******************************************************
typedef struct {
short mPaperSize; // native enum
double mWidth;
double mHeight;
bool mIsInches;
} NativePaperSizes;
// There are around 40 default print sizes defined by Windows
const NativePaperSizes kPaperSizes[] = {
{DMPAPER_LETTER, 8.5, 11.0, true},
{DMPAPER_LEGAL, 8.5, 14.0, true},
{DMPAPER_A4, 210.0, 297.0, false},
{DMPAPER_TABLOID, 11.0, 17.0, true},
{DMPAPER_LEDGER, 17.0, 11.0, true},
{DMPAPER_STATEMENT, 5.5, 8.5, true},
{DMPAPER_EXECUTIVE, 7.25, 10.5, true},
{DMPAPER_A3, 297.0, 420.0, false},
{DMPAPER_A5, 148.0, 210.0, false},
{DMPAPER_CSHEET, 17.0, 22.0, true},
{DMPAPER_DSHEET, 22.0, 34.0, true},
{DMPAPER_ESHEET, 34.0, 44.0, true},
{DMPAPER_LETTERSMALL, 8.5, 11.0, true},
{DMPAPER_A4SMALL, 210.0, 297.0, false},
{DMPAPER_B4, 250.0, 354.0, false},
{DMPAPER_B5, 182.0, 257.0, false},
{DMPAPER_FOLIO, 8.5, 13.0, true},
{DMPAPER_QUARTO, 215.0, 275.0, false},
{DMPAPER_10X14, 10.0, 14.0, true},
{DMPAPER_11X17, 11.0, 17.0, true},
{DMPAPER_NOTE, 8.5, 11.0, true},
{DMPAPER_ENV_9, 3.875, 8.875, true},
{DMPAPER_ENV_10, 40.125, 9.5, true},
{DMPAPER_ENV_11, 4.5, 10.375, true},
{DMPAPER_ENV_12, 4.75, 11.0, true},
{DMPAPER_ENV_14, 5.0, 11.5, true},
{DMPAPER_ENV_DL, 110.0, 220.0, false},
{DMPAPER_ENV_C5, 162.0, 229.0, false},
{DMPAPER_ENV_C3, 324.0, 458.0, false},
{DMPAPER_ENV_C4, 229.0, 324.0, false},
{DMPAPER_ENV_C6, 114.0, 162.0, false},
{DMPAPER_ENV_C65, 114.0, 229.0, false},
{DMPAPER_ENV_B4, 250.0, 353.0, false},
{DMPAPER_ENV_B5, 176.0, 250.0, false},
{DMPAPER_ENV_B6, 176.0, 125.0, false},
{DMPAPER_ENV_ITALY, 110.0, 230.0, false},
{DMPAPER_ENV_MONARCH, 3.875, 7.5, true},
{DMPAPER_ENV_PERSONAL, 3.625, 6.5, true},
{DMPAPER_FANFOLD_US, 14.875, 11.0, true},
{DMPAPER_FANFOLD_STD_GERMAN, 8.5, 12.0, true},
{DMPAPER_FANFOLD_LGL_GERMAN, 8.5, 13.0, true},
};
const int32_t kNumPaperSizes = 41;
//----------------------------------------------------------------------------------
// Map an incoming size to a Windows Native enum in the DevMode
static void
MapPaperSizeToNativeEnum(LPDEVMODEW aDevMode,
int16_t aType,
double aW,
double aH)
{
#ifdef DEBUG_rods
BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION;
BOOL doingPaperSize = aDevMode->dmFields & DM_PAPERSIZE;
BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH;
BOOL doingPaperWidth = aDevMode->dmFields & DM_PAPERWIDTH;
#endif
const double kThreshold = 0.05;
for (int32_t i=0;i<kNumPaperSizes;i++) {
double width = kPaperSizes[i].mWidth;
double height = kPaperSizes[i].mHeight;
if (aW < width+kThreshold && aW > width-kThreshold &&
aH < height+kThreshold && aH > height-kThreshold) {
aDevMode->dmPaperSize = kPaperSizes[i].mPaperSize;
aDevMode->dmFields &= ~DM_PAPERLENGTH;
aDevMode->dmFields &= ~DM_PAPERWIDTH;
aDevMode->dmFields |= DM_PAPERSIZE;
return;
}
}
short width = 0;
short height = 0;
if (aType == nsIPrintSettings::kPaperSizeInches) {
width = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aW))) / 10);
height = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aH))) / 10);
} else if (aType == nsIPrintSettings::kPaperSizeMillimeters) {
width = short(aW / 10.0);
height = short(aH / 10.0);
} else {
return; // don't set anything
}
// width and height is in
aDevMode->dmPaperSize = 0;
aDevMode->dmPaperWidth = width;
aDevMode->dmPaperLength = height;
aDevMode->dmFields |= DM_PAPERSIZE;
aDevMode->dmFields |= DM_PAPERLENGTH;
aDevMode->dmFields |= DM_PAPERWIDTH;
}
//----------------------------------------------------------------------------------
// Setup Paper Size & Orientation options into the DevMode
//
static void
SetupDevModeFromSettings(LPDEVMODEW aDevMode, nsIPrintSettings* aPrintSettings)
{
// Setup paper size
if (aPrintSettings) {
int16_t type;
aPrintSettings->GetPaperSizeType(&type);
if (type == nsIPrintSettings::kPaperSizeNativeData) {
int16_t paperEnum;
aPrintSettings->GetPaperData(&paperEnum);
aDevMode->dmPaperSize = paperEnum;
aDevMode->dmFields &= ~DM_PAPERLENGTH;
aDevMode->dmFields &= ~DM_PAPERWIDTH;
aDevMode->dmFields |= DM_PAPERSIZE;
} else {
int16_t unit;
double width, height;
aPrintSettings->GetPaperSizeUnit(&unit);
aPrintSettings->GetPaperWidth(&width);
aPrintSettings->GetPaperHeight(&height);
MapPaperSizeToNativeEnum(aDevMode, unit, width, height);
}
// Setup Orientation
int32_t orientation;
aPrintSettings->GetOrientation(&orientation);
aDevMode->dmOrientation = orientation == nsIPrintSettings::kPortraitOrientation?DMORIENT_PORTRAIT:DMORIENT_LANDSCAPE;
aDevMode->dmFields |= DM_ORIENTATION;
// Setup Number of Copies
int32_t copies;
aPrintSettings->GetNumCopies(&copies);
aDevMode->dmCopies = copies;
aDevMode->dmFields |= DM_COPIES;
}
}
//----------------------------------------------------------------------------------
// Helper Function - Free and reallocate the string
static nsresult
SetPrintSettingsFromDevMode(nsIPrintSettings* aPrintSettings,
LPDEVMODEW aDevMode)
{
if (aPrintSettings == nullptr) {
return NS_ERROR_FAILURE;
}
aPrintSettings->SetIsInitializedFromPrinter(true);
if (aDevMode->dmFields & DM_ORIENTATION) {
int32_t orientation = aDevMode->dmOrientation == DMORIENT_PORTRAIT?
nsIPrintSettings::kPortraitOrientation:nsIPrintSettings::kLandscapeOrientation;
aPrintSettings->SetOrientation(orientation);
}
// Setup Number of Copies
if (aDevMode->dmFields & DM_COPIES) {
aPrintSettings->SetNumCopies(int32_t(aDevMode->dmCopies));
}
// Scaling
// Since we do the scaling, grab their value and reset back to 100
if (aDevMode->dmFields & DM_SCALE) {
double origScale = 1.0;
aPrintSettings->GetScaling(&origScale);
double scale = double(aDevMode->dmScale) / 100.0f;
if (origScale == 1.0 || scale != 1.0) {
aPrintSettings->SetScaling(scale);
}
aDevMode->dmScale = 100;
// To turn this on you must change where the mPrt->mShrinkToFit is being set in the DocumentViewer
//aPrintSettings->SetShrinkToFit(false);
}
if (aDevMode->dmFields & DM_PAPERSIZE) {
aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeNativeData);
aPrintSettings->SetPaperData(aDevMode->dmPaperSize);
for (int32_t i=0;i<kNumPaperSizes;i++) {
if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) {
aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSettings::kPaperSizeInches:nsIPrintSettings::kPaperSizeMillimeters);
break;
}
}
} else if (aDevMode->dmFields & DM_PAPERLENGTH && aDevMode->dmFields & DM_PAPERWIDTH) {
bool found = false;
for (int32_t i=0;i<kNumPaperSizes;i++) {
if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) {
aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined);
aPrintSettings->SetPaperWidth(kPaperSizes[i].mWidth);
aPrintSettings->SetPaperHeight(kPaperSizes[i].mHeight);
aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSettings::kPaperSizeInches:nsIPrintSettings::kPaperSizeMillimeters);
found = true;
break;
}
}
if (!found) {
return NS_ERROR_FAILURE;
}
} else {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
//----------------------------------------------------------------------------------
// Return localized bundle for resource strings
static nsresult
@ -724,7 +506,9 @@ HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSett
if (devMode) {
memcpy(devMode, pNewDevMode, dwNeeded);
// Initialize values from the PrintSettings
SetupDevModeFromSettings(devMode, aPS);
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
MOZ_ASSERT(psWin);
psWin->CopyToNative(devMode);
// Sets back the changes we made to the DevMode into the Printer Driver
dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER);
@ -992,9 +776,8 @@ ShowNativePrintDialog(HWND aHWnd,
return NS_ERROR_FAILURE;
}
psWin->SetDevMode(devMode); // copies DevMode
SetPrintSettingsFromDevMode(aPrintSettings, devMode);
psWin->CopyFromNative(prntdlg.hDC, devMode);
::GlobalUnlock(prntdlg.hDevMode);
psWin->CopyFromNative(prntdlg.hDC);
::DeleteDC(prntdlg.hDC);
#if defined(DEBUG_rods) || defined(DEBUG_dcone)

View File

@ -232,7 +232,6 @@ function createPaperSizeList(selectedInx)
//---------------------------------------------------
function loadDialog()
{
var print_paper_type = 0;
var print_paper_unit = 0;
var print_paper_width = 0.0;
var print_paper_height = 0.0;
@ -243,7 +242,6 @@ function loadDialog()
gPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
if (gPrintSettings) {
print_paper_type = gPrintSettings.paperSizeType;
print_paper_unit = gPrintSettings.paperSizeUnit;
print_paper_width = gPrintSettings.paperWidth;
print_paper_height = gPrintSettings.paperHeight;
@ -353,7 +351,6 @@ function onLoad()
//---------------------------------------------------
function onAccept()
{
var print_paper_type = gPrintSettingsInterface.kPaperSizeDefined;
var print_paper_unit = gPrintSettingsInterface.kPaperSizeInches;
var print_paper_width = 0.0;
var print_paper_height = 0.0;
@ -370,7 +367,6 @@ function onAccept()
print_paper_height = gPaperArray[paperSelectedInx].height;
print_paper_name = gPaperArray[paperSelectedInx].name;
gPrintSettings.paperSizeType = print_paper_type;
gPrintSettings.paperSizeUnit = print_paper_unit;
gPrintSettings.paperWidth = print_paper_width;
gPrintSettings.paperHeight = print_paper_height;
@ -387,7 +383,6 @@ function onAccept()
if (doDebug) {
dump("onAccept******************************\n");
dump("paperSizeType "+print_paper_type+" (should be 1)\n");
dump("paperSizeUnit "+print_paper_unit+"\n");
dump("paperWidth "+print_paper_width+"\n");
dump("paperHeight "+print_paper_height+"\n");

View File

@ -22,7 +22,7 @@ interface nsIPrintSession;
/**
* Simplified graphics interface for JS rendering.
*/
[scriptable, uuid(04dd3a01-a74e-44aa-8d49-2c30478fd7b8)]
[scriptable, uuid(ecc5cbad-57fc-4731-b0bd-09e865bd62ad)]
interface nsIPrintSettings : nsISupports
{
@ -223,7 +223,6 @@ interface nsIPrintSettings : nsISupports
/* Additional XP Related */
attribute wstring paperName; /* name of paper */
attribute short paperSizeType; /* use native data or is defined here */
attribute short paperData; /* native data value */
attribute double paperWidth; /* width of the paper in inches or mm */
attribute double paperHeight; /* height of the paper in inches or mm */

View File

@ -18,7 +18,7 @@
/**
* Simplified PrintSettings for Windows interface
*/
[scriptable, uuid(57c22cc1-311f-44c3-bb49-4d1cf411a3b5)]
[scriptable, uuid(c63eed41-6ac5-459e-8a64-033eb9ad770a)]
interface nsIPrintSettingsWin : nsISupports
{
@ -56,6 +56,14 @@ interface nsIPrintSettingsWin : nsISupports
* Copy relevant print settings from native Windows device.
*
* @param hdc HDC to copy from
* @param devMode DEVMODE to copy from
*/
[notxpcom] void copyFromNative(in nsHdc hdc);
[notxpcom] void copyFromNative(in nsHdc hdc, in nsDevMode devMode);
/**
* Copy relevant print settings to native windows structures.
*
* @param devMode DEVMODE to be populated.
*/
[notxpcom] void copyToNative(in nsDevMode devMode);
};

View File

@ -64,7 +64,6 @@ static const char kPrintFooterStrRight[] = "print_footerright";
static const char kPrintReversed[] = "print_reversed";
static const char kPrintInColor[] = "print_in_color";
static const char kPrintPaperName[] = "print_paper_name";
static const char kPrintPaperSizeType[] = "print_paper_size_type";
static const char kPrintPaperData[] = "print_paper_data";
static const char kPrintPaperSizeUnit[] = "print_paper_size_unit";
static const char kPrintPaperWidth[] = "print_paper_width";
@ -176,7 +175,6 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
aSettings->GetPaperName(getter_Copies(paperName));
data->paperName() = paperName;
aSettings->GetPaperSizeType(&data->paperSizeType());
aSettings->GetPaperData(&data->paperData());
aSettings->GetPaperWidth(&data->paperWidth());
aSettings->GetPaperHeight(&data->paperHeight());
@ -293,7 +291,6 @@ nsPrintOptions::DeserializeToPrintSettings(const PrintData& data,
settings->SetPaperName(data.paperName().get());
settings->SetPaperSizeType(data.paperSizeType());
settings->SetPaperData(data.paperData());
settings->SetPaperWidth(data.paperWidth());
settings->SetPaperHeight(data.paperHeight());
@ -523,11 +520,10 @@ nsPrintOptions::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName,
// Paper size prefs are read as a group
if (aFlags & nsIPrintSettings::kInitSavePaperSize) {
int32_t sizeUnit, sizeType;
int32_t sizeUnit;
double width, height;
bool success = GETINTPREF(kPrintPaperSizeUnit, &sizeUnit)
&& GETINTPREF(kPrintPaperSizeType, &sizeType)
&& GETDBLPREF(kPrintPaperWidth, width)
&& GETDBLPREF(kPrintPaperHeight, height)
&& GETSTRPREF(kPrintPaperName, &str);
@ -544,8 +540,6 @@ nsPrintOptions::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName,
if (success) {
aPS->SetPaperSizeUnit(sizeUnit);
DUMP_INT(kReadStr, kPrintPaperSizeUnit, sizeUnit);
aPS->SetPaperSizeType(sizeType);
DUMP_INT(kReadStr, kPrintPaperSizeType, sizeType);
aPS->SetPaperWidth(width);
DUMP_DBL(kReadStr, kPrintPaperWidth, width);
aPS->SetPaperHeight(height);
@ -777,13 +771,12 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
// Paper size prefs are saved as a group
if (aFlags & nsIPrintSettings::kInitSavePaperSize) {
int16_t sizeUnit, sizeType;
int16_t sizeUnit;
double width, height;
char16_t *name;
if (
NS_SUCCEEDED(aPS->GetPaperSizeUnit(&sizeUnit)) &&
NS_SUCCEEDED(aPS->GetPaperSizeType(&sizeType)) &&
NS_SUCCEEDED(aPS->GetPaperWidth(&width)) &&
NS_SUCCEEDED(aPS->GetPaperHeight(&height)) &&
NS_SUCCEEDED(aPS->GetPaperName(&name))
@ -791,9 +784,6 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
DUMP_INT(kWriteStr, kPrintPaperSizeUnit, sizeUnit);
Preferences::SetInt(GetPrefName(kPrintPaperSizeUnit, aPrinterName),
int32_t(sizeUnit));
DUMP_INT(kWriteStr, kPrintPaperSizeType, sizeType);
Preferences::SetInt(GetPrefName(kPrintPaperSizeType, aPrinterName),
int32_t(sizeType));
DUMP_DBL(kWriteStr, kPrintPaperWidth, width);
WritePrefDouble(GetPrefName(kPrintPaperWidth, aPrinterName), width);
DUMP_DBL(kWriteStr, kPrintPaperHeight, height);
@ -1413,7 +1403,6 @@ Tester::Tester()
ps->SetFooterStrCenter(NS_ConvertUTF8toUTF16("Center").get());
ps->SetFooterStrRight(NS_ConvertUTF8toUTF16("Right").get());
ps->SetPaperName(NS_ConvertUTF8toUTF16("Paper Name").get());
ps->SetPaperSizeType(10);
ps->SetPaperData(1);
ps->SetPaperWidth(100.0);
ps->SetPaperHeight(50.0);

View File

@ -35,7 +35,6 @@ nsPrintSettings::nsPrintSettings() :
mShowPrintProgress(true),
mPrintPageDelay(50),
mPaperData(0),
mPaperSizeType(kPaperSizeDefined),
mPaperWidth(8.5),
mPaperHeight(11.0),
mPaperSizeUnit(kPaperSizeInches),
@ -846,18 +845,6 @@ NS_IMETHODIMP nsPrintSettings::SetPaperSizeUnit(int16_t aPaperSizeUnit)
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::GetPaperSizeType(int16_t *aPaperSizeType)
{
NS_ENSURE_ARG_POINTER(aPaperSizeType);
*aPaperSizeType = mPaperSizeType;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::SetPaperSizeType(int16_t aPaperSizeType)
{
mPaperSizeType = aPaperSizeType;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::GetPaperData(int16_t *aPaperData)
{
NS_ENSURE_ARG_POINTER(aPaperData);
@ -1028,7 +1015,6 @@ nsPrintSettings& nsPrintSettings::operator=(const nsPrintSettings& rhs)
mShrinkToFit = rhs.mShrinkToFit;
mShowPrintProgress = rhs.mShowPrintProgress;
mPaperName = rhs.mPaperName;
mPaperSizeType = rhs.mPaperSizeType;
mPaperData = rhs.mPaperData;
mPaperWidth = rhs.mPaperWidth;
mPaperHeight = rhs.mPaperHeight;

View File

@ -81,7 +81,6 @@ protected:
nsString mPaperName;
int16_t mPaperData;
int16_t mPaperSizeType;
double mPaperWidth;
double mPaperHeight;
int16_t mPaperSizeUnit;

View File

@ -90,63 +90,6 @@ struct AutoFreeGlobalPrinters
}
};
//******************************************************
// Define native paper sizes
//******************************************************
typedef struct {
short mPaperSize; // native enum
double mWidth;
double mHeight;
bool mIsInches;
} NativePaperSizes;
// There are around 40 default print sizes defined by Windows
const NativePaperSizes kPaperSizes[] = {
{DMPAPER_LETTER, 8.5, 11.0, true},
{DMPAPER_LEGAL, 8.5, 14.0, true},
{DMPAPER_A4, 210.0, 297.0, false},
{DMPAPER_B4, 250.0, 354.0, false},
{DMPAPER_B5, 182.0, 257.0, false},
{DMPAPER_TABLOID, 11.0, 17.0, true},
{DMPAPER_LEDGER, 17.0, 11.0, true},
{DMPAPER_STATEMENT, 5.5, 8.5, true},
{DMPAPER_EXECUTIVE, 7.25, 10.5, true},
{DMPAPER_A3, 297.0, 420.0, false},
{DMPAPER_A5, 148.0, 210.0, false},
{DMPAPER_CSHEET, 17.0, 22.0, true},
{DMPAPER_DSHEET, 22.0, 34.0, true},
{DMPAPER_ESHEET, 34.0, 44.0, true},
{DMPAPER_LETTERSMALL, 8.5, 11.0, true},
{DMPAPER_A4SMALL, 210.0, 297.0, false},
{DMPAPER_FOLIO, 8.5, 13.0, true},
{DMPAPER_QUARTO, 215.0, 275.0, false},
{DMPAPER_10X14, 10.0, 14.0, true},
{DMPAPER_11X17, 11.0, 17.0, true},
{DMPAPER_NOTE, 8.5, 11.0, true},
{DMPAPER_ENV_9, 3.875, 8.875, true},
{DMPAPER_ENV_10, 40.125, 9.5, true},
{DMPAPER_ENV_11, 4.5, 10.375, true},
{DMPAPER_ENV_12, 4.75, 11.0, true},
{DMPAPER_ENV_14, 5.0, 11.5, true},
{DMPAPER_ENV_DL, 110.0, 220.0, false},
{DMPAPER_ENV_C5, 162.0, 229.0, false},
{DMPAPER_ENV_C3, 324.0, 458.0, false},
{DMPAPER_ENV_C4, 229.0, 324.0, false},
{DMPAPER_ENV_C6, 114.0, 162.0, false},
{DMPAPER_ENV_C65, 114.0, 229.0, false},
{DMPAPER_ENV_B4, 250.0, 353.0, false},
{DMPAPER_ENV_B5, 176.0, 250.0, false},
{DMPAPER_ENV_B6, 176.0, 125.0, false},
{DMPAPER_ENV_ITALY, 110.0, 230.0, false},
{DMPAPER_ENV_MONARCH, 3.875, 7.5, true},
{DMPAPER_ENV_PERSONAL, 3.625, 6.5, true},
{DMPAPER_FANFOLD_US, 14.875, 11.0, true},
{DMPAPER_FANFOLD_STD_GERMAN, 8.5, 12.0, true},
{DMPAPER_FANFOLD_LGL_GERMAN, 8.5, 13.0, true},
};
const int32_t kNumPaperSizes = 41;
//----------------------------------------------------------------------------------
nsDeviceContextSpecWin::nsDeviceContextSpecWin()
{
@ -373,96 +316,6 @@ nsDeviceContextSpecWin::GetDevMode(LPDEVMODEW &aDevMode)
aDevMode = mDevMode;
}
//----------------------------------------------------------------------------------
// Map an incoming size to a Windows Native enum in the DevMode
static void
MapPaperSizeToNativeEnum(LPDEVMODEW aDevMode,
int16_t aType,
double aW,
double aH)
{
#ifdef DEBUG_rods
BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION;
BOOL doingPaperSize = aDevMode->dmFields & DM_PAPERSIZE;
BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH;
BOOL doingPaperWidth = aDevMode->dmFields & DM_PAPERWIDTH;
#endif
for (int32_t i=0;i<kNumPaperSizes;i++) {
if (kPaperSizes[i].mWidth == aW && kPaperSizes[i].mHeight == aH) {
aDevMode->dmPaperSize = kPaperSizes[i].mPaperSize;
aDevMode->dmFields &= ~DM_PAPERLENGTH;
aDevMode->dmFields &= ~DM_PAPERWIDTH;
aDevMode->dmFields |= DM_PAPERSIZE;
return;
}
}
short width = 0;
short height = 0;
if (aType == nsIPrintSettings::kPaperSizeInches) {
width = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aW))) / 10);
height = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aH))) / 10);
} else if (aType == nsIPrintSettings::kPaperSizeMillimeters) {
width = short(aW / 10.0);
height = short(aH / 10.0);
} else {
return; // don't set anything
}
// width and height is in
aDevMode->dmPaperSize = 0;
aDevMode->dmPaperWidth = width;
aDevMode->dmPaperLength = height;
aDevMode->dmFields |= DM_PAPERSIZE;
aDevMode->dmFields |= DM_PAPERLENGTH;
aDevMode->dmFields |= DM_PAPERWIDTH;
}
//----------------------------------------------------------------------------------
// Setup Paper Size & Orientation options into the DevMode
//
static void
SetupDevModeFromSettings(LPDEVMODEW aDevMode, nsIPrintSettings* aPrintSettings)
{
// Setup paper size
if (aPrintSettings) {
int16_t type;
aPrintSettings->GetPaperSizeType(&type);
if (type == nsIPrintSettings::kPaperSizeNativeData) {
int16_t paperEnum;
aPrintSettings->GetPaperData(&paperEnum);
aDevMode->dmPaperSize = paperEnum;
aDevMode->dmFields &= ~DM_PAPERLENGTH;
aDevMode->dmFields &= ~DM_PAPERWIDTH;
aDevMode->dmFields |= DM_PAPERSIZE;
} else {
int16_t unit;
double width, height;
aPrintSettings->GetPaperSizeUnit(&unit);
aPrintSettings->GetPaperWidth(&width);
aPrintSettings->GetPaperHeight(&height);
MapPaperSizeToNativeEnum(aDevMode, unit, width, height);
}
// Setup Orientation
int32_t orientation;
aPrintSettings->GetOrientation(&orientation);
aDevMode->dmOrientation = orientation == nsIPrintSettings::kPortraitOrientation?DMORIENT_PORTRAIT:DMORIENT_LANDSCAPE;
aDevMode->dmFields |= DM_ORIENTATION;
// Setup Number of Copies
int32_t copies;
aPrintSettings->GetNumCopies(&copies);
aDevMode->dmCopies = copies;
aDevMode->dmFields |= DM_COPIES;
}
}
#define DISPLAY_LAST_ERROR
//----------------------------------------------------------------------------------
@ -501,7 +354,9 @@ nsDeviceContextSpecWin::GetDataFromPrinter(char16ptr_t aName, nsIPrintSettings*
pDevMode, nullptr, DM_OUT_BUFFER);
if (dwRet == IDOK && aPS) {
SetupDevModeFromSettings(pDevMode, aPS);
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
MOZ_ASSERT(psWin);
psWin->CopyToNative(pDevMode);
// Sets back the changes we made to the DevMode into the Printer Driver
dwRet = ::DocumentPropertiesW(nullptr, hPrinter, name,
pDevMode, pDevMode,
@ -532,95 +387,6 @@ nsDeviceContextSpecWin::GetDataFromPrinter(char16ptr_t aName, nsIPrintSettings*
return rv;
}
//----------------------------------------------------------------------------------
// Setup Paper Size options into the DevMode
//
// When using a data member it may be a HGLOCAL or LPDEVMODE
// if it is a HGLOBAL then we need to "lock" it to get the LPDEVMODE
// and unlock it when we are done.
void
nsDeviceContextSpecWin::SetupPaperInfoFromSettings()
{
LPDEVMODEW devMode;
GetDevMode(devMode);
NS_ASSERTION(devMode, "DevMode can't be NULL here");
if (devMode) {
SetupDevModeFromSettings(devMode, mPrintSettings);
}
}
//----------------------------------------------------------------------------------
// Helper Function - Free and reallocate the string
nsresult
nsDeviceContextSpecWin::SetPrintSettingsFromDevMode(nsIPrintSettings* aPrintSettings,
LPDEVMODEW aDevMode)
{
if (aPrintSettings == nullptr) {
return NS_ERROR_FAILURE;
}
aPrintSettings->SetIsInitializedFromPrinter(true);
BOOL doingNumCopies = aDevMode->dmFields & DM_COPIES;
BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION;
BOOL doingPaperSize = aDevMode->dmFields & DM_PAPERSIZE;
BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH;
BOOL doingPaperWidth = aDevMode->dmFields & DM_PAPERWIDTH;
if (doingOrientation) {
int32_t orientation = aDevMode->dmOrientation == DMORIENT_PORTRAIT?
int32_t(nsIPrintSettings::kPortraitOrientation):nsIPrintSettings::kLandscapeOrientation;
aPrintSettings->SetOrientation(orientation);
}
// Setup Number of Copies
if (doingNumCopies) {
aPrintSettings->SetNumCopies(int32_t(aDevMode->dmCopies));
}
if (aDevMode->dmFields & DM_SCALE) {
double scale = double(aDevMode->dmScale) / 100.0f;
if (scale != 1.0) {
aPrintSettings->SetScaling(scale);
aDevMode->dmScale = 100;
// To turn this on you must change where the mPrt->mShrinkToFit is being set in the DocumentViewer
//aPrintSettings->SetShrinkToFit(false);
}
}
if (doingPaperSize) {
aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeNativeData);
aPrintSettings->SetPaperData(aDevMode->dmPaperSize);
for (int32_t i=0;i<kNumPaperSizes;i++) {
if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) {
aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches
?int16_t(nsIPrintSettings::kPaperSizeInches):nsIPrintSettings::kPaperSizeMillimeters);
break;
}
}
} else if (doingPaperLength && doingPaperWidth) {
bool found = false;
for (int32_t i=0;i<kNumPaperSizes;i++) {
if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) {
aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined);
aPrintSettings->SetPaperWidth(kPaperSizes[i].mWidth);
aPrintSettings->SetPaperHeight(kPaperSizes[i].mHeight);
aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches
?int16_t(nsIPrintSettings::kPaperSizeInches):nsIPrintSettings::kPaperSizeMillimeters);
found = true;
break;
}
}
if (!found) {
return NS_ERROR_FAILURE;
}
} else {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
//***********************************************************
// Printer Enumerator
//***********************************************************
@ -676,7 +442,6 @@ nsPrinterEnumeratorWin::InitPrintSettingsFromPrinter(const char16_t *aPrinterNam
}
aPrintSettings->SetPrinterName(aPrinterName);
nsDeviceContextSpecWin::SetPrintSettingsFromDevMode(aPrintSettings, devmode);
// We need to get information from the device as well.
HDC dc = ::CreateICW(kDriverName, aPrinterName, nullptr, devmode);
@ -686,7 +451,7 @@ nsPrinterEnumeratorWin::InitPrintSettingsFromPrinter(const char16_t *aPrinterNam
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPrintSettings);
MOZ_ASSERT(psWin);
psWin->CopyFromNative(dc);
psWin->CopyFromNative(dc, devmode);
::DeleteDC(dc);
return NS_OK;

View File

@ -51,17 +51,12 @@ public:
// helper functions
nsresult GetDataFromPrinter(char16ptr_t aName, nsIPrintSettings* aPS = nullptr);
static nsresult SetPrintSettingsFromDevMode(nsIPrintSettings* aPrintSettings,
LPDEVMODEW aDevMode);
protected:
void SetDeviceName(char16ptr_t aDeviceName);
void SetDriverName(char16ptr_t aDriverName);
void SetDevMode(LPDEVMODEW aDevMode);
void SetupPaperInfoFromSettings();
virtual ~nsDeviceContextSpecWin();
wchar_t* mDriverName;

View File

@ -160,9 +160,50 @@ nsPrintSettingsWin::GetEffectivePageSize(double *aWidth, double *aHeight)
}
void
nsPrintSettingsWin::CopyFromNative(HDC aHdc)
nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode)
{
MOZ_ASSERT(aHdc);
MOZ_ASSERT(aDevMode);
mIsInitedFromPrinter = true;
if (aDevMode->dmFields & DM_ORIENTATION) {
mOrientation = int32_t(aDevMode->dmOrientation == DMORIENT_PORTRAIT
? kPortraitOrientation : kLandscapeOrientation);
}
if (aDevMode->dmFields & DM_COPIES) {
mNumCopies = aDevMode->dmCopies;
}
// 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) {
mPaperData = aDevMode->dmPaperSize;
} else {
mPaperData = -1;
}
// The length and width in DEVMODE are always in tenths of a millimeter, so
// storing them in millimeters is easiest.
mPaperSizeUnit = kPaperSizeMillimeters;
if (aDevMode->dmFields & DM_PAPERLENGTH) {
mPaperHeight = aDevMode->dmPaperLength / 10l;
} else {
mPaperHeight = -1l;
}
if (aDevMode->dmFields & DM_PAPERWIDTH) {
mPaperWidth = aDevMode->dmPaperWidth / 10l;
} else {
mPaperWidth = -1l;
}
// On Windows we currently create a surface using the printable area of the
// page and don't set the unwriteable [sic] margins. Using the unwriteable
@ -187,6 +228,57 @@ nsPrintSettingsWin::CopyFromNative(HDC aHdc)
mResolution = heightDPI;
}
void
nsPrintSettingsWin::CopyToNative(DEVMODEW* aDevMode)
{
MOZ_ASSERT(aDevMode);
if (mPaperData >= 0) {
aDevMode->dmPaperSize = mPaperData;
aDevMode->dmFields |= DM_PAPERSIZE;
} else {
aDevMode->dmPaperSize = 0;
aDevMode->dmFields &= ~DM_PAPERSIZE;
}
double paperHeight;
double paperWidth;
if (mPaperSizeUnit == kPaperSizeMillimeters) {
paperHeight = mPaperHeight;
paperWidth = mPaperWidth;
} else {
paperHeight = mPaperHeight * MM_PER_INCH_FLOAT;
paperWidth = mPaperWidth * MM_PER_INCH_FLOAT;
}
// Set a sensible limit on the minimum height and width.
if (paperHeight >= MM_PER_INCH_FLOAT) {
// In DEVMODEs, physical lengths are stored in tenths of millimeters.
aDevMode->dmPaperLength = paperHeight * 10l;
aDevMode->dmFields |= DM_PAPERLENGTH;
} else {
aDevMode->dmPaperLength = 0;
aDevMode->dmFields &= ~DM_PAPERLENGTH;
}
if (paperWidth >= MM_PER_INCH_FLOAT) {
aDevMode->dmPaperWidth = paperWidth * 10l;
aDevMode->dmFields |= DM_PAPERWIDTH;
} else {
aDevMode->dmPaperWidth = 0;
aDevMode->dmFields &= ~DM_PAPERWIDTH;
}
// Setup Orientation
aDevMode->dmOrientation = mOrientation == kPortraitOrientation
? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
aDevMode->dmFields |= DM_ORIENTATION;
// Setup Number of Copies
aDevMode->dmCopies = mNumCopies;
aDevMode->dmFields |= DM_COPIES;
}
//-------------------------------------------
nsresult
nsPrintSettingsWin::_Clone(nsIPrintSettings **_retval)
@ -277,7 +369,6 @@ Tester::Tester()
ps->SetFooterStrCenter(NS_ConvertUTF8toUTF16("Center").get());
ps->SetFooterStrRight(NS_ConvertUTF8toUTF16("Right").get());
ps->SetPaperName(NS_ConvertUTF8toUTF16("Paper Name").get());
ps->SetPaperSizeType(10);
ps->SetPaperData(1);
ps->SetPaperWidth(100.0);
ps->SetPaperHeight(50.0);
@ -306,5 +397,4 @@ Tester::Tester()
}
Tester gTester;
#endif
#endif