Bug 1280159: Let paper type drive page size units on Windows. r?jimm draft
authorBob Owen <bobowencode@gmail.com>
Thu, 30 Jun 2016 10:01:10 +0100
changeset 382744 761d55a70127df480372efe4ef5511e7cf477a41
parent 381966 e45890951ce77c3df05575bd54072b9f300d77b0
child 524282 8cb92f27d9acac2d08656f2e368073c1f82cfcc7
push id21817
push userbobowencode@gmail.com
push dateThu, 30 Jun 2016 09:01:29 +0000
reviewersjimm
bugs1280159
milestone50.0a1
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