MozillaThunderbird/cups-paper.patch

859 lines
32 KiB
Diff

From: Wolfgang Rosenauer <stark@suse.de>, Arne John Glenstrup <panic@itu.dk>
Subject: get paper sizes from CUPS
References:
https://bugzilla.novell.com/show_bug.cgi?id=65482
https://bugzilla.mozilla.org/show_bug.cgi?id=324060
================================================================================
--- gfx/src/gtk/nsDeviceContextSpecG.cpp
+++ gfx/src/gtk/nsDeviceContextSpecG.cpp
@@ -66,6 +66,7 @@
#ifdef USE_POSTSCRIPT
#include "nsPSPrinters.h"
#include "nsPaperPS.h" /* Paper size list */
+#include "nsPaperFactoryPS.h" /* Paper size list factory */
#endif /* USE_POSTSCRIPT */
/* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
@@ -1210,34 +1211,38 @@
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
printerFeatures.SetCanChangePaperSize(PR_TRUE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
- nsXPIDLCString papername;
- if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
- nsPaperSizePS paper;
-
- if (paper.Find(papername)) {
- DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
- paper.Name(), paper.Width_mm(), paper.Height_mm()));
- aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ?
- (int)nsIPrintSettings::kPaperSizeMillimeters :
- (int)nsIPrintSettings::kPaperSizeInches);
- aPrintSettings->SetPaperWidth(paper.Width_mm());
- aPrintSettings->SetPaperHeight(paper.Height_mm());
- aPrintSettings->SetPaperName(NS_ConvertASCIItoUCS2(paper.Name()).get());
- }
- else {
- DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
+ {
+ nsIPaperSizePS* paper;
+ nsresult rv;
+ rv = nsPaperFactoryPS::CreatePaper
+ (fullPrinterName.get(), printerName.get(), paper);
+ if (NS_FAILED(rv)) return rv;
+ paper->FindDefault();
+
+ nsXPIDLCString papername;
+ if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", fullPrinterName, "print_paper_name", getter_Copies(papername)))) {
+ if (!paper->Find(papername)) {
+ DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
+ }
}
+ DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
+ paper->Name(), paper->Width_mm(), paper->Height_mm()));
+ aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
+ aPrintSettings->SetPaperWidth(paper->Width_mm());
+ aPrintSettings->SetPaperHeight(paper->Height_mm());
+ aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper->Name()).get());
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
- paper.First();
+ paper->First();
int count = 0;
- while (!paper.AtEnd())
+ while (!paper->AtEnd())
{
- printerFeatures.SetPaperRecord(count++, paper.Name(),
- (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
- paper.Next();
+ printerFeatures.SetPaperRecord(count++, paper->Name(),
+ (int)paper->Width_mm(), (int)paper->Height_mm(), !paper->IsMetric());
+ paper->Next();
}
printerFeatures.SetNumPaperSizeRecords(count);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
+ delete(paper);
}
PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
--- gfx/src/ps/nsPrintJobPS.cpp
+++ gfx/src/ps/nsPrintJobPS.cpp
@@ -364,6 +364,10 @@
const char *slash = strchr(printerName, '/');
mPrinterName = slash ? slash + 1 : printerName;
mJobTitle.SetIsVoid(PR_TRUE);
+ /* Paper name */
+ const char* paperName = nsnull;
+ aSpec->GetPaperName(&paperName);
+ mPaperName = paperName;
return NS_OK;
}
@@ -445,6 +449,11 @@
mNumCopies.get(),
dest->num_options,
&dest->options);
+ if (!mPaperName.IsEmpty())
+ dest->num_options = (mCups.mCupsAddOption)("media",
+ mPaperName.get(),
+ dest->num_options,
+ &dest->options);
const char *title = mJobTitle.IsVoid() ?
"Untitled Document" : mJobTitle.get();
result = (mCups.mCupsPrintFile)(printer.CStringAt(0)->get(),
--- gfx/src/ps/nsPrintJobPS.h
+++ gfx/src/ps/nsPrintJobPS.h
@@ -179,6 +179,7 @@
nsCUPSShim mCups;
nsCString mPrinterName;
nsCString mNumCopies;
+ nsCString mPaperName;
nsCString mJobTitle; // IsVoid() if no title
};
#endif /* VMS */
--- gfx/src/psshared/Makefile.in
+++ gfx/src/psshared/Makefile.in
@@ -57,13 +57,16 @@
EXPORTS = nsCUPSShim.h \
nsPaperPS.h \
+ nsIPaperPS.h \
nsPSPrinters.h\
psSharedCore.h \
+ nsPaperFactoryPS.h \
$(NULL)
CPPSRCS = nsCUPSShim.cpp \
nsPaperPS.cpp \
nsPSPrinters.cpp \
+ nsPaperFactoryPS.cpp \
$(NULL)
EXTRA_DSO_LDOPTS = \
--- gfx/src/psshared/nsCUPSShim.cpp
+++ gfx/src/psshared/nsCUPSShim.cpp
@@ -45,13 +45,18 @@
// List of symbols to find in libcups. Must match symAddr[] defined in Init().
// Making this an array of arrays instead of pointers allows storing the
// whole thing in read-only memory.
-static const char gSymName[][sizeof("cupsPrintFile")] = {
+static const char gSymName[][sizeof("ppdMarkDefaults")] = {
{ "cupsAddOption" },
{ "cupsFreeDests" },
{ "cupsGetDest" },
{ "cupsGetDests" },
{ "cupsPrintFile" },
{ "cupsTempFd" },
+ { "cupsGetPPD" },
+ { "ppdOpenFile" },
+ { "ppdClose" },
+ { "ppdMarkDefaults" },
+ { "ppdIsMarked" },
};
static const int gSymNameCt = sizeof(gSymName) / sizeof(gSymName[0]);
@@ -71,6 +76,11 @@
(void **)&mCupsGetDests,
(void **)&mCupsPrintFile,
(void **)&mCupsTempFd,
+ (void **)&mCupsGetPPD,
+ (void **)&mPpdOpenFile,
+ (void **)&mPpdClose,
+ (void **)&mPpdMarkDefaults,
+ (void **)&mPpdIsMarked,
};
for (int i = gSymNameCt; i--; ) {
--- gfx/src/psshared/nsCUPSShim.h
+++ gfx/src/psshared/nsCUPSShim.h
@@ -62,6 +62,82 @@
cups_option_t *options; /* Options */
} cups_dest_t;
+typedef enum /**** Colorspaces ****/
+{
+ PPD_CS_CMYK = -4, /* CMYK colorspace */
+ PPD_CS_CMY, /* CMY colorspace */
+ PPD_CS_GRAY = 1, /* Grayscale colorspace */
+ PPD_CS_RGB = 3, /* RGB colorspace */
+ PPD_CS_RGBK, /* RGBK (K = gray) colorspace */
+ PPD_CS_N /* DeviceN colorspace */
+} ppd_cs_t;
+
+typedef struct /**** Page Sizes ****/
+{
+ int marked; /* Page size selected? */
+ char name[41];
+ /* Media size option */
+ float width, /* Width of media in points */
+ length, /* Length of media in points */
+ left, /* Left printable margin in points */
+ bottom, /* Bottom printable margin in points */
+ right, /* Right printable margin in points */
+ top; /* Top printable margin in points */
+} ppd_size_t;
+
+typedef struct /**** Files ****/
+{
+ int language_level, /* Language level of device */
+ color_device, /* 1 = color device, 0 = grayscale */
+ variable_sizes, /* 1 = supports variable sizes, 0 = doesn't */
+ accurate_screens, /* 1 = supports accurate screens, 0 = not */
+ contone_only, /* 1 = continuous tone only, 0 = not */
+ landscape, /* -90 or 90 */
+ model_number, /* Device-specific model number */
+ manual_copies, /* 1 = Copies done manually, 0 = hardware */
+ throughput; /* Pages per minute */
+ ppd_cs_t colorspace; /* Default colorspace */
+ char *patches; /* Patch commands to be sent to printer */
+ int num_emulations; /* Number of emulations supported */
+ void *emulations; /* Emulations and the code to invoke them */
+ char *jcl_begin, /* Start JCL commands */
+ *jcl_ps, /* Enter PostScript interpreter */
+ *jcl_end, /* End JCL commands */
+ *lang_encoding, /* Language encoding */
+ *lang_version, /* Language version (English, Spanish, etc.) */
+ *modelname, /* Model name (general) */
+ *ttrasterizer, /* Truetype rasterizer */
+ *manufacturer, /* Manufacturer name */
+ *product, /* Product name (from PS RIP/interpreter) */
+ *nickname, /* Nickname (specific) */
+ *shortnickname; /* Short version of nickname */
+ int num_groups; /* Number of UI groups */
+ void *groups; /* UI groups */
+ int num_sizes; /* Number of page sizes */
+ ppd_size_t *sizes; /* Page sizes */
+ float custom_min[2], /* Minimum variable page size */
+ custom_max[2], /* Maximum variable page size */
+ custom_margins[4];/* Margins around page */
+ int num_consts; /* Number of UI/Non-UI constraints */
+ void *consts; /* UI/Non-UI constraints */
+ int num_fonts; /* Number of pre-loaded fonts */
+ char **fonts; /* Pre-loaded fonts */
+ int num_profiles; /* Number of sRGB color profiles */
+ void *profiles; /* sRGB color profiles */
+ int num_filters; /* Number of filters */
+ char **filters; /* Filter strings... */
+
+ /**** New in CUPS 1.1 ****/
+ int flip_duplex; /* 1 = Flip page for back sides */
+
+ /**** New in CUPS 1.1.19 ****/
+ char *protocols, /* Protocols (BCP, TBCP) string */
+ *pcfilename; /* PCFileName string */
+ int num_attrs, /* Number of attributes */
+ cur_attr; /* Current attribute */
+ void **attrs; /* Attributes */
+} ppd_file_t;
+
typedef cups_dest_t* (PR_CALLBACK *CupsGetDestType)(const char *printer,
const char *instance,
int num_dests,
@@ -80,6 +156,11 @@
const char *value,
int num_options,
cups_option_t **options);
+typedef const char* (PR_CALLBACK *CupsGetPPDType) (const char* name);
+typedef ppd_file_t* (PR_CALLBACK *PPDOpenFileType) (const char* filename);
+typedef void (PR_CALLBACK *PPDCloseType) (ppd_file_t* ppd);
+typedef void (PR_CALLBACK *PPDMarkDefaultsType) (ppd_file_t* ppd);
+typedef int (PR_CALLBACK *PPDIsMarkedType) (ppd_file_t* ppd, const char* pname, const char* pname_clear);
struct PRLibrary;
@@ -113,6 +194,11 @@
CupsGetDestsType mCupsGetDests;
CupsPrintFileType mCupsPrintFile;
CupsTempFdType mCupsTempFd;
+ CupsGetPPDType mCupsGetPPD;
+ PPDOpenFileType mPpdOpenFile;
+ PPDCloseType mPpdClose;
+ PPDMarkDefaultsType mPpdMarkDefaults;
+ PPDIsMarkedType mPpdIsMarked;
private:
PRLibrary *mCupsLib;
--- gfx/src/psshared/nsIPaperPS.h
+++ gfx/src/psshared/nsIPaperPS.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ * Arne John Glenstrup <panic@itu.dk>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _NSIPAPERPS_H_
+#define _NSIPAPERPS_H_
+
+#include "prtypes.h"
+#include "psSharedCore.h"
+
+class nsIPaperSizePS {
+ public:
+ /** ---------------------------------------------------
+ * Virtual destructor.
+ */
+ virtual ~nsIPaperSizePS();
+
+ /* Allow the paper factory to create instances */
+ friend class nsPaperFactoryPS;
+
+ /** ---------------------------------------------------
+ * @return PR_TRUE if the cursor points past the last item.
+ */
+ virtual PRBool AtEnd() = 0;
+
+ /** ---------------------------------------------------
+ * Position the cursor at the beginning of the paper size list.
+ * @return VOID
+ */
+ virtual void First() = 0;
+
+ /** ---------------------------------------------------
+ * Advance the cursor to the next item.
+ * @return VOID
+ */
+ virtual void Next() = 0;
+
+ /** ---------------------------------------------------
+ * Point the cursor to the entry with the given paper name.
+ * @return PR_TRUE if pointing to a valid entry.
+ */
+ virtual PRBool Find(const char *aName) = 0;
+
+ /** ---------------------------------------------------
+ * Point the cursor to a default entry if available.
+ * Otherwise it's equivalent to First().
+ * @return PR_TRUE if pointing to a valid entry.
+ */
+ virtual PRBool FindDefault() = 0;
+
+ /** ---------------------------------------------------
+ * @return a pointer to the name of the current paper size
+ */
+ virtual const char *Name() = 0;
+
+ /** ---------------------------------------------------
+ * @return the width of the page in millimeters
+ */
+ virtual float Width_mm() = 0;
+
+ /** ---------------------------------------------------
+ * @return the height of the page in millimeters
+ */
+ virtual float Height_mm() = 0;
+
+ /** ---------------------------------------------------
+ * @return PR_TRUE if the paper should be presented to
+ * the user in metric units.
+ */
+ virtual PRBool IsMetric() { return PR_TRUE; };
+};
+
+#endif /* _NSIPAPERPS_H_ */
--- gfx/src/psshared/nsPSPrinters.h
+++ gfx/src/psshared/nsPSPrinters.h
@@ -44,6 +44,7 @@
#include "prtypes.h"
#include "nsCUPSShim.h"
#include "psSharedCore.h"
+#include "nsCOMPtr.h"
class nsIPrefService;
class nsIPrefBranch;
--- gfx/src/psshared/nsPaperFactoryPS.cpp
+++ gfx/src/psshared/nsPaperFactoryPS.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Kenneth Herron <kherron@fastmail.us>.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Arne John Glenstrup <panic@itu.dk>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsDebug.h"
+#include "nsPaperFactoryPS.h"
+#include "nsIPaperPS.h"
+#include "nsPaperPS.h"
+#include "nsPSPrinters.h"
+
+nsresult
+nsPaperFactoryPS::CreatePaper(const char* fullPrinterName,
+ const char* printerName,
+ nsIPaperSizePS* &aPaper)
+{
+ nsIPaperSizePS *newPZ;
+
+ if (nsPSPrinterList::kTypeCUPS == nsPSPrinterList::GetPrinterType
+ (nsDependentCString(fullPrinterName)))
+ newPZ = new nsPaperSizeCUPS(fullPrinterName, printerName);
+ else
+ newPZ = new nsPaperSizePS();
+
+ if (!newPZ)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ aPaper = newPZ;
+ return NS_OK;
+}
--- gfx/src/psshared/nsPaperFactoryPS.h
+++ gfx/src/psshared/nsPaperFactoryPS.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ * Arne John Glenstrup <panic@itu.dk>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsPaperFactoryPS_h__
+#define nsPaperFactoryPS_h__
+
+#include "nscore.h"
+#include "nsIPaperPS.h"
+
+/* Factory class for the paper sizes. This class determines
+ * which paper size class should handle a request, and constructs
+ * an object of the appropriate class.
+ */
+
+class NS_PSSHARED nsPaperFactoryPS
+{
+public:
+ /**
+ * Construct a paper size object for the given device context spec.
+ * On success, the paper size object is owned by the caller and should
+ * be destroyed when no longer needed.
+ *
+ * @param fullPrinterName Fully qualified name, e.g., "CUPS/myprinter"
+ * @param printerName Stripped name, e.g., "myprinter"
+ * @param aPaper If NS_OK is returned, this will be filled
+ * in with a pointer to a paper size object.
+ * @return NS_OK or a suitable error value.
+ */
+ static nsresult CreatePaper(const char* fullPrinterName,
+ const char* printerName,
+ nsIPaperSizePS* &aPaper);
+};
+
+
+#endif /* nsPaperFactoryPS_h__ */
--- gfx/src/psshared/nsPaperPS.cpp
+++ gfx/src/psshared/nsPaperPS.cpp
@@ -22,6 +22,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Arne John Glenstrup <panic@itu.dk>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -37,9 +38,25 @@
*
* ***** END LICENSE BLOCK ***** */
-
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG 1 /* Allow logging in the release build */
+#endif /* MOZ_LOGGING */
+#include "prlog.h"
+
#include "nsPaperPS.h"
#include "plstr.h"
+#include "nsPSPrinters.h"
+#include <math.h>
+
+#ifdef PR_LOGGING
+static PRLogModuleInfo *PaperSizePSLM = PR_NewLogModule("PaperSizePS");
+#endif /* PR_LOGGING */
+/* Macro to make lines shorter */
+#define DO_PR_DEBUG_LOG(x) PR_LOG(PaperSizePSLM, PR_LOG_DEBUG, x)
+
+#define MM_PER_PT (25.4 / 72.0)
+#define HALF_INCH_PT 36.0
+#define EPSILON 0.125
#define COUNTOF(x) (sizeof(x) / sizeof((x)[0]))
@@ -57,7 +74,15 @@
#undef SIZE_MM
};
-const unsigned int nsPaperSizePS::mCount = COUNTOF(mList);
+nsCUPSShim nsPaperSizeCUPS::mCups;
+
+/* ~nsIPaperSizePS() is virtual, so must implement a destructor. */
+nsIPaperSizePS::~nsIPaperSizePS () { }
+
+nsPaperSizePS::nsPaperSizePS() {
+ mCount = COUNTOF(mList);
+ mCurrent = 0;
+}
PRBool
nsPaperSizePS::Find(const char *aName)
@@ -70,3 +95,125 @@
}
return PR_FALSE;
}
+
+nsPaperSizeCUPS::nsPaperSizeCUPS(const char* fullPrinterName,
+ const char* printerName) {
+ DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS('%s', '%s')\n",
+ fullPrinterName, printerName));
+ /* Don't use CUPS before we are sure we have access to the PPD */
+ mUsingCups = false;
+ mPPD = nsnull;
+ mCount = COUNTOF(mList);
+ mCurrent = 0;
+ if (!fullPrinterName || !printerName ||
+ nsPSPrinterList::kTypeCUPS !=
+ nsPSPrinterList::GetPrinterType(nsDependentCString(fullPrinterName)))
+ return;
+ if (!mCups.IsInitialized()) { mCups.Init(); }
+ if (!mCups.IsInitialized()) {
+ DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: CUPS unavailable\n"));
+ return;
+ }
+ const char* ppdFileName = mCups.mCupsGetPPD(printerName);
+ if (!ppdFileName) {
+ DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: "
+ "cannot get PPD file name for printer '%s'\n",
+ printerName));
+ return;
+ }
+ mPPD = mCups.mPpdOpenFile(ppdFileName);
+ if (!mPPD) {
+ DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: "
+ "cannot open PPD file '%s'\n",
+ ppdFileName));
+ return;
+ }
+ mCount = mPPD->num_sizes;
+ mUsingCups = true;
+}
+
+nsPaperSizeCUPS::~nsPaperSizeCUPS() {
+ if (mPPD) mCups.mPpdClose(mPPD);
+}
+
+void
+nsPaperSizeCUPS::SkipZeroSizes() {
+ if (!mUsingCups) return;
+ while (mCurrent < mCount
+ && (mPPD->sizes[mCurrent].width == 0.0f ||
+ mPPD->sizes[mCurrent].length == 0.0f)) {
+ mCurrent++;
+ }
+}
+
+PRBool
+nsPaperSizeCUPS::Find(const char* aName) {
+ DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::Find ('%s') ", aName));
+ if (!mUsingCups) return nsPaperSizePS::Find(aName);
+ for (int i = mCount; i--; ) {
+ if (!PL_strcasecmp(aName, mPPD->sizes[i].name)) {
+ DO_PR_DEBUG_LOG
+ (("found paper '%s' (%gx%gmm)\n",
+ aName,
+ round(mPPD->sizes[i].width * MM_PER_PT),
+ round(mPPD->sizes[i].length * MM_PER_PT)));
+ mCurrent = i;
+ return PR_TRUE;
+ }
+ }
+ DO_PR_DEBUG_LOG(("did not find paper '%s'\n", aName));
+ return PR_FALSE;
+}
+
+PRBool
+nsPaperSizeCUPS::FindDefault() {
+ DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::FindDefault"));
+ if (!mUsingCups) return nsPaperSizePS::FindDefault();
+ mCups.mPpdMarkDefaults(mPPD);
+ for (int i = mCount; i--; ) {
+ if (mCups.mPpdIsMarked(mPPD, "PageSize", mPPD->sizes[i].name )) {
+ DO_PR_DEBUG_LOG
+ (("found default paper '%s' (%gx%gmm)\n",
+ mPPD->sizes[i].name,
+ round(mPPD->sizes[i].width * MM_PER_PT),
+ round(mPPD->sizes[i].length * MM_PER_PT)));
+ mCurrent = i;
+ return PR_TRUE;
+ }
+ }
+ mCurrent = 0;
+ DO_PR_DEBUG_LOG(("no default paper found, therefore set the first\n"));
+ return PR_TRUE;
+}
+
+const char*
+nsPaperSizeCUPS::Name() {
+ if (!mUsingCups) return nsPaperSizePS::Name();
+ NS_PRECONDITION(!AtEnd(), "Invalid current item");
+ return mPPD->sizes[mCurrent].name;
+}
+
+float
+nsPaperSizeCUPS::Width_mm() {
+ if (!mUsingCups) return nsPaperSizePS::Width_mm();
+ NS_PRECONDITION(!AtEnd(), "Invalid current item");
+ return round(mPPD->sizes[mCurrent].width * MM_PER_PT);
+}
+
+float
+nsPaperSizeCUPS::Height_mm() {
+ if (!mUsingCups) return nsPaperSizePS::Height_mm();
+ NS_PRECONDITION(!AtEnd(), "Invalid current item");
+ return round(mPPD->sizes[mCurrent].length * MM_PER_PT);
+}
+
+PRBool
+nsPaperSizeCUPS::IsMetric() {
+ if (!mUsingCups) return nsPaperSizePS::IsMetric();
+ NS_PRECONDITION(!AtEnd(), "Invalid current item");
+ /* Educated guess: unless sizes are integral number */
+ /* of half inches, present them to the user in metric. */
+ return
+ fabs(fmod(mPPD->sizes[mCurrent].width, HALF_INCH_PT)) > EPSILON ||
+ fabs(fmod(mPPD->sizes[mCurrent].length, HALF_INCH_PT)) > EPSILON;
+}
--- gfx/src/psshared/nsPaperPS.h
+++ gfx/src/psshared/nsPaperPS.h
@@ -40,9 +40,9 @@
#ifndef _PAPERPS_H_
#define _PAPERPS_H_
-#include "prtypes.h"
+#include "nsIPaperPS.h"
#include "nsDebug.h"
-#include "psSharedCore.h"
+#include "nsCUPSShim.h"
struct nsPaperSizePS_ {
const char *name;
@@ -51,13 +51,13 @@
PRBool isMetric; // Present to the user in metric, if possible
};
-class NS_PSSHARED nsPaperSizePS {
+class NS_PSSHARED nsPaperSizePS : public nsIPaperSizePS {
public:
/** ---------------------------------------------------
* Constructor
*/
- nsPaperSizePS() { mCurrent = 0; }
-
+ nsPaperSizePS();
+
/** ---------------------------------------------------
* @return PR_TRUE if the cursor points past the last item.
*/
@@ -85,6 +85,12 @@
PRBool Find(const char *aName);
/** ---------------------------------------------------
+ * Position the cursor at the beginning of the paper size list.
+ * @return PR_TRUE
+ */
+ PRBool FindDefault() { mCurrent = 0; return PR_TRUE; }
+
+ /** ---------------------------------------------------
* @return a pointer to the name of the current paper size
*/
const char *Name() {
@@ -117,11 +123,83 @@
return mList[mCurrent].isMetric;
}
- private:
+ protected:
unsigned int mCurrent;
// the class visibility should export these, but it doesn't
static NS_PSSHARED_STATIC_MEMBER_(const nsPaperSizePS_) mList[];
- static NS_PSSHARED_STATIC_MEMBER_(const unsigned int) mCount;
+ unsigned int mCount;
+};
+
+class NS_PSSHARED nsPaperSizeCUPS : public nsPaperSizePS {
+ public:
+ /** ---------------------------------------------------
+ * Constructor for a specific CUPS printer.
+ * @param fullPrinterName Fully qualified name, e.g., "CUPS/myprinter"
+ * @param printerName Stripped name, e.g., "myprinter"
+ */
+ nsPaperSizeCUPS(const char* fullPrinterName, const char* printerName);
+
+ /** ---------------------------------------------------
+ * Destructor.
+ */
+ ~nsPaperSizeCUPS();
+
+ /** ---------------------------------------------------
+ * Position the cursor at the beginning of the paper size list.
+ * @return VOID
+ */
+ void First() {
+ nsPaperSizePS::First();
+ SkipZeroSizes();
+ }
+
+ /** ---------------------------------------------------
+ * Advance the cursor to the next item.
+ * @return VOID
+ */
+ void Next() {
+ nsPaperSizePS::Next();
+ SkipZeroSizes();
+ }
+
+ /** ---------------------------------------------------
+ * Point the cursor to the entry with the given paper name.
+ * @return PR_TRUE if pointing to a valid entry.
+ */
+ PRBool Find(const char *aName);
+
+ /** ---------------------------------------------------
+ * Point the cursor to the CUPS default entry for paper size.
+ * @return PR_TRUE if pointing to a valid entry.
+ */
+ PRBool FindDefault();
+
+ /** ---------------------------------------------------
+ * @return a pointer to the name of the current paper size
+ */
+ const char *Name();
+
+ /** ---------------------------------------------------
+ * @return the width of the page in millimeters
+ */
+ float Width_mm();
+
+ /** ---------------------------------------------------
+ * @return the height of the page in millimeters
+ */
+ float Height_mm();
+
+ /** ---------------------------------------------------
+ * @return PR_TRUE if the paper should be presented to
+ * the user in metric units.
+ */
+ PRBool IsMetric();
+
+ private:
+ void SkipZeroSizes();
+ PRBool mUsingCups;
+ static NS_PSSHARED_STATIC_MEMBER_(nsCUPSShim) mCups;
+ ppd_file_t* mPPD;
};
#endif
--- gfx/src/xlib/nsDeviceContextSpecXlib.cpp
+++ gfx/src/xlib/nsDeviceContextSpecXlib.cpp
@@ -1212,7 +1212,11 @@
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
nsXPIDLCString papername;
if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
- nsPaperSizePS paper;
+ nsIPaperSizePS* paper;
+ nsresult rv;
+ rv = nsPaperFactoryPS::CreatePaper
+ (fullPrinterName.get(), printerName.get(), paper);
+ if (NS_FAILED(rv)) return rv;
if (paper.Find(papername)) {
DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
@@ -1238,6 +1242,7 @@
}
printerFeatures.SetNumPaperSizeRecords(count);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
+ delete(paper);
}
PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==