1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsPrintSettingsWin.h"
6 
7 #include "mozilla/ArrayUtils.h"
8 #include "nsCRT.h"
9 
10 // Using paper sizes from wingdi.h and the units given there, plus a little
11 // extra research for the ones it doesn't give. Looks like the list hasn't
12 // changed since Windows 2000, so should be fairly stable now.
13 const short kPaperSizeUnits[] = {
14     nsIPrintSettings::kPaperSizeMillimeters,  // Not Used default to mm as
15                                               // DEVMODE uses tenths of mm, just
16                                               // in case
17     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTER
18     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTERSMALL
19     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_TABLOID
20     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LEDGER
21     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LEGAL
22     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_STATEMENT
23     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_EXECUTIVE
24     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A3
25     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A4
26     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A4SMALL
27     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A5
28     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B4
29     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B5
30     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_FOLIO
31     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_QUARTO
32     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_10X14
33     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_11X17
34     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_NOTE
35     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_9
36     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_10
37     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_11
38     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_12
39     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_14
40     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_CSHEET
41     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_DSHEET
42     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ESHEET
43     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_DL
44     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_C5
45     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_C3
46     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_C4
47     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_C6
48     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_C65
49     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_B4
50     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_B5
51     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_B6
52     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_ITALY
53     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_MONARCH
54     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_ENV_PERSONAL
55     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_FANFOLD_US
56     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_FANFOLD_STD_GERMAN
57     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_FANFOLD_LGL_GERMAN
58     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ISO_B4
59     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JAPANESE_POSTCARD
60     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_9X11
61     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_10X11
62     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_15X11
63     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_ENV_INVITE
64     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_RESERVED_48
65     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_RESERVED_49
66     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTER_EXTRA
67     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LEGAL_EXTRA
68     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_TABLOID_EXTRA
69     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_A4_EXTRA
70     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTER_TRANSVERSE
71     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A4_TRANSVERSE
72     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTER_EXTRA_TRANSVERSE
73     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A_PLUS
74     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B_PLUS
75     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTER_PLUS
76     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A4_PLUS
77     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A5_TRANSVERSE
78     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B5_TRANSVERSE
79     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A3_EXTRA
80     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A5_EXTRA
81     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B5_EXTRA
82     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A2
83     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A3_TRANSVERSE
84     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A3_EXTRA_TRANSVERSE
85     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_DBL_JAPANESE_POSTCARD
86     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A6
87     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_KAKU2
88     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_KAKU3
89     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_CHOU3
90     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_CHOU4
91     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_LETTER_ROTATED
92     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A3_ROTATED
93     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A4_ROTATED
94     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A5_ROTATED
95     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B4_JIS_ROTATED
96     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B5_JIS_ROTATED
97     nsIPrintSettings::
98         kPaperSizeMillimeters,  // DMPAPER_JAPANESE_POSTCARD_ROTATED
99     nsIPrintSettings::
100         kPaperSizeMillimeters,  // DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED
101     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_A6_ROTATED
102     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_KAKU2_ROTATED
103     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_KAKU3_ROTATED
104     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_CHOU3_ROTATED
105     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_CHOU4_ROTATED
106     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B6_JIS
107     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_B6_JIS_ROTATED
108     nsIPrintSettings::kPaperSizeInches,       // DMPAPER_12X11
109     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_YOU4
110     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_JENV_YOU4_ROTATED
111     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_P16K
112     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_P32K
113     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_P32KBIG
114     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_1
115     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_2
116     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_3
117     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_4
118     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_5
119     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_6
120     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_7
121     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_8
122     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_9
123     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_10
124     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_P16K_ROTATED
125     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_P32K_ROTATED
126     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_P32KBIG_ROTATED
127     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_1_ROTATED
128     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_2_ROTATED
129     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_3_ROTATED
130     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_4_ROTATED
131     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_5_ROTATED
132     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_6_ROTATED
133     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_7_ROTATED
134     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_8_ROTATED
135     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_9_ROTATED
136     nsIPrintSettings::kPaperSizeMillimeters,  // DMPAPER_PENV_10_ROTATED
137 };
138 
NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsWin,nsPrintSettings,nsIPrintSettingsWin)139 NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsWin, nsPrintSettings,
140                             nsIPrintSettingsWin)
141 
142 /** ---------------------------------------------------
143  *  See documentation in nsPrintSettingsWin.h
144  *	@update
145  */
146 nsPrintSettingsWin::nsPrintSettingsWin()
147     : nsPrintSettings(),
148       mDeviceName(nullptr),
149       mDriverName(nullptr),
150       mDevMode(nullptr) {}
151 
152 /** ---------------------------------------------------
153  *  See documentation in nsPrintSettingsWin.h
154  *	@update
155  */
nsPrintSettingsWin(const nsPrintSettingsWin & aPS)156 nsPrintSettingsWin::nsPrintSettingsWin(const nsPrintSettingsWin& aPS)
157     : mDevMode(nullptr) {
158   *this = aPS;
159 }
160 
161 /** ---------------------------------------------------
162  *  See documentation in nsPrintSettingsWin.h
163  *	@update
164  */
~nsPrintSettingsWin()165 nsPrintSettingsWin::~nsPrintSettingsWin() {
166   if (mDevMode) ::HeapFree(::GetProcessHeap(), 0, mDevMode);
167 }
168 
SetDeviceName(const nsAString & aDeviceName)169 NS_IMETHODIMP nsPrintSettingsWin::SetDeviceName(const nsAString& aDeviceName) {
170   mDeviceName = aDeviceName;
171   return NS_OK;
172 }
GetDeviceName(nsAString & aDeviceName)173 NS_IMETHODIMP nsPrintSettingsWin::GetDeviceName(nsAString& aDeviceName) {
174   aDeviceName = mDeviceName;
175   return NS_OK;
176 }
177 
SetDriverName(const nsAString & aDriverName)178 NS_IMETHODIMP nsPrintSettingsWin::SetDriverName(const nsAString& aDriverName) {
179   mDriverName = aDriverName;
180   return NS_OK;
181 }
GetDriverName(nsAString & aDriverName)182 NS_IMETHODIMP nsPrintSettingsWin::GetDriverName(nsAString& aDriverName) {
183   aDriverName = mDriverName;
184   return NS_OK;
185 }
186 
CopyDevMode(DEVMODEW * aInDevMode,DEVMODEW * & aOutDevMode)187 void nsPrintSettingsWin::CopyDevMode(DEVMODEW* aInDevMode,
188                                      DEVMODEW*& aOutDevMode) {
189   aOutDevMode = nullptr;
190   size_t size = aInDevMode->dmSize + aInDevMode->dmDriverExtra;
191   aOutDevMode =
192       (LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, size);
193   if (aOutDevMode) {
194     memcpy(aOutDevMode, aInDevMode, size);
195   }
196 }
197 
GetDevMode(DEVMODEW ** aDevMode)198 NS_IMETHODIMP nsPrintSettingsWin::GetDevMode(DEVMODEW** aDevMode) {
199   NS_ENSURE_ARG_POINTER(aDevMode);
200 
201   if (mDevMode) {
202     CopyDevMode(mDevMode, *aDevMode);
203   } else {
204     *aDevMode = nullptr;
205   }
206   return NS_OK;
207 }
208 
SetDevMode(DEVMODEW * aDevMode)209 NS_IMETHODIMP nsPrintSettingsWin::SetDevMode(DEVMODEW* aDevMode) {
210   if (mDevMode) {
211     ::HeapFree(::GetProcessHeap(), 0, mDevMode);
212     mDevMode = nullptr;
213   }
214 
215   if (aDevMode) {
216     CopyDevMode(aDevMode, mDevMode);
217   }
218   return NS_OK;
219 }
220 
221 NS_IMETHODIMP
GetPrintableWidthInInches(double * aPrintableWidthInInches)222 nsPrintSettingsWin::GetPrintableWidthInInches(double* aPrintableWidthInInches) {
223   MOZ_ASSERT(aPrintableWidthInInches);
224   *aPrintableWidthInInches = mPrintableWidthInInches;
225   return NS_OK;
226 }
227 
228 NS_IMETHODIMP
SetPrintableWidthInInches(double aPrintableWidthInInches)229 nsPrintSettingsWin::SetPrintableWidthInInches(double aPrintableWidthInInches) {
230   mPrintableWidthInInches = aPrintableWidthInInches;
231   return NS_OK;
232 }
233 
234 NS_IMETHODIMP
GetPrintableHeightInInches(double * aPrintableHeightInInches)235 nsPrintSettingsWin::GetPrintableHeightInInches(
236     double* aPrintableHeightInInches) {
237   MOZ_ASSERT(aPrintableHeightInInches);
238   *aPrintableHeightInInches = mPrintableHeightInInches;
239   return NS_OK;
240 }
241 
242 NS_IMETHODIMP
SetPrintableHeightInInches(double aPrintableHeightInInches)243 nsPrintSettingsWin::SetPrintableHeightInInches(
244     double aPrintableHeightInInches) {
245   mPrintableHeightInInches = aPrintableHeightInInches;
246   return NS_OK;
247 }
248 
249 NS_IMETHODIMP
GetEffectivePageSize(double * aWidth,double * aHeight)250 nsPrintSettingsWin::GetEffectivePageSize(double* aWidth, double* aHeight) {
251   // If printable page size not set, fall back to nsPrintSettings.
252   if (mPrintableWidthInInches == 0l || mPrintableHeightInInches == 0l) {
253     return nsPrintSettings::GetEffectivePageSize(aWidth, aHeight);
254   }
255 
256   if (mOrientation == kPortraitOrientation) {
257     *aWidth = NS_INCHES_TO_TWIPS(mPrintableWidthInInches);
258     *aHeight = NS_INCHES_TO_TWIPS(mPrintableHeightInInches);
259   } else {
260     *aHeight = NS_INCHES_TO_TWIPS(mPrintableWidthInInches);
261     *aWidth = NS_INCHES_TO_TWIPS(mPrintableHeightInInches);
262   }
263   return NS_OK;
264 }
265 
CopyFromNative(HDC aHdc,DEVMODEW * aDevMode)266 void nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode) {
267   MOZ_ASSERT(aHdc);
268   MOZ_ASSERT(aDevMode);
269 
270   mIsInitedFromPrinter = true;
271   if (aDevMode->dmFields & DM_ORIENTATION) {
272     mOrientation = int32_t(aDevMode->dmOrientation == DMORIENT_PORTRAIT
273                                ? kPortraitOrientation
274                                : kLandscapeOrientation);
275   }
276 
277   if (aDevMode->dmFields & DM_COPIES) {
278     mNumCopies = aDevMode->dmCopies;
279   }
280 
281   // Since we do the scaling, grab their value and reset back to 100.
282   if (aDevMode->dmFields & DM_SCALE) {
283     double scale = double(aDevMode->dmScale) / 100.0f;
284     if (mScaling == 1.0 || scale != 1.0) {
285       mScaling = scale;
286     }
287     aDevMode->dmScale = 100;
288   }
289 
290   if (aDevMode->dmFields & DM_PAPERSIZE) {
291     mPaperData = aDevMode->dmPaperSize;
292     // If not a paper size we know about, the unit will be the last one saved.
293     if (mPaperData > 0 &&
294         mPaperData < int32_t(mozilla::ArrayLength(kPaperSizeUnits))) {
295       mPaperSizeUnit = kPaperSizeUnits[mPaperData];
296     }
297   } else {
298     mPaperData = -1;
299   }
300 
301   // The length and width in DEVMODE are always in tenths of a millimeter.
302   double sizeUnitToTenthsOfAmm =
303       10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L);
304   if (aDevMode->dmFields & DM_PAPERLENGTH) {
305     mPaperHeight = aDevMode->dmPaperLength / sizeUnitToTenthsOfAmm;
306   } else {
307     mPaperHeight = -1l;
308   }
309 
310   if (aDevMode->dmFields & DM_PAPERWIDTH) {
311     mPaperWidth = aDevMode->dmPaperWidth / sizeUnitToTenthsOfAmm;
312   } else {
313     mPaperWidth = -1l;
314   }
315 
316   // On Windows we currently create a surface using the printable area of the
317   // page and don't set the unwriteable [sic] margins. Using the unwriteable
318   // margins doesn't appear to work on Windows, but I am not sure if this is a
319   // bug elsewhere in our code or a Windows quirk.
320   // Note: we only scale the printing using the LOGPIXELSY, so we use that
321   // when calculating the surface width as well as the height.
322   int32_t printableWidthInDots = GetDeviceCaps(aHdc, HORZRES);
323   int32_t printableHeightInDots = GetDeviceCaps(aHdc, VERTRES);
324   int32_t heightDPI = GetDeviceCaps(aHdc, LOGPIXELSY);
325 
326   // Keep these values in portrait format, so we can reflect our own changes
327   // to mOrientation.
328   if (mOrientation == kPortraitOrientation) {
329     mPrintableWidthInInches = double(printableWidthInDots) / heightDPI;
330     mPrintableHeightInInches = double(printableHeightInDots) / heightDPI;
331   } else {
332     mPrintableHeightInInches = double(printableWidthInDots) / heightDPI;
333     mPrintableWidthInInches = double(printableHeightInDots) / heightDPI;
334   }
335 
336   // Using Y to match existing code for print scaling calculations.
337   mResolution = heightDPI;
338 }
339 
CopyToNative(DEVMODEW * aDevMode)340 void nsPrintSettingsWin::CopyToNative(DEVMODEW* aDevMode) {
341   MOZ_ASSERT(aDevMode);
342 
343   if (mPaperData >= 0) {
344     aDevMode->dmPaperSize = mPaperData;
345     aDevMode->dmFields |= DM_PAPERSIZE;
346   } else {
347     aDevMode->dmPaperSize = 0;
348     aDevMode->dmFields &= ~DM_PAPERSIZE;
349   }
350 
351   // The length and width in DEVMODE are always in tenths of a millimeter.
352   double sizeUnitToTenthsOfAmm =
353       10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L);
354 
355   // Note: small page sizes can be required here for sticker, label and slide
356   // printers etc. see bug 1271900.
357   if (mPaperHeight > 0) {
358     aDevMode->dmPaperLength = mPaperHeight * sizeUnitToTenthsOfAmm;
359     aDevMode->dmFields |= DM_PAPERLENGTH;
360   } else {
361     aDevMode->dmPaperLength = 0;
362     aDevMode->dmFields &= ~DM_PAPERLENGTH;
363   }
364 
365   if (mPaperWidth > 0) {
366     aDevMode->dmPaperWidth = mPaperWidth * sizeUnitToTenthsOfAmm;
367     aDevMode->dmFields |= DM_PAPERWIDTH;
368   } else {
369     aDevMode->dmPaperWidth = 0;
370     aDevMode->dmFields &= ~DM_PAPERWIDTH;
371   }
372 
373   // Setup Orientation
374   aDevMode->dmOrientation = mOrientation == kPortraitOrientation
375                                 ? DMORIENT_PORTRAIT
376                                 : DMORIENT_LANDSCAPE;
377   aDevMode->dmFields |= DM_ORIENTATION;
378 
379   // Setup Number of Copies
380   aDevMode->dmCopies = mNumCopies;
381   aDevMode->dmFields |= DM_COPIES;
382 }
383 
384 //-------------------------------------------
_Clone(nsIPrintSettings ** _retval)385 nsresult nsPrintSettingsWin::_Clone(nsIPrintSettings** _retval) {
386   RefPtr<nsPrintSettingsWin> printSettings = new nsPrintSettingsWin(*this);
387   printSettings.forget(_retval);
388   return NS_OK;
389 }
390 
391 //-------------------------------------------
operator =(const nsPrintSettingsWin & rhs)392 nsPrintSettingsWin& nsPrintSettingsWin::operator=(
393     const nsPrintSettingsWin& rhs) {
394   if (this == &rhs) {
395     return *this;
396   }
397 
398   ((nsPrintSettings&)*this) = rhs;
399 
400   // Use free because we used the native malloc to create the memory
401   if (mDevMode) {
402     ::HeapFree(::GetProcessHeap(), 0, mDevMode);
403   }
404 
405   mDeviceName = rhs.mDeviceName;
406   mDriverName = rhs.mDriverName;
407 
408   if (rhs.mDevMode) {
409     CopyDevMode(rhs.mDevMode, mDevMode);
410   } else {
411     mDevMode = nullptr;
412   }
413 
414   return *this;
415 }
416 
417 //-------------------------------------------
_Assign(nsIPrintSettings * aPS)418 nsresult nsPrintSettingsWin::_Assign(nsIPrintSettings* aPS) {
419   nsPrintSettingsWin* psWin = static_cast<nsPrintSettingsWin*>(aPS);
420   *this = *psWin;
421   return NS_OK;
422 }
423 
424 //----------------------------------------------------------------------
425 // Testing of assign and clone
426 // This define turns on the testing module below
427 // so at start up it writes and reads the prefs.
428 #ifdef DEBUG_rodsX
429 #include "nsIPrintSettingsService.h"
430 #include "nsIServiceManager.h"
431 class Tester {
432  public:
433   Tester();
434 };
Tester()435 Tester::Tester() {
436   nsCOMPtr<nsIPrintSettings> ps;
437   nsresult rv;
438   nsCOMPtr<nsIPrintSettingsService> printService =
439       do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
440   if (NS_SUCCEEDED(rv)) {
441     rv = printService->CreatePrintSettings(getter_AddRefs(ps));
442   }
443 
444   if (ps) {
445     ps->SetPrintOptions(nsIPrintSettings::kPrintOddPages, true);
446     ps->SetPrintOptions(nsIPrintSettings::kPrintEvenPages, false);
447     ps->SetMarginTop(1.0);
448     ps->SetMarginLeft(1.0);
449     ps->SetMarginBottom(1.0);
450     ps->SetMarginRight(1.0);
451     ps->SetScaling(0.5);
452     ps->SetPrintBGColors(true);
453     ps->SetPrintBGImages(true);
454     ps->SetPrintRange(15);
455     ps->SetHeaderStrLeft(NS_ConvertUTF8toUTF16("Left").get());
456     ps->SetHeaderStrCenter(NS_ConvertUTF8toUTF16("Center").get());
457     ps->SetHeaderStrRight(NS_ConvertUTF8toUTF16("Right").get());
458     ps->SetFooterStrLeft(NS_ConvertUTF8toUTF16("Left").get());
459     ps->SetFooterStrCenter(NS_ConvertUTF8toUTF16("Center").get());
460     ps->SetFooterStrRight(NS_ConvertUTF8toUTF16("Right").get());
461     ps->SetPaperName(NS_ConvertUTF8toUTF16("Paper Name").get());
462     ps->SetPaperData(1);
463     ps->SetPaperWidth(100.0);
464     ps->SetPaperHeight(50.0);
465     ps->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
466     ps->SetPrintReversed(true);
467     ps->SetPrintInColor(true);
468     ps->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
469     ps->SetPrintCommand(NS_ConvertUTF8toUTF16("Command").get());
470     ps->SetNumCopies(2);
471     ps->SetPrinterName(NS_ConvertUTF8toUTF16("Printer Name").get());
472     ps->SetPrintToFile(true);
473     ps->SetToFileName(NS_ConvertUTF8toUTF16("File Name").get());
474     ps->SetPrintPageDelay(1000);
475 
476     nsCOMPtr<nsIPrintSettings> ps2;
477     if (NS_SUCCEEDED(rv)) {
478       rv = printService->CreatePrintSettings(getter_AddRefs(ps2));
479     }
480 
481     ps2->Assign(ps);
482 
483     nsCOMPtr<nsIPrintSettings> psClone;
484     ps2->Clone(getter_AddRefs(psClone));
485   }
486 }
487 Tester gTester;
488 #endif
489