Logoj0ke.net Open Build Service > Projects > mozilla > MozillaThunderbird > cups-paper.patch
Sign Up | Log In

File cups-paper.patch of Package MozillaThunderbird (Revision 5203d2e3dfb8f690164f48661b2cc8c4)

Currently displaying revision 5203d2e3dfb8f690164f48661b2cc8c4, show latest

 
1
From: Wolfgang Rosenauer <stark@suse.de>, Arne John Glenstrup <panic@itu.dk>
2
Subject: get paper sizes from CUPS
3
References:
4
https://bugzilla.novell.com/show_bug.cgi?id=65482
5
https://bugzilla.mozilla.org/show_bug.cgi?id=324060
6
7
8
================================================================================
9
--- gfx/src/gtk/nsDeviceContextSpecG.cpp
10
+++ gfx/src/gtk/nsDeviceContextSpecG.cpp
11
@@ -66,6 +66,7 @@
12
 #ifdef USE_POSTSCRIPT
13
 #include "nsPSPrinters.h"
14
 #include "nsPaperPS.h"  /* Paper size list */
15
+#include "nsPaperFactoryPS.h"  /* Paper size list factory */
16
 #endif /* USE_POSTSCRIPT */
17
 
18
 /* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
19
@@ -1210,34 +1211,38 @@
20
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
21
     printerFeatures.SetCanChangePaperSize(PR_TRUE);
22
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
23
-    nsXPIDLCString papername;
24
-    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
25
-      nsPaperSizePS paper;
26
-
27
-      if (paper.Find(papername)) {
28
-        DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
29
-              paper.Name(), paper.Width_mm(), paper.Height_mm()));
30
-        aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ?
31
-            (int)nsIPrintSettings::kPaperSizeMillimeters :
32
-            (int)nsIPrintSettings::kPaperSizeInches);
33
-        aPrintSettings->SetPaperWidth(paper.Width_mm());
34
-        aPrintSettings->SetPaperHeight(paper.Height_mm());
35
-        aPrintSettings->SetPaperName(NS_ConvertASCIItoUCS2(paper.Name()).get());
36
-      }
37
-      else {
38
-        DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
39
+    {
40
+      nsIPaperSizePS* paper;
41
+      nsresult rv;
42
+      rv = nsPaperFactoryPS::CreatePaper
43
+        (fullPrinterName.get(), printerName.get(), paper);
44
+      if (NS_FAILED(rv)) return rv;
45
+      paper->FindDefault();
46
+
47
+      nsXPIDLCString papername;
48
+      if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", fullPrinterName, "print_paper_name", getter_Copies(papername)))) {
49
+        if (!paper->Find(papername)) {
50
+          DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
51
+        }
52
       }
53
+      DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
54
+              paper->Name(), paper->Width_mm(), paper->Height_mm()));
55
+      aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
56
+      aPrintSettings->SetPaperWidth(paper->Width_mm());
57
+      aPrintSettings->SetPaperHeight(paper->Height_mm());
58
+      aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper->Name()).get());
59
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
60
-      paper.First();
61
+      paper->First();
62
       int count = 0;
63
-      while (!paper.AtEnd())
64
+      while (!paper->AtEnd())
65
       {
66
-        printerFeatures.SetPaperRecord(count++, paper.Name(),
67
-            (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
68
-        paper.Next();
69
+        printerFeatures.SetPaperRecord(count++, paper->Name(),
70
+            (int)paper->Width_mm(), (int)paper->Height_mm(), !paper->IsMetric());
71
+        paper->Next();
72
       }
73
       printerFeatures.SetNumPaperSizeRecords(count);
74
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
75
+      delete(paper);
76
     }
77
 
78
     PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
79
--- gfx/src/ps/nsPrintJobPS.cpp
80
+++ gfx/src/ps/nsPrintJobPS.cpp
81
@@ -364,6 +364,10 @@
82
     const char *slash = strchr(printerName, '/');
83
     mPrinterName = slash ? slash + 1 : printerName;
84
     mJobTitle.SetIsVoid(PR_TRUE);
85
+    /* Paper name */
86
+    const char* paperName = nsnull;
87
+    aSpec->GetPaperName(&paperName);
88
+    mPaperName = paperName;
89
     return NS_OK;
90
 }
91
 
92
@@ -445,6 +449,11 @@
93
                                                        mNumCopies.get(),
94
                                                        dest->num_options,
95
                                                        &dest->options);
96
+        if (!mPaperName.IsEmpty())
97
+            dest->num_options = (mCups.mCupsAddOption)("media",
98
+                                                       mPaperName.get(),
99
+                                                       dest->num_options,
100
+                                                       &dest->options);
101
         const char *title = mJobTitle.IsVoid() ?
102
             "Untitled Document" : mJobTitle.get();
103
         result = (mCups.mCupsPrintFile)(printer.CStringAt(0)->get(),
104
--- gfx/src/ps/nsPrintJobPS.h
105
+++ gfx/src/ps/nsPrintJobPS.h
106
@@ -179,6 +179,7 @@
107
         nsCUPSShim mCups;
108
         nsCString mPrinterName;
109
         nsCString mNumCopies;
110
+        nsCString mPaperName;
111
         nsCString mJobTitle;        // IsVoid() if no title
112
 };
113
 #endif  /* VMS */
114
--- gfx/src/psshared/Makefile.in
115
+++ gfx/src/psshared/Makefile.in
116
@@ -57,13 +57,16 @@
117
 
118
 EXPORTS        = nsCUPSShim.h \
119
          nsPaperPS.h \
120
+         nsIPaperPS.h \
121
          nsPSPrinters.h\
122
          psSharedCore.h \
123
+         nsPaperFactoryPS.h \
124
          $(NULL)
125
 
126
 CPPSRCS        = nsCUPSShim.cpp \
127
          nsPaperPS.cpp \
128
          nsPSPrinters.cpp \
129
+         nsPaperFactoryPS.cpp \
130
          $(NULL)
131
 
132
 EXTRA_DSO_LDOPTS = \
133
--- gfx/src/psshared/nsCUPSShim.cpp
134
+++ gfx/src/psshared/nsCUPSShim.cpp
135
@@ -45,13 +45,18 @@
136
 // List of symbols to find in libcups. Must match symAddr[] defined in Init().
137
 // Making this an array of arrays instead of pointers allows storing the
138
 // whole thing in read-only memory.
139
-static const char gSymName[][sizeof("cupsPrintFile")] = {
140
+static const char gSymName[][sizeof("ppdMarkDefaults")] = {
141
     { "cupsAddOption" },
142
     { "cupsFreeDests" },
143
     { "cupsGetDest" },
144
     { "cupsGetDests" },
145
     { "cupsPrintFile" },
146
     { "cupsTempFd" },
147
+    { "cupsGetPPD" },
148
+    { "ppdOpenFile" },
149
+    { "ppdClose" },
150
+    { "ppdMarkDefaults" },
151
+    { "ppdIsMarked" },
152
 };
153
 static const int gSymNameCt = sizeof(gSymName) / sizeof(gSymName[0]);
154
 
155
@@ -71,6 +76,11 @@
156
         (void **)&mCupsGetDests,
157
         (void **)&mCupsPrintFile,
158
         (void **)&mCupsTempFd,
159
+        (void **)&mCupsGetPPD,
160
+        (void **)&mPpdOpenFile,
161
+        (void **)&mPpdClose,
162
+        (void **)&mPpdMarkDefaults,
163
+        (void **)&mPpdIsMarked,
164
     };
165
 
166
     for (int i = gSymNameCt; i--; ) {
167
--- gfx/src/psshared/nsCUPSShim.h
168
+++ gfx/src/psshared/nsCUPSShim.h
169
@@ -62,6 +62,82 @@
170
     cups_option_t *options;    /* Options */
171
 } cups_dest_t;
172
 
173
+typedef enum           /**** Colorspaces ****/
174
+{
175
+  PPD_CS_CMYK = -4,        /* CMYK colorspace */
176
+  PPD_CS_CMY,          /* CMY colorspace */
177
+  PPD_CS_GRAY = 1,     /* Grayscale colorspace */
178
+  PPD_CS_RGB = 3,      /* RGB colorspace */
179
+  PPD_CS_RGBK,         /* RGBK (K = gray) colorspace */
180
+  PPD_CS_N             /* DeviceN colorspace */
181
+} ppd_cs_t;
182
+
183
+typedef struct          /**** Page Sizes ****/
184
+{
185
+    int         marked;     /* Page size selected? */
186
+    char        name[41];
187
+    /* Media size option */
188
+    float       width,      /* Width of media in points */
189
+                length,     /* Length of media in points */
190
+                left,       /* Left printable margin in points */
191
+                bottom,     /* Bottom printable margin in points */
192
+                right,      /* Right printable margin in points */
193
+                top;        /* Top printable margin in points */
194
+} ppd_size_t;
195
+
196
+typedef struct         /**** Files ****/
197
+{
198
+    int         language_level,   /* Language level of device */
199
+                color_device,     /* 1 = color device, 0 = grayscale */
200
+                variable_sizes,   /* 1 = supports variable sizes, 0 = doesn't */
201
+                accurate_screens, /* 1 = supports accurate screens, 0 = not */
202
+                contone_only,     /* 1 = continuous tone only, 0 = not */
203
+                landscape,        /* -90 or 90 */
204
+                model_number,     /* Device-specific model number */
205
+                manual_copies,    /* 1 = Copies done manually, 0 = hardware */
206
+                throughput;       /* Pages per minute */
207
+    ppd_cs_t    colorspace;       /* Default colorspace */
208
+    char        *patches;         /* Patch commands to be sent to printer */
209
+    int         num_emulations;   /* Number of emulations supported */
210
+    void        *emulations;      /* Emulations and the code to invoke them */
211
+    char        *jcl_begin,       /* Start JCL commands */
212
+                *jcl_ps,          /* Enter PostScript interpreter */
213
+                *jcl_end,         /* End JCL commands */
214
+                *lang_encoding,   /* Language encoding */
215
+                *lang_version,    /* Language version (English, Spanish, etc.) */
216
+                *modelname,       /* Model name (general) */
217
+                *ttrasterizer,    /* Truetype rasterizer */
218
+                *manufacturer,    /* Manufacturer name */
219
+                *product,         /* Product name (from PS RIP/interpreter) */
220
+                *nickname,        /* Nickname (specific) */
221
+                *shortnickname;   /* Short version of nickname */
222
+    int         num_groups;       /* Number of UI groups */
223
+    void        *groups;          /* UI groups */
224
+    int         num_sizes;        /* Number of page sizes */
225
+    ppd_size_t  *sizes;           /* Page sizes */
226
+    float       custom_min[2],    /* Minimum variable page size */
227
+                custom_max[2],    /* Maximum variable page size */
228
+                custom_margins[4];/* Margins around page */
229
+    int         num_consts;       /* Number of UI/Non-UI constraints */
230
+    void        *consts;          /* UI/Non-UI constraints */
231
+    int         num_fonts;        /* Number of pre-loaded fonts */
232
+    char        **fonts;          /* Pre-loaded fonts */
233
+    int         num_profiles;     /* Number of sRGB color profiles */
234
+    void        *profiles;    /* sRGB color profiles */
235
+    int         num_filters;      /* Number of filters */
236
+    char        **filters;        /* Filter strings... */
237
+
238
+    /**** New in CUPS 1.1 ****/
239
+    int         flip_duplex;      /* 1 = Flip page for back sides */
240
+    
241
+    /**** New in CUPS 1.1.19 ****/
242
+    char        *protocols,       /* Protocols (BCP, TBCP) string */
243
+                *pcfilename;      /* PCFileName string */
244
+    int         num_attrs,        /* Number of attributes */
245
+                cur_attr;         /* Current attribute */
246
+    void        **attrs;          /* Attributes */
247
+} ppd_file_t;
248
+
249
 typedef cups_dest_t* (PR_CALLBACK *CupsGetDestType)(const char *printer,
250
                                                     const char *instance,
251
                                                     int num_dests, 
252
@@ -80,6 +156,11 @@
253
                                              const char    *value,
254
                                              int           num_options,
255
                                              cups_option_t **options);
256
+typedef const char* (PR_CALLBACK *CupsGetPPDType) (const char* name);
257
+typedef ppd_file_t* (PR_CALLBACK *PPDOpenFileType) (const char* filename);
258
+typedef void (PR_CALLBACK *PPDCloseType) (ppd_file_t* ppd);
259
+typedef void (PR_CALLBACK *PPDMarkDefaultsType) (ppd_file_t* ppd);
260
+typedef int (PR_CALLBACK *PPDIsMarkedType) (ppd_file_t* ppd, const char* pname, const char* pname_clear);
261
 
262
 struct PRLibrary;
263
 
264
@@ -113,6 +194,11 @@
265
         CupsGetDestsType    mCupsGetDests;
266
         CupsPrintFileType   mCupsPrintFile;
267
         CupsTempFdType      mCupsTempFd;
268
+        CupsGetPPDType      mCupsGetPPD;
269
+        PPDOpenFileType     mPpdOpenFile;
270
+        PPDCloseType        mPpdClose;
271
+        PPDMarkDefaultsType mPpdMarkDefaults;
272
+        PPDIsMarkedType     mPpdIsMarked;
273
 
274
     private:
275
         PRLibrary *mCupsLib;
276
--- gfx/src/psshared/nsIPaperPS.h
277
+++ gfx/src/psshared/nsIPaperPS.h
278
@@ -0,0 +1,102 @@
279
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
280
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
281
+/* ***** BEGIN LICENSE BLOCK *****
282
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
283
+ *
284
+ * The contents of this file are subject to the Mozilla Public License Version
285
+ * 1.1 (the "License"); you may not use this file except in compliance with
286
+ * the License. You may obtain a copy of the License at
287
+ * http://www.mozilla.org/MPL/
288
+ *
289
+ * Software distributed under the License is distributed on an "AS IS" basis,
290
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
291
+ * for the specific language governing rights and limitations under the
292
+ * License.
293
+ *
294
+ * Contributor(s):
295
+ *   Arne John Glenstrup <panic@itu.dk>
296
+ *
297
+ * Alternatively, the contents of this file may be used under the terms of
298
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
299
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
300
+ * in which case the provisions of the GPL or the LGPL are applicable instead
301
+ * of those above. If you wish to allow use of your version of this file only
302
+ * under the terms of either the GPL or the LGPL, and not to allow others to
303
+ * use your version of this file under the terms of the MPL, indicate your
304
+ * decision by deleting the provisions above and replace them with the notice
305
+ * and other provisions required by the GPL or the LGPL. If you do not delete
306
+ * the provisions above, a recipient may use your version of this file under
307
+ * the terms of any one of the MPL, the GPL or the LGPL.
308
+ *
309
+ * ***** END LICENSE BLOCK ***** */
310
+
311
+ 
312
+#ifndef _NSIPAPERPS_H_
313
+#define _NSIPAPERPS_H_
314
+
315
+#include "prtypes.h"
316
+#include "psSharedCore.h"
317
+
318
+class nsIPaperSizePS {
319
+    public:
320
+        /** ---------------------------------------------------
321
+         * Virtual destructor.
322
+         */
323
+        virtual ~nsIPaperSizePS();
324
+        
325
+        /* Allow the paper factory to create instances */
326
+        friend class nsPaperFactoryPS;
327
+        
328
+        /** ---------------------------------------------------
329
+         * @return PR_TRUE if the cursor points past the last item.
330
+         */
331
+        virtual PRBool AtEnd() = 0;
332
+
333
+        /** ---------------------------------------------------
334
+         * Position the cursor at the beginning of the paper size list.
335
+         * @return VOID
336
+         */
337
+        virtual void First() = 0;
338
+
339
+        /** ---------------------------------------------------
340
+         * Advance the cursor to the next item.
341
+         * @return VOID
342
+         */
343
+        virtual void Next() = 0;
344
+
345
+        /** ---------------------------------------------------
346
+         * Point the cursor to the entry with the given paper name.
347
+         * @return PR_TRUE if pointing to a valid entry.
348
+         */
349
+        virtual PRBool Find(const char *aName) = 0;
350
+
351
+        /** ---------------------------------------------------
352
+         * Point the cursor to a default  entry if available.
353
+         * Otherwise it's equivalent to First().
354
+         * @return PR_TRUE if pointing to a valid entry.
355
+         */
356
+        virtual PRBool FindDefault() = 0;
357
+        
358
+        /** ---------------------------------------------------
359
+         * @return a pointer to the name of the current paper size
360
+         */
361
+        virtual const char *Name() = 0;
362
+
363
+        /** ---------------------------------------------------
364
+         * @return the width of the page in millimeters
365
+         */
366
+        virtual float Width_mm() = 0;
367
+
368
+        /** ---------------------------------------------------
369
+         * @return the height of the page in millimeters
370
+         */
371
+        virtual float Height_mm() = 0;
372
+
373
+        /** ---------------------------------------------------
374
+         * @return PR_TRUE if the paper should be presented to
375
+         *                 the user in metric units.
376
+         */
377
+        virtual PRBool IsMetric() { return PR_TRUE; };
378
+};
379
+
380
+#endif /* _NSIPAPERPS_H_ */
381
--- gfx/src/psshared/nsPSPrinters.h
382
+++ gfx/src/psshared/nsPSPrinters.h
383
@@ -44,6 +44,7 @@
384
 #include "prtypes.h"
385
 #include "nsCUPSShim.h"
386
 #include "psSharedCore.h"
387
+#include "nsCOMPtr.h"
388
 
389
 class nsIPrefService;
390
 class nsIPrefBranch;
391
--- gfx/src/psshared/nsPaperFactoryPS.cpp
392
+++ gfx/src/psshared/nsPaperFactoryPS.cpp
393
@@ -0,0 +1,65 @@
394
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
395
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
396
+/* ***** BEGIN LICENSE BLOCK *****
397
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
398
+ *
399
+ * The contents of this file are subject to the Mozilla Public License Version
400
+ * 1.1 (the "License"); you may not use this file except in compliance with
401
+ * the License. You may obtain a copy of the License at
402
+ * http://www.mozilla.org/MPL/
403
+ *
404
+ * Software distributed under the License is distributed on an "AS IS" basis,
405
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
406
+ * for the specific language governing rights and limitations under the
407
+ * License.
408
+ *
409
+ * The Original Code is mozilla.org code.
410
+ *
411
+ * The Initial Developer of the Original Code is
412
+ * Kenneth Herron <kherron@fastmail.us>.
413
+ * Portions created by the Initial Developer are Copyright (C) 2004
414
+ * the Initial Developer. All Rights Reserved.
415
+ *
416
+ * Contributor(s):
417
+ *   Arne John Glenstrup <panic@itu.dk>
418
+ *
419
+ * Alternatively, the contents of this file may be used under the terms of
420
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
421
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
422
+ * in which case the provisions of the GPL or the LGPL are applicable instead
423
+ * of those above. If you wish to allow use of your version of this file only
424
+ * under the terms of either the GPL or the LGPL, and not to allow others to
425
+ * use your version of this file under the terms of the MPL, indicate your
426
+ * decision by deleting the provisions above and replace them with the notice
427
+ * and other provisions required by the GPL or the LGPL. If you do not delete
428
+ * the provisions above, a recipient may use your version of this file under
429
+ * the terms of any one of the MPL, the GPL or the LGPL.
430
+ *
431
+ * ***** END LICENSE BLOCK ***** */
432
+
433
+
434
+#include "nsDebug.h"
435
+#include "nsPaperFactoryPS.h"
436
+#include "nsIPaperPS.h"
437
+#include "nsPaperPS.h"
438
+#include "nsPSPrinters.h"
439
+
440
+nsresult
441
+nsPaperFactoryPS::CreatePaper(const char* fullPrinterName,
442
+                              const char* printerName,
443
+                              nsIPaperSizePS* &aPaper)
444
+{
445
+    nsIPaperSizePS *newPZ;
446
+
447
+    if (nsPSPrinterList::kTypeCUPS == nsPSPrinterList::GetPrinterType
448
+        (nsDependentCString(fullPrinterName)))
449
+        newPZ = new nsPaperSizeCUPS(fullPrinterName, printerName);
450
+    else
451
+        newPZ = new nsPaperSizePS();
452
+    
453
+    if (!newPZ)
454
+        return NS_ERROR_OUT_OF_MEMORY;
455
+
456
+    aPaper = newPZ;
457
+    return NS_OK;
458
+}
459
--- gfx/src/psshared/nsPaperFactoryPS.h
460
+++ gfx/src/psshared/nsPaperFactoryPS.h
461
@@ -0,0 +1,64 @@
462
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
463
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
464
+/* ***** BEGIN LICENSE BLOCK *****
465
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
466
+ *
467
+ * The contents of this file are subject to the Mozilla Public License Version
468
+ * 1.1 (the "License"); you may not use this file except in compliance with
469
+ * the License. You may obtain a copy of the License at
470
+ * http://www.mozilla.org/MPL/
471
+ *
472
+ * Software distributed under the License is distributed on an "AS IS" basis,
473
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
474
+ * for the specific language governing rights and limitations under the
475
+ * License.
476
+ *
477
+ * Contributor(s):
478
+ *   Arne John Glenstrup <panic@itu.dk>
479
+ *
480
+ * Alternatively, the contents of this file may be used under the terms of
481
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
482
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
483
+ * in which case the provisions of the GPL or the LGPL are applicable instead
484
+ * of those above. If you wish to allow use of your version of this file only
485
+ * under the terms of either the GPL or the LGPL, and not to allow others to
486
+ * use your version of this file under the terms of the MPL, indicate your
487
+ * decision by deleting the provisions above and replace them with the notice
488
+ * and other provisions required by the GPL or the LGPL. If you do not delete
489
+ * the provisions above, a recipient may use your version of this file under
490
+ * the terms of any one of the MPL, the GPL or the LGPL.
491
+ *
492
+ * ***** END LICENSE BLOCK ***** */
493
+
494
+#ifndef nsPaperFactoryPS_h__
495
+#define nsPaperFactoryPS_h__
496
+
497
+#include "nscore.h"
498
+#include "nsIPaperPS.h"
499
+
500
+/* Factory class for the paper sizes. This class determines
501
+ * which paper size class should handle a request, and constructs
502
+ * an object of the appropriate class.
503
+ */
504
+
505
+class NS_PSSHARED nsPaperFactoryPS
506
+{
507
+public:
508
+    /**
509
+     * Construct a paper size object for the given device context spec.
510
+     * On success, the paper size object is owned by the caller and should
511
+     * be destroyed when no longer needed.
512
+     *
513
+     * @param fullPrinterName  Fully qualified name, e.g., "CUPS/myprinter"
514
+     * @param printerName      Stripped name, e.g., "myprinter"
515
+     * @param aPaper           If NS_OK is returned, this will be filled
516
+     *                         in with a pointer to a paper size object.
517
+     * @return NS_OK or a suitable error value.
518
+     */
519
+    static nsresult CreatePaper(const char* fullPrinterName,
520
+               const char* printerName,
521
+               nsIPaperSizePS* &aPaper);
522
+};
523
+
524
+
525
+#endif /* nsPaperFactoryPS_h__ */
526
--- gfx/src/psshared/nsPaperPS.h
527
+++ gfx/src/psshared/nsPaperPS.h
528
@@ -40,9 +40,9 @@
529
 #ifndef _PAPERPS_H_
530
 #define _PAPERPS_H_
531
 
532
-#include "prtypes.h"
533
+#include "nsIPaperPS.h"
534
 #include "nsDebug.h"
535
-#include "psSharedCore.h"
536
+#include "nsCUPSShim.h"
537
 
538
 struct nsPaperSizePS_ {
539
     const char *name;
540
@@ -51,13 +51,13 @@
541
     PRBool isMetric;        // Present to the user in metric, if possible
542
 };
543
 
544
-class NS_PSSHARED nsPaperSizePS {
545
+class NS_PSSHARED nsPaperSizePS : public nsIPaperSizePS {
546
     public:
547
         /** ---------------------------------------------------
548
          * Constructor
549
          */
550
-        nsPaperSizePS() { mCurrent = 0; }
551
-
552
+        nsPaperSizePS();
553
+        
554
         /** ---------------------------------------------------
555
          * @return PR_TRUE if the cursor points past the last item.
556
          */
557
@@ -85,6 +85,12 @@
558
         PRBool Find(const char *aName);
559
 
560
         /** ---------------------------------------------------
561
+         * Position the cursor at the beginning of the paper size list.
562
+         * @return PR_TRUE
563
+         */
564
+        PRBool FindDefault() { mCurrent = 0; return PR_TRUE; }
565
+        
566
+        /** ---------------------------------------------------
567
          * @return a pointer to the name of the current paper size
568
          */
569
         const char *Name() {
570
@@ -117,11 +123,83 @@
571
             return mList[mCurrent].isMetric;
572
         }
573
 
574
-    private:
575
+    protected:
576
         unsigned int mCurrent;
577
         // the class visibility should export these, but it doesn't
578
         static NS_PSSHARED_STATIC_MEMBER_(const nsPaperSizePS_) mList[];
579
-        static NS_PSSHARED_STATIC_MEMBER_(const unsigned int) mCount;
580
+        unsigned int mCount;
581
+};
582
+
583
+class NS_PSSHARED nsPaperSizeCUPS : public nsPaperSizePS {
584
+    public:
585
+        /** ---------------------------------------------------
586
+         * Constructor for a specific CUPS printer.
587
+         * @param fullPrinterName  Fully qualified name, e.g., "CUPS/myprinter"
588
+         * @param printerName      Stripped name, e.g., "myprinter"
589
+         */
590
+        nsPaperSizeCUPS(const char* fullPrinterName, const char* printerName);
591
+        
592
+        /** ---------------------------------------------------
593
+         * Destructor.
594
+         */
595
+        ~nsPaperSizeCUPS();
596
+        
597
+        /** ---------------------------------------------------
598
+         * Position the cursor at the beginning of the paper size list.
599
+         * @return VOID
600
+         */
601
+        void First() {
602
+            nsPaperSizePS::First();
603
+            SkipZeroSizes();
604
+        }
605
+
606
+        /** ---------------------------------------------------
607
+         * Advance the cursor to the next item.
608
+         * @return VOID
609
+         */
610
+        void Next() {
611
+            nsPaperSizePS::Next();
612
+            SkipZeroSizes();
613
+        }
614
+
615
+        /** ---------------------------------------------------
616
+         * Point the cursor to the entry with the given paper name.
617
+         * @return PR_TRUE if pointing to a valid entry.
618
+         */
619
+        PRBool Find(const char *aName);
620
+
621
+        /** ---------------------------------------------------
622
+         * Point the cursor to the CUPS default entry for paper size.
623
+         * @return PR_TRUE if pointing to a valid entry.
624
+         */
625
+        PRBool FindDefault();
626
+        
627
+        /** ---------------------------------------------------
628
+         * @return a pointer to the name of the current paper size
629
+         */
630
+        const char *Name();
631
+
632
+        /** ---------------------------------------------------
633
+         * @return the width of the page in millimeters
634
+         */
635
+        float Width_mm();
636
+
637
+        /** ---------------------------------------------------
638
+         * @return the height of the page in millimeters
639
+         */
640
+        float Height_mm();
641
+
642
+        /** ---------------------------------------------------
643
+         * @return PR_TRUE if the paper should be presented to
644
+         *                 the user in metric units.
645
+         */
646
+        PRBool IsMetric();
647
+        
648
+    private:
649
+        void SkipZeroSizes();
650
+        PRBool mUsingCups;
651
+        static NS_PSSHARED_STATIC_MEMBER_(nsCUPSShim) mCups;
652
+        ppd_file_t* mPPD;
653
 };
654
 
655
 #endif
656
--- gfx/src/xlib/nsDeviceContextSpecXlib.cpp
657
+++ gfx/src/xlib/nsDeviceContextSpecXlib.cpp
658
@@ -1212,7 +1212,11 @@
659
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
660
     nsXPIDLCString papername;
661
     if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
662
-      nsPaperSizePS paper;
663
+      nsIPaperSizePS* paper;
664
+      nsresult rv;
665
+      rv = nsPaperFactoryPS::CreatePaper
666
+        (fullPrinterName.get(), printerName.get(), paper);
667
+      if (NS_FAILED(rv)) return rv;
668
 
669
       if (paper.Find(papername)) {
670
         DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
671
@@ -1238,6 +1242,7 @@
672
       }
673
       printerFeatures.SetNumPaperSizeRecords(count);
674
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
675
+      delete(paper);
676
     }
677
 
678
     PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
679
Index: gfx/src/psshared/nsPaperPS.cpp
680
===================================================================
681
RCS file: /cvsroot/mozilla/gfx/src/psshared/nsPaperPS.cpp,v
682
retrieving revision 1.1.20.1
683
diff -u -p -6 -r1.1.20.1 nsPaperPS.cpp
684
--- gfx/src/psshared/nsPaperPS.cpp  3 Dec 2006 17:59:29 -0000   1.1.20.1
685
+++ gfx/src/psshared/nsPaperPS.cpp  31 Oct 2007 14:28:58 -0000
686
@@ -19,12 +19,14 @@
687
  * The Initial Developer of the Original Code is
688
  * Kenneth Herron <kherron@newsguy.com>.
689
  * Portions created by the Initial Developer are Copyright (C) 2004
690
  * the Initial Developer. All Rights Reserved.
691
  *
692
  * Contributor(s):
693
+ *   Arne John Glenstrup <panic@itu.dk>
694
+ *   Wolfgang Rosenauer <wr@rosenauer.org>
695
  *
696
  * Alternatively, the contents of this file may be used under the terms of
697
  * either the GNU General Public License Version 2 or later (the "GPL"), or
698
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
699
  * in which case the provisions of the GPL or the LGPL are applicable instead
700
  * of those above. If you wish to allow use of your version of this file only
701
@@ -34,15 +36,32 @@
702
  * and other provisions required by the GPL or the LGPL. If you do not delete
703
  * the provisions above, a recipient may use your version of this file under
704
  * the terms of any one of the MPL, the GPL or the LGPL.
705
  *
706
  * ***** END LICENSE BLOCK ***** */
707
 
708
- 
709
+#ifdef MOZ_LOGGING
710
+#define FORCE_PR_LOG 1 /* Allow logging in the release build */
711
+#endif /* MOZ_LOGGING */
712
+#include "prlog.h"
713
+#include "prio.h"
714
+
715
 #include "nsPaperPS.h"
716
 #include "plstr.h"
717
+#include "nsPSPrinters.h"
718
+#include <math.h> 
719
+
720
+#ifdef PR_LOGGING 
721
+static PRLogModuleInfo *PaperSizePSLM = PR_NewLogModule("PaperSizePS");
722
+#endif /* PR_LOGGING */
723
+/* Macro to make lines shorter */
724
+#define DO_PR_DEBUG_LOG(x) PR_LOG(PaperSizePSLM, PR_LOG_DEBUG, x)
725
+
726
+#define MM_PER_PT (25.4 / 72.0)
727
+#define HALF_INCH_PT 36.0
728
+#define EPSILON 0.125
729
 
730
 #define COUNTOF(x) (sizeof(x) / sizeof((x)[0]))
731
 
732
 const nsPaperSizePS_ nsPaperSizePS::mList[] =
733
 {
734
 #define SIZE_MM(x)      (x)
735
@@ -55,19 +74,153 @@ const nsPaperSizePS_ nsPaperSizePS::mLis
736
     { "Tabloid",        SIZE_INCH(11),  SIZE_INCH(17),  PR_FALSE },
737
     { "Executive",      SIZE_INCH(7.5), SIZE_INCH(10),  PR_FALSE },
738
 #undef SIZE_INCH
739
 #undef SIZE_MM
740
 };
741
 
742
-const unsigned int nsPaperSizePS::mCount = COUNTOF(mList);
743
+nsCUPSShim nsPaperSizeCUPS::mCups;
744
+
745
+/* ~nsIPaperSizePS() is virtual, so must implement a destructor. */
746
+nsIPaperSizePS::~nsIPaperSizePS () { }
747
+
748
+nsPaperSizePS::nsPaperSizePS() {
749
+    mCount = COUNTOF(mList);
750
+    mCurrent = 0;
751
+}
752
 
753
 PRBool
754
 nsPaperSizePS::Find(const char *aName)
755
 {
756
     for (int i = mCount; i--; ) {
757
         if (!PL_strcasecmp(aName, mList[i].name)) {
758
             mCurrent = i;
759
             return PR_TRUE;
760
         }
761
     }
762
     return PR_FALSE;
763
 }
764
+
765
+nsPaperSizeCUPS::nsPaperSizeCUPS(const char* fullPrinterName,
766
+                                 const char* printerName) {
767
+    DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS('%s', '%s')\n",
768
+                     fullPrinterName, printerName));
769
+    /* Don't use CUPS before we are sure we have access to the PPD */
770
+    mUsingCups = false;
771
+    mPPD = nsnull;
772
+    mCount = COUNTOF(mList);
773
+    mCurrent = 0;
774
+    if (!fullPrinterName || !printerName ||
775
+        nsPSPrinterList::kTypeCUPS !=
776
+        nsPSPrinterList::GetPrinterType(nsDependentCString(fullPrinterName))) 
777
+        return;
778
+    if (!mCups.IsInitialized()) { mCups.Init(); }
779
+    if (!mCups.IsInitialized()) {
780
+        DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: CUPS unavailable\n"));
781
+        return;
782
+    }
783
+    const char* ppdFileName = mCups.mCupsGetPPD(printerName);
784
+    if (!ppdFileName) {
785
+        DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: "
786
+                         "cannot get PPD file name for printer '%s'\n",
787
+                         printerName));
788
+        return;
789
+    }
790
+    mPPD = mCups.mPpdOpenFile(ppdFileName);
791
+    // Remove the PPD file returned (it is a temporary file)
792
+    // as soon as we've opened it
793
+    if (ppdFileName) PR_Delete(ppdFileName);
794
+
795
+    if (!mPPD)  {
796
+        DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: "
797
+                         "cannot open PPD file '%s'\n",
798
+                         ppdFileName));
799
+        return;
800
+    }
801
+    mCount = mPPD->num_sizes;
802
+    mUsingCups = true;
803
+}
804
+
805
+nsPaperSizeCUPS::~nsPaperSizeCUPS() {
806
+    if (mPPD)  mCups.mPpdClose(mPPD);
807
+}
808
+
809
+void
810
+nsPaperSizeCUPS::SkipZeroSizes() {
811
+    if (!mUsingCups) return; 
812
+    while (mCurrent < mCount
813
+           && (mPPD->sizes[mCurrent].width == 0.0f || 
814
+               mPPD->sizes[mCurrent].length == 0.0f)) {
815
+        mCurrent++;
816
+    }
817
+}
818
+
819
+PRBool
820
+nsPaperSizeCUPS::Find(const char* aName) {
821
+    DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::Find ('%s') ", aName));
822
+    if (!mUsingCups) return nsPaperSizePS::Find(aName);
823
+    for (int i = mCount; i--; ) {
824
+        if (!PL_strcasecmp(aName, mPPD->sizes[i].name)) {
825
+            DO_PR_DEBUG_LOG
826
+                (("found paper '%s' (%gx%gmm)\n",
827
+                  aName,
828
+                  round(mPPD->sizes[i].width * MM_PER_PT),
829
+                  round(mPPD->sizes[i].length * MM_PER_PT)));
830
+            mCurrent = i;
831
+            return PR_TRUE;
832
+        }
833
+    }
834
+    DO_PR_DEBUG_LOG(("did not find paper '%s'\n", aName));
835
+    return PR_FALSE;
836
+}
837
+
838
+PRBool
839
+nsPaperSizeCUPS::FindDefault() {
840
+    DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::FindDefault"));
841
+    if (!mUsingCups) return nsPaperSizePS::FindDefault();
842
+    mCups.mPpdMarkDefaults(mPPD);
843
+    for (int i = mCount; i--; ) {
844
+        if (mCups.mPpdIsMarked(mPPD, "PageSize", mPPD->sizes[i].name )) {
845
+            DO_PR_DEBUG_LOG
846
+                (("found default paper '%s' (%gx%gmm)\n",
847
+                  mPPD->sizes[i].name,
848
+                  round(mPPD->sizes[i].width * MM_PER_PT),
849
+                  round(mPPD->sizes[i].length * MM_PER_PT)));
850
+            mCurrent = i;
851
+            return PR_TRUE;
852
+        }
853
+    }
854
+    mCurrent = 0;
855
+    DO_PR_DEBUG_LOG(("no default paper found, therefore set the first\n"));
856
+    return PR_TRUE;
857
+}
858
+
859
+const char*
860
+nsPaperSizeCUPS::Name() {
861
+    if (!mUsingCups) return nsPaperSizePS::Name();
862
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
863
+    return mPPD->sizes[mCurrent].name;
864
+}
865
+
866
+float
867
+nsPaperSizeCUPS::Width_mm() {
868
+    if (!mUsingCups) return nsPaperSizePS::Width_mm();
869
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
870
+    return round(mPPD->sizes[mCurrent].width * MM_PER_PT);
871
+}
872
+
873
+float
874
+nsPaperSizeCUPS::Height_mm() {
875
+    if (!mUsingCups) return nsPaperSizePS::Height_mm();
876
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
877
+    return round(mPPD->sizes[mCurrent].length * MM_PER_PT);
878
+}
879
+
880
+PRBool 
881
+nsPaperSizeCUPS::IsMetric() {
882
+    if (!mUsingCups) return nsPaperSizePS::IsMetric();
883
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
884
+    /* Educated guess: unless sizes are integral number    */
885
+    /* of half inches, present them to the user in metric. */
886
+    return
887
+        fabs(fmod(mPPD->sizes[mCurrent].width, HALF_INCH_PT)) > EPSILON ||
888
+        fabs(fmod(mPPD->sizes[mCurrent].length, HALF_INCH_PT)) > EPSILON;
889
+}
890