Bug 1280159: Let paper type drive page size units on Windows. r=jimm
authorBob Owen <bobowencode@gmail.com>
Thu, 30 Jun 2016 10:01:10 +0100
changeset 303492 a4999a2b771d06451ace2ed67447f336b8d42c84
parent 303491 c61101c15a280b078071fd130eba2dd5079d69c2
child 303493 511ae2ae8db693ef4799d68cd152283345eadf18
push id30410
push userbobowencode@gmail.com
push dateSun, 03 Jul 2016 08:45:44 +0000
treeherderautoland@a4999a2b771d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1280159
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1280159: Let paper type drive page size units on Windows. r=jimm Also, changed the other paper size conversion code to be similar, as I think it is easier to follow. MozReview-Commit-ID: 2PzzxevnQSz
widget/windows/nsPrintSettingsWin.cpp
--- a/widget/windows/nsPrintSettingsWin.cpp
+++ b/widget/windows/nsPrintSettingsWin.cpp
@@ -1,15 +1,143 @@
 /* -*- 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"
 
+// 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 
  */
@@ -181,31 +309,36 @@ nsPrintSettingsWin::CopyFromNative(HDC a
     if (mScaling == 1.0 || scale != 1.0) {
       mScaling = scale;
     }
     aDevMode->dmScale = 100;
   }
 
   if (aDevMode->dmFields & DM_PAPERSIZE) {
     mPaperData = aDevMode->dmPaperSize;
+    // If not a paper size we know about, the unit will be the last one saved.
+    if (mPaperData > 0 &&
+        mPaperData < int32_t(mozilla::ArrayLength(kPaperSizeUnits))) {
+      mPaperSizeUnit = kPaperSizeUnits[mPaperData];
+    }
   } 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;
+  // 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 / 10l;
+    mPaperHeight = aDevMode->dmPaperLength / sizeUnitToTenthsOfAmm;
   } else {
     mPaperHeight = -1l;
   }
 
   if (aDevMode->dmFields & DM_PAPERWIDTH) {
-    mPaperWidth = aDevMode->dmPaperWidth / 10l;
+    mPaperWidth = aDevMode->dmPaperWidth / sizeUnitToTenthsOfAmm;
   } 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
   // margins doesn't appear to work on Windows, but I am not sure if this is a
   // bug elsewhere in our code or a Windows quirk.
@@ -237,39 +370,32 @@ nsPrintSettingsWin::CopyToNative(DEVMODE
   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;
-  }
+  // The length and width in DEVMODE are always in tenths of a millimeter.
+  double sizeUnitToTenthsOfAmm =
+    10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L);
 
   // Note: small page sizes can be required here for sticker, label and slide
   // printers etc. see bug 1271900.
-  if (paperHeight > 0) {
-    // In DEVMODEs, physical lengths are stored in tenths of millimeters.
-    aDevMode->dmPaperLength = paperHeight * 10l;
+  if (mPaperHeight > 0) {
+    aDevMode->dmPaperLength = mPaperHeight * sizeUnitToTenthsOfAmm;
     aDevMode->dmFields |= DM_PAPERLENGTH;
   } else {
     aDevMode->dmPaperLength = 0;
     aDevMode->dmFields &= ~DM_PAPERLENGTH;
   }
 
-  if (paperWidth > 0) {
-    aDevMode->dmPaperWidth = paperWidth * 10l;
+  if (mPaperWidth > 0) {
+    aDevMode->dmPaperWidth = mPaperWidth * sizeUnitToTenthsOfAmm;
     aDevMode->dmFields |= DM_PAPERWIDTH;
   } else {
     aDevMode->dmPaperWidth = 0;
     aDevMode->dmFields &= ~DM_PAPERWIDTH;
   }
 
   // Setup Orientation
   aDevMode->dmOrientation = mOrientation == kPortraitOrientation