From 82cffe4fb9a6ddfe47b138c6da1f52764db13999 Mon Sep 17 00:00:00 2001 From: "timeless%mac.com" Date: Tue, 12 Feb 2002 19:58:37 +0000 Subject: [PATCH] =?UTF-8?q?Bug=20120916=EF=BF=BDPostScript/Xprint=20module?= =?UTF-8?q?=20revamp=20by=20Roland.Mainz@informatik.med.uni-giessen.de=20r?= =?UTF-8?q?=3Drods,=20r=3Ddcone,=20rs=3Dattinasi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gfx/src/gtk/nsDeviceContextSpecG.cpp | 163 +-- gfx/src/gtk/nsDeviceContextSpecG.h | 114 +- gfx/src/ps/nsAFMObject.cpp | 6 +- gfx/src/ps/nsAFMObject.h | 91 +- gfx/src/ps/nsDeviceContextPS.cpp | 89 +- gfx/src/ps/nsDeviceContextPS.h | 4 +- gfx/src/ps/nsIDeviceContextSpecPS.h | 29 +- gfx/src/ps/nsPostScriptObj.cpp | 146 ++- gfx/src/ps/nsPostScriptObj.h | 33 +- gfx/src/ps/nsRenderingContextPS.cpp | 64 +- gfx/src/ps/nsRenderingContextPS.h | 4 +- gfx/src/xlib/nsDeviceContextSpecXlib.cpp | 147 +-- gfx/src/xlib/nsDeviceContextSpecXlib.h | 32 +- gfx/src/xlib/nsFontMetricsXlib.cpp | 7 +- gfx/src/xlib/nsPrintdXlib.cpp | 50 - gfx/src/xlib/nsPrintdXlib.h | 89 -- gfx/src/xlib/nsRenderingContextXlib.cpp | 42 +- gfx/src/xlib/nsRenderingContextXlib.h | 2 +- gfx/src/xprint/nsDeviceContextXP.cpp | 36 +- gfx/src/xprint/nsIDeviceContextSpecXPrint.h | 35 +- gfx/src/xprint/nsRenderingContextXp.cpp | 6 +- gfx/src/xprint/nsXPrintContext.cpp | 257 +++-- gfx/src/xprint/nsXPrintContext.h | 7 +- gfx/src/xprint/xprintutil.c | 1089 ++++++++++++++++--- gfx/src/xprint/xprintutil.h | 118 +- gfx/src/xprint/xprintutil_printtofile.c | 28 +- 26 files changed, 1746 insertions(+), 942 deletions(-) diff --git a/gfx/src/gtk/nsDeviceContextSpecG.cpp b/gfx/src/gtk/nsDeviceContextSpecG.cpp index 253a5a195867..0a4369b1b69d 100644 --- a/gfx/src/gtk/nsDeviceContextSpecG.cpp +++ b/gfx/src/gtk/nsDeviceContextSpecG.cpp @@ -39,17 +39,16 @@ #include "nsDeviceContextSpecG.h" -#include "nsReadableUtils.h" - #include "nsIPref.h" #include "prenv.h" /* for PR_GetEnv */ -#include "nsIDOMWindow.h" +#include "nsIDOMWindowInternal.h" #include "nsIServiceManager.h" #include "nsIDialogParamBlock.h" #include "nsISupportsPrimitives.h" #include "nsIWindowWatcher.h" -#include "nsIDOMWindowInternal.h" + +#include "nsReadableUtils.h" #include "nsISupportsArray.h" #ifdef USE_XPRINT @@ -57,9 +56,9 @@ #endif /* USE_XPRINT */ //---------------------------------------------------------------------------------- -// The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecG +// The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecGTK // The PrinterEnumerator creates the printer info -// but the nsDeviceContextSpecG cleans it up +// but the nsDeviceContextSpecGTK cleans it up // If it gets created (via the Page Setup Dialog) but the user never prints anything // then it will never be delete, so this class takes care of that. class GlobalPrinters { @@ -89,20 +88,12 @@ nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull; int GlobalPrinters::mGlobalNumPrinters = 0; //--------------- -/** ------------------------------------------------------- - * Construct the nsDeviceContextSpecGTK - * @update dc 12/02/98 - */ -nsDeviceContextSpecGTK :: nsDeviceContextSpecGTK() +nsDeviceContextSpecGTK::nsDeviceContextSpecGTK() { NS_INIT_REFCNT(); } -/** ------------------------------------------------------- - * Destroy the nsDeviceContextSpecGTK - * @update dc 2/15/98 - */ -nsDeviceContextSpecGTK :: ~nsDeviceContextSpecGTK() +nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK() { } @@ -117,6 +108,8 @@ NS_IMPL_ISUPPORTS2(nsDeviceContextSpecGTK, nsIDeviceContextSpecPS) #endif /* USE_XPRINT */ +/** ------------------------------------------------------- + */ static nsresult DisplayXPDialog(nsIPrintSettings* aPS, const char* aChromeURL, PRBool& aClickedOK) @@ -174,8 +167,6 @@ static nsresult DisplayXPDialog(nsIPrintSettings* aPS, return rv; } - - /** ------------------------------------------------------- * Initialize the nsDeviceContextSpecGTK * @update dc 2/15/98 @@ -217,7 +208,6 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings* aPS, PRBool aQuiet) PRBool color = PR_FALSE; PRBool tofile = PR_FALSE; PRInt16 printRange = nsIPrintSettings::kRangeAllPages; - PRInt32 paper_size = NS_LETTER_SIZE; PRInt32 orientation = NS_PORTRAIT; PRInt32 fromPage = 1; PRInt32 toPage = 1; @@ -250,7 +240,6 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings* aPS, PRBool aQuiet) aPS->GetPrinterName(&printer); aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); - aPS->GetPaperSize(&paper_size); aPS->GetOrientation(&orientation); aPS->GetPrintCommand(&command); aPS->GetPrintRange(&printRange); @@ -266,11 +255,11 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings* aPS, PRBool aQuiet) if (command != nsnull && printfile != nsnull) { // ToDo: Use LocalEncoding instead of UTF-8 (see bug 73446) - strcpy(mPrData.command, NS_ConvertUCS2toUTF8(command).get()); - strcpy(mPrData.path, NS_ConvertUCS2toUTF8(printfile).get()); + strcpy(mCommand, NS_ConvertUCS2toUTF8(command).get()); + strcpy(mPath, NS_ConvertUCS2toUTF8(printfile).get()); } if (printer != nsnull) - strcpy(mPrData.printer, NS_ConvertUCS2toUTF8(printer).get()); + strcpy(mPrinter, NS_ConvertUCS2toUTF8(printer).get()); #ifdef DEBUG_rods printf("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright); @@ -289,45 +278,35 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings* aPS, PRBool aQuiet) #ifdef VMS // Note to whoever puts the "lpr" into the prefs file. Please contact me // as I need to make the default be "print" instead of "lpr" for OpenVMS. - strcpy(mPrData.command, "print"); + strcpy(mCommand, "print"); #else - strcpy(mPrData.command, "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}"); + strcpy(mCommand, "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}"); #endif /* VMS */ } - mPrData.top = dtop; - mPrData.bottom = dbottom; - mPrData.left = dleft; - mPrData.right = dright; - mPrData.fpf = !reversed; - mPrData.grayscale = !color; - mPrData.size = paper_size; - mPrData.orientation = orientation; - mPrData.toPrinter = !tofile; - mPrData.copies = copies; + mTop = dtop; + mBottom = dbottom; + mLeft = dleft; + mRight = dright; + mFpf = !reversed; + mGrayscale = !color; + mOrientation = orientation; + mToPrinter = !tofile; + mCopies = copies; // PWD, HOME, or fail if (!printfile) { if ( ( path = PR_GetEnv( "PWD" ) ) == (char *) nsnull ) if ( ( path = PR_GetEnv( "HOME" ) ) == (char *) nsnull ) - strcpy(mPrData.path, "mozilla.ps"); + strcpy(mPath, "mozilla.ps"); if ( path != (char *) nsnull ) - sprintf(mPrData.path, "%s/mozilla.ps", path); + sprintf(mPath, "%s/mozilla.ps", path); else return NS_ERROR_FAILURE; } - -#ifdef NOT_IMPLEMENTED_YET - if (mGlobalNumPrinters) { - for(int i = 0; (i < mGlobalNumPrinters) && !mQueue; i++) { - if (!(mGlobalPrinterList->StringAt(i)->CompareWithConversion(mPrData.printer, TRUE, -1))) - mQueue = PrnDlg.SetPrinterQueue(i); - } - } -#endif /* NOT_IMPLEMENTED_YET */ - + if (command != nsnull) { nsMemory::Free(command); } @@ -342,123 +321,92 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings* aPS, PRBool aQuiet) NS_IMETHODIMP nsDeviceContextSpecGTK::GetToPrinter(PRBool &aToPrinter) { - aToPrinter = mPrData.toPrinter; + aToPrinter = mToPrinter; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrinterName ( char **aPrinter ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrinterName ( const char **aPrinter ) { - *aPrinter = &mPrData.printer[0]; + *aPrinter = mPrinter; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetCopies ( int &aCopies ) { - aCopies = mPrData.copies; + aCopies = mCopies; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetFirstPageFirst ( PRBool &aFpf ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetFirstPageFirst(PRBool &aFpf) { - aFpf = mPrData.fpf; + aFpf = mFpf; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetGrayscale ( PRBool &aGrayscale ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetGrayscale(PRBool &aGrayscale) { - aGrayscale = mPrData.grayscale; + aGrayscale = mGrayscale; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetSize ( int &aSize ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetLandscape(PRBool &landscape) { - aSize = mPrData.size; + landscape = (mOrientation == NS_LANDSCAPE); return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetPageDimensions ( float &aWidth, float &aHeight ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetTopMargin(float &value) { - if ( mPrData.size == NS_LETTER_SIZE ) { - aWidth = 8.5; - aHeight = 11.0; - } else if ( mPrData.size == NS_LEGAL_SIZE ) { - aWidth = 8.5; - aHeight = 14.0; - } else if ( mPrData.size == NS_EXECUTIVE_SIZE ) { - aWidth = 7.5; - aHeight = 10.0; - } else if ( mPrData.size == NS_A4_SIZE ) { - // 210mm X 297mm == 8.27in X 11.69in - aWidth = 8.27; - aHeight = 11.69; - } else if ( mPrData.size == NS_A3_SIZE ) { - // 297mm X 420mm == 11.69in X 16.53in - aWidth = 11.69; - aHeight = 16.53; } - - if (mPrData.orientation == NS_LANDSCAPE) { - float temp; - temp = aWidth; - aWidth = aHeight; - aHeight = temp; - } - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetLandscape ( PRBool &landscape ) -{ - landscape = (mPrData.orientation == NS_LANDSCAPE); + value = mTop; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetTopMargin ( float &value ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetBottomMargin(float &value) { - value = mPrData.top; + value = mBottom; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetBottomMargin ( float &value ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetRightMargin(float &value) { - value = mPrData.bottom; + value = mRight; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetRightMargin ( float &value ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetLeftMargin(float &value) { - value = mPrData.right; + value = mLeft; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetLeftMargin ( float &value ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetCommand(const char **aCommand) { - value = mPrData.left; + *aCommand = mCommand; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetCommand ( char **aCommand ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetPath(const char **aPath) { - *aCommand = &mPrData.command[0]; + *aPath = mPath; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetPath ( char **aPath ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetUserCancelled(PRBool &aCancel) { - *aPath = &mPrData.path[0]; + aCancel = mCancel; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecGTK :: GetUserCancelled( PRBool &aCancel ) +NS_IMETHODIMP nsDeviceContextSpecGTK::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) { - aCancel = mPrData.cancel; - return NS_OK; + return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrintMethod(PrintMethod &aMethod) { /* printer names for the PostScript module alwas start with * the NS_POSTSCRIPT_DRIVER_NAME string */ - if (strncmp(mPrData.printer, NS_POSTSCRIPT_DRIVER_NAME, + if (strncmp(mPrinter, NS_POSTSCRIPT_DRIVER_NAME, NS_POSTSCRIPT_DRIVER_NAME_LEN) != 0) aMethod = pmXprint; else @@ -472,6 +420,7 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::ClosePrintManager() return NS_OK; } + // Printer Enumerator nsPrinterEnumeratorGTK::nsPrinterEnumeratorGTK() { @@ -533,7 +482,7 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::EnumeratePrinters(PRUint32* aCount, PRUnic return NS_OK; } -NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings* aPrintSettings) +NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings) { /* fixme: We simply ignore the |aPrinter| argument here * We should get the supported printer attributes from the printer and @@ -632,5 +581,3 @@ void GlobalPrinters::FreeGlobalPrinters() mGlobalNumPrinters = 0; } - - diff --git a/gfx/src/gtk/nsDeviceContextSpecG.h b/gfx/src/gtk/nsDeviceContextSpecG.h index c8826f2be031..4073e5393583 100644 --- a/gfx/src/gtk/nsDeviceContextSpecG.h +++ b/gfx/src/gtk/nsDeviceContextSpecG.h @@ -37,18 +37,20 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef nsDeviceContextSpecG_h___ -#define nsDeviceContextSpecG_h___ +#ifndef nsDeviceContextSpecGTK_h___ +#define nsDeviceContextSpecGTK_h___ #include "nsIDeviceContextSpec.h" -#include "nsIPrintOptions.h" +#include "nsIPrintSettings.h" +#include "nsIPrintOptions.h" #include "nsVoidArray.h" #include "nsIDeviceContextSpecPS.h" -#include "nsIPrintSettings.h" #ifdef USE_XPRINT #include "nsIDeviceContextSpecXPrint.h" #endif /* USE_XPRINT */ -#include "nsPrintdGTK.h" + +#define NS_PORTRAIT 0 +#define NS_LANDSCAPE 1 typedef enum { @@ -56,85 +58,54 @@ typedef enum pmXprint, pmPostScript } PrintMethod; - -class nsDeviceContextSpecGTK : public nsIDeviceContextSpec , - public nsIDeviceContextSpecPS + +class nsDeviceContextSpecGTK : public nsIDeviceContextSpec, + public nsIDeviceContextSpecPS #ifdef USE_XPRINT - , public nsIDeviceContextSpecXp -#endif + , public nsIDeviceContextSpecXp +#endif /* USE_XPRINT */ { public: -/** - * Construct a nsDeviceContextSpecMac, which is an object which contains and manages a mac printrecord - * @update dc 12/02/98 - */ nsDeviceContextSpecGTK(); NS_DECL_ISUPPORTS -/** - * Initialize the nsDeviceContextSpecMac for use. This will allocate a printrecord for use - * @update dc 2/16/98 - * @param aQuiet if PR_TRUE, prevent the need for user intervention - * in obtaining device context spec. if nsnull is passed in for - * the aOldSpec, this will typically result in getting a device - * context spec for the default output device (i.e. default - * printer). - * @return error status - */ - NS_IMETHOD Init(nsIPrintSettings* aPS, PRBool aQuiet); - - -/** - * Closes the printmanager if it is open. - * @update dc 2/13/98 - * @update syd 3/20/99 - * @return error status - */ - - NS_IMETHOD ClosePrintManager(); - - NS_IMETHOD GetToPrinter( PRBool &aToPrinter ); - - NS_IMETHOD GetPrinterName ( char **aPrinter ); + NS_IMETHOD Init(nsIPrintSettings* aPS, PRBool aQuiet); + NS_IMETHOD ClosePrintManager(); + NS_IMETHOD GetToPrinter(PRBool &aToPrinter); + NS_IMETHOD GetPrinterName ( const char **aPrinter ); NS_IMETHOD GetCopies ( int &aCopies ); - - NS_IMETHOD GetFirstPageFirst ( PRBool &aFpf ); - - NS_IMETHOD GetGrayscale( PRBool &aGrayscale ); - - NS_IMETHOD GetSize ( int &aSize ); - - NS_IMETHOD GetTopMargin ( float &value ); - - NS_IMETHOD GetBottomMargin ( float &value ); - - NS_IMETHOD GetLeftMargin ( float &value ); - - NS_IMETHOD GetRightMargin ( float &value ); - - NS_IMETHOD GetCommand ( char **aCommand ); - - NS_IMETHOD GetPath ( char **aPath ); - - NS_IMETHOD GetPageDimensions (float &aWidth, float &aHeight ); - + NS_IMETHOD GetFirstPageFirst(PRBool &aFpf); + NS_IMETHOD GetGrayscale(PRBool &aGrayscale); + NS_IMETHOD GetTopMargin(float &value); + NS_IMETHOD GetBottomMargin(float &value); + NS_IMETHOD GetLeftMargin(float &value); + NS_IMETHOD GetRightMargin(float &value); + NS_IMETHOD GetCommand(const char **aCommand); + NS_IMETHOD GetPath (const char **aPath); NS_IMETHOD GetLandscape (PRBool &aLandscape); - - NS_IMETHOD GetUserCancelled( PRBool &aCancel ); - - NS_IMETHOD GetPrintMethod(PrintMethod &aMethod ); - -/** - * Destuct a nsDeviceContextSpecMac, this will release the printrecord - * @update dc 2/16/98 - */ + NS_IMETHOD GetUserCancelled(PRBool &aCancel); + NS_IMETHOD GetPrintMethod(PrintMethod &aMethod); + NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight); virtual ~nsDeviceContextSpecGTK(); protected: nsCOMPtr mPrintSettings; - UnixPrData mPrData; + PRBool mToPrinter; /* If PR_TRUE, print to printer */ + PRBool mFpf; /* If PR_TRUE, first page first */ + PRBool mGrayscale; /* If PR_TRUE, print grayscale */ + int mSize; /* Paper size e.g., SizeLetter */ + int mOrientation; /* Orientation e.g. Portrait */ + char mCommand[PATH_MAX]; /* Print command e.g., lpr */ + char mPath[PATH_MAX]; /* If toPrinter = PR_FALSE, dest file */ + char mPrinter[256]; /* Printer name */ + int mCopies; /* number of copies */ + PRBool mCancel; /* If PR_TRUE, user cancelled */ + float mLeft; /* left margin */ + float mRight; /* right margin */ + float mTop; /* top margin */ + float mBottom; /* bottom margin */ }; //------------------------------------------------------------------------- @@ -150,5 +121,6 @@ public: protected: }; -#endif /* !nsDeviceContextSpecG_h___ */ + +#endif /* !nsDeviceContextSpecGTK_h___ */ diff --git a/gfx/src/ps/nsAFMObject.cpp b/gfx/src/ps/nsAFMObject.cpp index 4ed5ff5eb0f3..08e83fd6da23 100644 --- a/gfx/src/ps/nsAFMObject.cpp +++ b/gfx/src/ps/nsAFMObject.cpp @@ -79,7 +79,7 @@ DefFonts gSubstituteFonts[] = */ static struct keyname_st { - char *name; + const char *name; AFMKey key; } keynames[] = { @@ -494,7 +494,7 @@ PRBool found = PR_FALSE; while((upper >=lower) && !found) { midpoint = (lower+upper)/2; - if(keynames[midpoint].name == NULL){ + if(keynames[midpoint].name == nsnull) { break; } cmpvalue = strcmp(aKey,keynames[midpoint].name); @@ -617,7 +617,7 @@ void nsAFMObject::ReadCharMetrics (AFMFontInformation *aFontInfo,PRInt32 aNumCharacters) { PRInt32 i = 0,ivalue,first=1; -AFMscm *cm = NULL; +AFMscm *cm = nsnull; AFMKey key; PRBool done = PR_FALSE; double notyet; diff --git a/gfx/src/ps/nsAFMObject.h b/gfx/src/ps/nsAFMObject.h index 025d947a27a9..f745d38aa550 100644 --- a/gfx/src/ps/nsAFMObject.h +++ b/gfx/src/ps/nsAFMObject.h @@ -164,14 +164,14 @@ typedef enum struct AFM_Single_Char_Metrics { - PRInt32 mCharacter_Code; // default charcode (-1 if not encoded) - double mW0x; // character width x in writing direction 0, - double mW0y; // character width y in writing direction 0 - double mW1x; // character width x in writing direction 1 - double mW1y; // character width y in writing direction 1 - //char *mName; // character name , not using currently - //double mVv_x; // local VVector x , not using currently - //double mVv_y; // local VVector y , not using currently + PRInt32 mCharacter_Code; // default charcode (-1 if not encoded) + double mW0x; // character width x in writing direction 0, + double mW0y; // character width y in writing direction 0 + double mW1x; // character width x in writing direction 1 + double mW1y; // character width y in writing direction 1 + //char *mName; // character name , not using currently + //double mVv_x; // local VVector x , not using currently + //double mVv_y; // local VVector y , not using currently // character bounding box. double mLlx; @@ -191,36 +191,35 @@ typedef struct AFM_Single_Char_Metrics AFMscm; // Font information which we get from AFM files, this is needed for the PS output struct fontInformation { - double mFontVersion; - char *mFontName; - char *mFullName; - char *mFamilyName; - char *mWeight; - double mFontBBox_llx; - double mFontBBox_lly; - double mFontBBox_urx; - double mFontBBox_ury; - char *mVersion; - char *mNotice; - char *mEncodingScheme; - PRInt32 mMappingScheme; - PRInt32 mEscChar; - char *mCharacterSet; - PRInt32 mCharacters; - PRBool mIsBaseFont; - double mVVector_0; - double mVVector_1; - PRBool mIsFixedV; - double mCapHeight; - double mXHeight; - double mAscender; - double mDescender; - double mUnderlinePosition; - double mUnderlineThickness; - - PRInt32 mNumCharacters; - AFMscm *mAFMCharMetrics; + double mFontVersion; + const char *mFontName; + const char *mFullName; + const char *mFamilyName; + const char *mWeight; + double mFontBBox_llx; + double mFontBBox_lly; + double mFontBBox_urx; + double mFontBBox_ury; + const char *mVersion; + const char *mNotice; + const char *mEncodingScheme; + PRInt32 mMappingScheme; + PRInt32 mEscChar; + const char *mCharacterSet; + PRInt32 mCharacters; + PRBool mIsBaseFont; + double mVVector_0; + double mVVector_1; + PRBool mIsFixedV; + double mCapHeight; + double mXHeight; + double mAscender; + double mDescender; + double mUnderlinePosition; + double mUnderlineThickness; + PRInt32 mNumCharacters; + AFMscm *mAFMCharMetrics; }; @@ -414,7 +413,7 @@ protected: /** --------------------------------------------------- * A static structure initialized with the default fonts for postscript - * @update 3/12/99 dwc + * @update 3/12/99 dwc * @member mFontName -- string with the substitute font name * @member mFontInfo -- AFM font information header created with the AFMGen program * @member mCharInfo -- Character information created with the AFMGen program @@ -422,13 +421,13 @@ protected: */ struct AFM_SubstituteFonts { -const char* mPSName; -const char* mFamily; -PRUint16 mWeight; -PRUint8 mStyle; -AFMFontInformation* mFontInfo; -AFMscm* mCharInfo; -PRInt32 mIndex; + const char* mPSName; + const char* mFamily; + PRUint16 mWeight; + PRUint8 mStyle; + AFMFontInformation* mFontInfo; + AFMscm* mCharInfo; + PRInt32 mIndex; }; typedef struct AFM_SubstituteFonts DefFonts; @@ -438,5 +437,5 @@ extern DefFonts gSubstituteFonts[]; // number of supported default fonts #define NUM_AFM_FONTS 13 -#endif +#endif /* !nsAFMObject_h__ */ diff --git a/gfx/src/ps/nsDeviceContextPS.cpp b/gfx/src/ps/nsDeviceContextPS.cpp index c21d93f34c36..ad27a885e33a 100644 --- a/gfx/src/ps/nsDeviceContextPS.cpp +++ b/gfx/src/ps/nsDeviceContextPS.cpp @@ -43,9 +43,6 @@ #include "nsFontMetricsPS.h" #include "nsPostScriptObj.h" -static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID); -static NS_DEFINE_IID(kIDeviceContextSpecPSIID, NS_IDEVICE_CONTEXT_SPEC_PS_IID); - /** --------------------------------------------------- * See documentation in nsIDeviceContext.h * @update 12/21/98 dwc @@ -63,16 +60,30 @@ nsDeviceContextPS :: nsDeviceContextPS() */ nsDeviceContextPS :: ~nsDeviceContextPS() { - NS_IF_RELEASE(mSpec); - NS_IF_RELEASE(mParentDeviceContext); + /* nsCOMPtr<> will dispose the objects... */ + mSpec = nsnull; + mParentDeviceContext = nsnull; } NS_IMETHODIMP nsDeviceContextPS :: SetSpec(nsIDeviceContextSpec* aSpec) { + nsresult rv = NS_ERROR_FAILURE; + mSpec = aSpec; - NS_ADDREF(aSpec); - return NS_OK; + + nsCOMPtr psSpec; + + mPSObj = new nsPostScriptObj(); + if (!mPSObj) + return NS_ERROR_OUT_OF_MEMORY; + + psSpec = do_QueryInterface(mSpec, &rv); + if (NS_SUCCEEDED(rv)) { + rv = mPSObj->Init(psSpec); + } + + return rv; } NS_IMPL_ISUPPORTS_INHERITED1(nsDeviceContextPS, @@ -106,7 +117,6 @@ float t2d, a2d; mParentDeviceContext = aParentContext; NS_ASSERTION(mParentDeviceContext, "aCreatingDeviceContext cannot be NULL!!!"); - NS_ADDREF(mParentDeviceContext); return NS_OK; } @@ -119,18 +129,19 @@ float t2d, a2d; */ NS_IMETHODIMP nsDeviceContextPS :: CreateRenderingContext(nsIRenderingContext *&aContext) { -nsresult rv = NS_ERROR_OUT_OF_MEMORY; + nsresult rv; + + aContext = nsnull; - aContext = new nsRenderingContextPS(); - if (nsnull != aContext){ + nsCOMPtr renderingContext = new nsRenderingContextPS(); + if (!renderingContext) + return NS_ERROR_OUT_OF_MEMORY; + + rv = renderingContext->Init(this); + + if (NS_SUCCEEDED(rv)) { + aContext = renderingContext; NS_ADDREF(aContext); - rv = ((nsRenderingContextPS*) aContext)->Init(this); - }else{ - rv = NS_ERROR_OUT_OF_MEMORY; - } - - if (NS_FAILED(rv)) { - NS_IF_RELEASE(aContext); } return rv; @@ -152,11 +163,10 @@ NS_IMETHODIMP nsDeviceContextPS :: SupportsNativeWidgets(PRBool &aSupportsWidget */ NS_IMETHODIMP nsDeviceContextPS :: GetScrollBarDimensions(float &aWidth, float &aHeight) const { - //XXX: Hardcoded values for Postscript - aWidth = 20; - aHeight = 20; + //XXX: Hardcoded values for Postscript + aWidth = 20.f; + aHeight = 20.f; return NS_OK; - } /** --------------------------------------------------- @@ -165,6 +175,7 @@ NS_IMETHODIMP nsDeviceContextPS :: GetScrollBarDimensions(float &aWidth, float & */ NS_IMETHODIMP nsDeviceContextPS :: GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface) { + aSurface = nsnull; return NS_OK; } @@ -174,7 +185,8 @@ NS_IMETHODIMP nsDeviceContextPS :: GetDrawingSurface(nsIRenderingContext &aConte */ NS_IMETHODIMP nsDeviceContextPS::GetDepth(PRUint32& aDepth) { - return(1); // postscript is 1 bit + /* PostScript module uses 24bit RGB images */ + return(24); } /** --------------------------------------------------- @@ -205,15 +217,11 @@ NS_IMETHODIMP nsDeviceContextPS::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRI nsIDeviceContextSpecPS *psSpec; nsresult rv = NS_ERROR_FAILURE; float width, height; - float top,left,right,bottom; - if ( nsnull != mSpec ) { - rv = mSpec->QueryInterface(kIDeviceContextSpecPSIID, (void **) &psSpec); - if (NS_SUCCEEDED(rv)) { - psSpec->GetPageDimensions( width, height ); - aWidth = NSToIntRound((72.0f*width) * mDevUnitsToAppUnits); - aHeight = NSToIntRound((72.0f*height) * mDevUnitsToAppUnits); - } + if (mPSObj && mPSObj->mPrintSetup) { + aWidth = NSToIntRound(mPSObj->mPrintSetup->width * mDevUnitsToAppUnits); + aHeight = NSToIntRound(mPSObj->mPrintSetup->height * mDevUnitsToAppUnits); + rv = NS_OK; } return rv; } @@ -255,18 +263,12 @@ NS_IMETHODIMP nsDeviceContextPS::GetDeviceContextFor(nsIDeviceContextSpec *aDevi * @update 12/21/98 dwc */ NS_IMETHODIMP nsDeviceContextPS::BeginDocument(PRUnichar * aTitle) -{ - nsIDeviceContextSpecPS *psSpec; - nsresult res = NS_OK; +{ + if (!mPSObj) + return NS_ERROR_NULL_POINTER; - if ( nsnull != mSpec ) { - mPSObj = new nsPostScriptObj(); - res = mSpec->QueryInterface(kIDeviceContextSpecPSIID, (void **) &psSpec); - if (NS_SUCCEEDED(res)) { - res = mPSObj->Init(psSpec,aTitle); - } - } - return res; + mPSObj->settitle(aTitle); + return NS_OK; } /** --------------------------------------------------- @@ -286,6 +288,9 @@ NS_IMETHODIMP nsDeviceContextPS::EndDocument(void) */ NS_IMETHODIMP nsDeviceContextPS::BeginPage(void) { + if (!mPSObj) + return NS_ERROR_NULL_POINTER; + // begin the page mPSObj->begin_page(); return NS_OK; diff --git a/gfx/src/ps/nsDeviceContextPS.h b/gfx/src/ps/nsDeviceContextPS.h index d83a1dd22adb..b4db87d53312 100644 --- a/gfx/src/ps/nsDeviceContextPS.h +++ b/gfx/src/ps/nsDeviceContextPS.h @@ -102,8 +102,8 @@ protected: nsDrawingSurface mSurface; PRUint32 mDepth; - nsIDeviceContextSpec *mSpec; - nsIDeviceContext *mParentDeviceContext; + nsCOMPtr mSpec; + nsCOMPtr mParentDeviceContext; nsPostScriptObj *mPSObj; public: diff --git a/gfx/src/ps/nsIDeviceContextSpecPS.h b/gfx/src/ps/nsIDeviceContextSpecPS.h index 6aa5ba068419..6c2755f61652 100644 --- a/gfx/src/ps/nsIDeviceContextSpecPS.h +++ b/gfx/src/ps/nsIDeviceContextSpecPS.h @@ -79,14 +79,6 @@ public: **/ NS_IMETHOD GetGrayscale( PRBool &aGrayscale ) = 0; - /* - * Paper size e.g., NS_LETTER_SIZE - * @update - * @param aSize -- - * @return - **/ - NS_IMETHOD GetSize ( int &aSize ) = 0; - /* * Top margin * @update @@ -125,7 +117,7 @@ public: * @param aCommand -- * @return **/ - NS_IMETHOD GetCommand ( char **aCommand ) = 0; + NS_IMETHOD GetCommand ( const char **aCommand ) = 0; /* * Printer name e.g., myprinter @@ -133,15 +125,7 @@ public: * @param aPrinter -- * @return **/ - NS_IMETHOD GetPrinterName ( char **aPrinter ) = 0; - - /* - * Get width and height based on user page size choice, e.g., 8.5 x 11.0 - * @update - * @param aWidth, aHeight - * @return - **/ - NS_IMETHOD GetPageDimensions ( float &aWidth, float &aHeight ) = 0; + NS_IMETHOD GetPrinterName ( const char **aPrinter ) = 0; /* * If PR_TRUE, user chose Landscape @@ -157,7 +141,7 @@ public: * @param aPath -- * @return **/ - NS_IMETHOD GetPath ( char **aPath ) = 0; + NS_IMETHOD GetPath ( const char **aPath ) = 0; /* * If PR_TRUE, user cancelled @@ -166,7 +150,12 @@ public: * @return **/ NS_IMETHOD GetUserCancelled( PRBool &aCancel ) = 0; + + /* + * Returns W/H in Twips from Paper Size H/W + */ + NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) = 0; }; -#endif +#endif /* !nsIDeviceContextSpecPS_h___ */ diff --git a/gfx/src/ps/nsPostScriptObj.cpp b/gfx/src/ps/nsPostScriptObj.cpp index 03242e58dac3..a814018bb3bc 100644 --- a/gfx/src/ps/nsPostScriptObj.cpp +++ b/gfx/src/ps/nsPostScriptObj.cpp @@ -49,6 +49,10 @@ #include "nsIPersistentProperties2.h" #include "nsCRT.h" +#ifndef NS_BUILD_ID +#include "nsBuildID.h" +#endif /* !NS_BUILD_ID */ + #include "prenv.h" #ifdef VMS @@ -74,11 +78,6 @@ static NS_DEFINE_CID(kPrefCID, NS_PREF_CID); static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); static NS_DEFINE_IID(kICharsetConverterManagerIID, NS_ICHARSETCONVERTERMANAGER_IID); -/* - * Paper Names - */ -const char*const paper_string[]={ "Letter", "Legal", "Executive", "A4", "A3" }; - /* * global */ @@ -122,7 +121,7 @@ FreeLangGroups(nsHashKey * aKey, void *aData, void *aClosure) } static void -PrintAsDSCTextline(FILE *f, char *text, int maxlen) +PrintAsDSCTextline(FILE *f, const char *text, int maxlen) { NS_ASSERTION(maxlen > 1, "bad max length"); @@ -188,7 +187,7 @@ nsPostScriptObj::~nsPostScriptObj() // end the document end_document(); finalize_translation(); - if ( mPrintSetup->filename != (char *) NULL ) + if ( mPrintSetup->filename != nsnull ) fclose( mPrintSetup->out ); else { #if defined(XP_OS2_VACPP) || defined(XP_PC) @@ -198,7 +197,7 @@ nsPostScriptObj::~nsPostScriptObj() #endif } #ifdef VMS - if ( mPrintSetup->print_cmd != (char *) NULL ) { + if ( mPrintSetup->print_cmd != nsnull ) { char VMSPrintCommand[1024]; PR_snprintf(VMSPrintCommand, sizeof(VMSPrintCommand), "%s /delete %s.", mPrintSetup->print_cmd, mPrintSetup->filename); @@ -241,18 +240,52 @@ nsPostScriptObj::~nsPostScriptObj() #endif /* DEBUG */ } +void +nsPostScriptObj::settitle(PRUnichar * aTitle) +{ + if (aTitle) { + mTitle = ToNewCString(nsDependentString(aTitle)); + } +} + +static +const char *paper_size_to_paper_name(float width_in_inch, float height_in_inch) +{ +#define MORE_OR_LESS_EQUAL(a, b, tolerance) (PR_ABS((a) - (b)) <= (tolerance)) +#define MATCH_PAGE(width, height, paper_width, paper_height) \ + (MORE_OR_LESS_EQUAL((width), (paper_width), 0.4f) && \ + MORE_OR_LESS_EQUAL((height), (paper_height), 0.4f)) + + // 210mm X 297mm == 8.27in X 11.69in + if (MATCH_PAGE(width_in_inch, height_in_inch, 8.27f, 11.69f)) + return "A4"; + // 297mm X 420mm == 11.69in X 16.53in + if (MATCH_PAGE(width_in_inch, height_in_inch, 11.69f, 16.53f)) + return "A3"; + if (MATCH_PAGE(width_in_inch, height_in_inch, 8.5f, 11.0f)) + return "Letter"; + if (MATCH_PAGE(width_in_inch, height_in_inch, 8.5f, 14.0f)) + return "Legal"; + if (MATCH_PAGE(width_in_inch, height_in_inch, 7.5f, 10.0f)) + return "Executive"; +#undef MATCH_PAGE +#undef MORE_OR_LESS_EQUAL + + return nsnull; +} + /** --------------------------------------------------- * See documentation in nsPostScriptObj.h * @update 2/1/99 dwc */ nsresult -nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) +nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec ) { - PRBool isGray, isAPrinter, isFirstPageFirst; - int printSize; - int landscape; - float fwidth, fheight; - char *buf; + PRBool isGray, isAPrinter, isFirstPageFirst; + int printSize; + int landscape; + float fwidth, fheight; + const char *printername; PrintInfo* pi = new PrintInfo(); mPrintSetup = new PrintSetup(); @@ -262,7 +295,6 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) mPrintSetup->color = PR_TRUE; // Image output mPrintSetup->deep_color = PR_TRUE; // 24 bit color output - mPrintSetup->paper_size = NS_LEGAL_SIZE; // Paper Size(letter,legal,exec,a4,a3) mPrintSetup->reverse = 0; // Output order, 0 is acsending if ( aSpec != nsnull ) { aSpec->GetGrayscale( isGray ); @@ -271,12 +303,19 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) mPrintSetup->deep_color = PR_FALSE; } - aSpec->GetFirstPageFirst( isFirstPageFirst ); if ( isFirstPageFirst == PR_FALSE ) mPrintSetup->reverse = 1; - aSpec->GetSize( printSize ); - mPrintSetup->paper_size = printSize; + PRInt32 paper_width_in_twips, + paper_height_in_twips; + aSpec->GetPageSizeInTwips(&paper_width_in_twips, &paper_height_in_twips); + mPrintSetup->paper_width_in_inch = NS_TWIPS_TO_INCHES(paper_width_in_twips); + mPrintSetup->paper_height_in_inch = NS_TWIPS_TO_INCHES(paper_height_in_twips); + + /* Chceck if we have a name for this paper size... */ + if (!paper_size_to_paper_name(mPrintSetup->paper_width_in_inch, mPrintSetup->paper_height_in_inch)) + return NS_ERROR_GFX_PRINTER_PAPER_SIZE_NOT_SUPPORTED; + aSpec->GetToPrinter( isAPrinter ); if (isAPrinter) { /* Define the destination printer (queue). @@ -287,39 +326,41 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) */ char *envvar; /* get printer name */ - aSpec->GetPrinterName(&buf); + aSpec->GetPrinterName(&printername); /* do not set the ${MOZ_PRINTER_NAME} env var if we want the default * printer */ - if (buf) + if (printername) { /* strip the leading NS_POSTSCRIPT_DRIVER_NAME string */ - buf = buf + NS_POSTSCRIPT_DRIVER_NAME_LEN; + printername = printername + NS_POSTSCRIPT_DRIVER_NAME_LEN; - if (!strcmp(buf, "default")) - buf = ""; + if (!strcmp(printername, "default")) + printername = ""; } else - buf = ""; + printername = ""; - envvar = (char *)malloc(strlen(buf) + /*strlen("MOZ_PRINTER_NAME=")+1*/18); + envvar = (char *)malloc(strlen(printername) + /*strlen("MOZ_PRINTER_NAME=")+1*/18); if (!envvar) return NS_ERROR_OUT_OF_MEMORY; - sprintf(envvar, "MOZ_PRINTER_NAME=%s", buf); + sprintf(envvar, "MOZ_PRINTER_NAME=%s", printername); #ifdef DEBUG printf("setting printer name via '%s'\n", envvar); #endif /* DEBUG */ PR_SetEnv(envvar); free(envvar); + + const char *command; #ifndef VMS - aSpec->GetCommand( &buf ); + aSpec->GetCommand( &command ); #if defined(XP_OS2_VACPP) || defined(XP_PC) - mPrintSetup->out = NULL; + mPrintSetup->out = nsnull; // popen not defined OS2TODO #else - mPrintSetup->out = popen( buf, "w" ); + mPrintSetup->out = popen(command, "w"); #endif - mPrintSetup->filename = (char *) NULL; + mPrintSetup->filename = nsnull; #else // We can not open a pipe and print the contents of it. Instead // we have to print to a file and then print that. @@ -328,8 +369,9 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) mPrintSetup->out = fopen(mPrintSetup->filename, "w"); #endif } else { - aSpec->GetPath( &buf ); - mPrintSetup->filename = buf; + const char *path; + aSpec->GetPath(&path); + mPrintSetup->filename = path; mPrintSetup->out = fopen(mPrintSetup->filename, "w"); if (!mPrintSetup->out) return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; @@ -347,7 +389,17 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) memset(pi, 0, sizeof(struct PrintInfo_)); mPrintSetup->dpi = 72.0f; // dpi for externally sized items - aSpec->GetPageDimensions( fwidth, fheight ); + aSpec->GetLandscape( landscape ); + fwidth = mPrintSetup->paper_width_in_inch; + fheight = mPrintSetup->paper_height_in_inch; + + if (landscape) { + float temp; + temp = fwidth; + fwidth = fheight; + fheight = temp; + } + mPrintSetup->width = (int)(fwidth * mPrintSetup->dpi); mPrintSetup->height = (int)(fheight * mPrintSetup->dpi); #ifdef DEBUG @@ -356,9 +408,8 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) #endif mPrintSetup->header = "header"; mPrintSetup->footer = "footer"; - mPrintSetup->sizes = NULL; + mPrintSetup->sizes = nsnull; - aSpec->GetLandscape( landscape ); mPrintSetup->landscape = (landscape) ? PR_TRUE : PR_FALSE; // Rotated output //mPrintSetup->landscape = PR_FALSE; @@ -388,16 +439,16 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) #else mPrintSetup->url = nsnull; #endif - mPrintSetup->completion = NULL; // Called when translation finished - mPrintSetup->carg = NULL; // Data saved for completion routine + mPrintSetup->completion = nsnull; // Called when translation finished + mPrintSetup->carg = nsnull; // Data saved for completion routine mPrintSetup->status = 0; // Status of URL on completion // "other" font is for encodings other than iso-8859-1 - mPrintSetup->otherFontName[0] = NULL; + mPrintSetup->otherFontName[0] = nsnull; // name of "other" PostScript font - mPrintSetup->otherFontInfo[0] = NULL; + mPrintSetup->otherFontInfo[0] = nsnull; // font info parsed from "other" afm file mPrintSetup->otherFontCharSetID = 0; // charset ID of "other" font - //mPrintSetup->cx = NULL; // original context, if available + //mPrintSetup->cx = nsnull; // original context, if available pi->page_height = mPrintSetup->height * 10; // Size of printable area on page pi->page_width = mPrintSetup->width * 10; // Size of printable area on page pi->page_break = 0; // Current page bottom @@ -405,15 +456,12 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle ) pi->phase = 0; - pi->pages=NULL; // Contains extents of each page + pi->pages = nsnull; // Contains extents of each page pi->pt_size = 0; // Size of above table pi->n_pages = 0; // # of valid entries in above table mTitle = nsnull; - if(nsnull != aTitle){ - mTitle = ToNewCString(nsDependentString(aTitle)); - } pi->doc_title = mTitle; pi->doc_width = 0; // Total document width @@ -440,7 +488,7 @@ void nsPostScriptObj::finalize_translation() { XP_DELETE(mPrintContext->prSetup); - mPrintContext->prSetup = NULL; + mPrintContext->prSetup = nsnull; } /** --------------------------------------------------- @@ -487,10 +535,14 @@ FILE *f; PAGE_TO_POINT_I(mPrintContext->prSetup->top), PAGE_TO_POINT_I(mPrintContext->prSetup->width-mPrintContext->prSetup->right), PAGE_TO_POINT_I(mPrintContext->prSetup->height-(mPrintContext->prSetup->bottom + mPrintContext->prSetup->top))); - fprintf(f, "%%%%Creator: Mozilla (NetScape) HTML->PS\n"); + + nsXPIDLCString useragent; + useragent.Assign("unknown"); /* Fallback */ + gPrefs->CopyCharPref("general.useragent.misc", getter_Copies(useragent)); + fprintf(f, "%%%%Creator: Mozilla PostScript module (%s/%lu)\n", useragent.get(), (unsigned long)NS_BUILD_ID); fprintf(f, "%%%%DocumentData: Clean8Bit\n"); fprintf(f, "%%%%DocumentPaperSizes: %s\n", - paper_string[mPrintContext->prSetup->paper_size]); + paper_size_to_paper_name(mPrintSetup->paper_width_in_inch, mPrintSetup->paper_height_in_inch)); fprintf(f, "%%%%Orientation: %s\n", (mPrintContext->prSetup->width < mPrintContext->prSetup->height) ? "Portrait" : "Landscape"); diff --git a/gfx/src/ps/nsPostScriptObj.h b/gfx/src/ps/nsPostScriptObj.h index 0ae1023634f2..7e4547c705ca 100644 --- a/gfx/src/ps/nsPostScriptObj.h +++ b/gfx/src/ps/nsPostScriptObj.h @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Roland Mainz * * * Alternatively, the contents of this file may be used under the terms of @@ -58,15 +59,6 @@ class nsIImage; #endif -#define NS_LETTER_SIZE 0 -#define NS_LEGAL_SIZE 1 -#define NS_EXECUTIVE_SIZE 2 -#define NS_A4_SIZE 3 -#define NS_A3_SIZE 4 - -#define NS_PORTRAIT 0 -#define NS_LANDSCAPE 1 - #define N_FONTS 8 #define INCH_TO_PAGE(f) ((int) (.5 + (f)*720)) #define PAGE_TO_POINT_I(f) ((int) ((f) / 10.0)) @@ -86,7 +78,7 @@ typedef struct { } PS_CharInfo; typedef struct { - char *name; + const char *name; PS_BBox fontBBox; short upos, uthick; PS_CharInfo chars[256]; @@ -122,9 +114,9 @@ struct PrintInfo_ { int pt_size; /* Size of above table */ int n_pages; /* # of valid entries in above table */ - char* doc_title; /* best guess at title */ - int32 doc_width; /* Total document width */ - int32 doc_height; /* Total document height */ + const char *doc_title; /* best guess at title */ + int32 doc_width; /* Total document width */ + int32 doc_height; /* Total document height */ #ifdef LATER THIS IS GOING TO BE DELETED XXXXX @@ -175,19 +167,20 @@ struct PrintSetup_ { int n_up; /* cool page combining */ int bigger; /* Used to init sizes if sizesin NULL */ int paper_size; /* Paper Size(letter,legal,exec,a4,a3) */ - + float paper_width_in_inch, /* paper width in inch */ + paper_height_in_inch; /* paper height in inch */ const char* prefix; /* For text xlate, prepended to each line */ const char* eol; /* For text translation, line terminator */ const char* bullet; /* What char to use for bullets */ struct URL_Struct_ *url; /* url of doc being translated */ - FILE *out; /* Where to send the output */ - char *filename; /* output file name, if any */ + FILE *out; /* Where to send the output */ + const char *filename; /* output file name, if any */ XL_CompletionRoutine completion; /* Called when translation finished */ void* carg; /* Data saved for completion routine */ int status; /* Status of URL on completion */ #ifdef VMS - char *print_cmd; /* print command issued in dtor*/ + const char *print_cmd; /* print command issued in dtor*/ #endif /* "other" font is for encodings other than iso-8859-1 */ @@ -225,7 +218,7 @@ public: * Init PostScript Object * @update 3/19/99 dwc */ - nsresult Init( nsIDeviceContextSpecPS *aSpec, PRUnichar * aTitle); + nsresult Init( nsIDeviceContextSpecPS *aSpec ); /** --------------------------------------------------- * Start a postscript page * @update 2/1/99 dwc @@ -413,13 +406,15 @@ public: * @update 6/1/2000 katakai */ void preshow(const PRUnichar* aText, int aLen); + + void settitle(PRUnichar * aTitle); FILE * GetPrintFile(); PRBool InitUnixPrinterProps(); PRBool GetUnixPrinterSetting(const nsCAutoString&, char**); + PrintSetup *mPrintSetup; private: PSContext *mPrintContext; - PrintSetup *mPrintSetup; PRUint16 mPageNumber; nsCOMPtr mPrinterProps; char *mTitle; diff --git a/gfx/src/ps/nsRenderingContextPS.cpp b/gfx/src/ps/nsRenderingContextPS.cpp index 95ceafa81519..d86aa0b4f0e8 100644 --- a/gfx/src/ps/nsRenderingContextPS.cpp +++ b/gfx/src/ps/nsRenderingContextPS.cpp @@ -38,13 +38,12 @@ #include "nsRenderingContextPS.h" #include "nsFontMetricsPS.h" -#include #include "nsDeviceContextPS.h" #include "nsPostScriptObj.h" #include "nsIRegion.h" #include "nsIImage.h" -static NS_DEFINE_IID(kIRenderingContextIID, NS_IRENDERING_CONTEXT_IID); +#include // Macro to convert from TWIPS (1440 per inch) to POINTS (72 per inch) #define NS_PIXELS_TO_POINTS(x) (x * 10) @@ -83,13 +82,13 @@ public: */ PS_State :: PS_State() { - mNext = nsnull; + mNext = nsnull; mMatrix.SetToIdentity(); mLocalClip.x = mLocalClip.y = mLocalClip.width = mLocalClip.height = 0; - mFontMetrics = nsnull; + mFontMetrics = nsnull; mCurrentColor = NS_RGB(0, 0, 0); - mTextColor = NS_RGB(0, 0, 0); - mLineStyle = nsLineStyle_kSolid; + mTextColor = NS_RGB(0, 0, 0); + mLineStyle = nsLineStyle_kSolid; } /** --------------------------------------------------- @@ -97,13 +96,15 @@ PS_State :: PS_State() * Default Constructor for the state * @update 12/21/98 dwc */ -PS_State :: PS_State(PS_State &aState):mMatrix(&aState.mMatrix),mLocalClip(aState.mLocalClip) +PS_State :: PS_State(PS_State &aState) : + mMatrix(&aState.mMatrix), + mLocalClip(aState.mLocalClip) { mNext = &aState; - //mClipRegion = NULL; + //mClipRegion = nsnull; mCurrentColor = aState.mCurrentColor; mFontMetrics = nsnull; - //mFont = NULL; + //mFont = nsnull; mFlags = ~FLAGS_ALL; mTextColor = aState.mTextColor; mLineStyle = aState.mLineStyle; @@ -115,18 +116,17 @@ PS_State :: PS_State(PS_State &aState):mMatrix(&aState.mMatrix),mLocalClip(aStat */ PS_State :: ~PS_State() { - //if (NULL != mClipRegion){ + //if (nsnull != mClipRegion){ //VERIFY(::DeleteObject(mClipRegion)); - //mClipRegion = NULL; + //mClipRegion = nsnull; //} //don't delete this because it lives in the font metrics - //mFont = NULL; + //mFont = nsnull; } -static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID); - +NS_IMPL_THREADSAFE_ISUPPORTS1(nsRenderingContextPS, nsIRenderingContext) /** --------------------------------------------------- * See documentation in nsIRenderingContext.h @@ -171,40 +171,6 @@ nsRenderingContextPS :: ~nsRenderingContextPS() mTranMatrix = nsnull; } -/** --------------------------------------------------- - * See documentation in nsIRenderingContext.h - * @update 12/21/98 dwc - */ -nsresult -nsRenderingContextPS :: QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - - if (nsnull == aInstancePtr) - return NS_ERROR_NULL_POINTER; - - if (aIID.Equals(kIRenderingContextIID)){ - nsIRenderingContext* tmp = this; - *aInstancePtr = (void*) tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - - static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - - if (aIID.Equals(kISupportsIID)){ - nsIRenderingContext* tmp = this; - nsISupports* tmp2 = tmp; - *aInstancePtr = (void*) tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsRenderingContextPS) -NS_IMPL_RELEASE(nsRenderingContextPS) - /** --------------------------------------------------- * See documentation in nsIRenderingContext.h * @update 12/21/98 dwc @@ -1112,7 +1078,7 @@ PRInt32 y = aY; } mTranMatrix->TransformCoord(&x, &y); - PostscriptTextOut(aString, aLength, NS_PIXELS_TO_POINTS(x), NS_PIXELS_TO_POINTS(y), aLength, (const nscoord*) (aSpacing ? dx0 : NULL), PR_FALSE); + PostscriptTextOut(aString, aLength, NS_PIXELS_TO_POINTS(x), NS_PIXELS_TO_POINTS(y), aLength, (const nscoord*) (aSpacing ? dx0 : nsnull), PR_FALSE); if ((nsnull != aSpacing) && (dx0 != dxMem)) { delete [] dx0; diff --git a/gfx/src/ps/nsRenderingContextPS.h b/gfx/src/ps/nsRenderingContextPS.h index b1e1032afc1e..c2eb01572cb9 100644 --- a/gfx/src/ps/nsRenderingContextPS.h +++ b/gfx/src/ps/nsRenderingContextPS.h @@ -76,8 +76,8 @@ protected: public: // nsIRenderingContext NS_IMETHOD Init(nsIDeviceContext* aContext); - NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget){return NS_OK;} - NS_IMETHOD Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface){return NS_OK;} + NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget) {return NS_ERROR_NOT_IMPLEMENTED;} + NS_IMETHOD Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface) {return NS_ERROR_NOT_IMPLEMENTED;} NS_IMETHOD Reset(void); diff --git a/gfx/src/xlib/nsDeviceContextSpecXlib.cpp b/gfx/src/xlib/nsDeviceContextSpecXlib.cpp index 58e303a9985c..1ce2fd8df48a 100644 --- a/gfx/src/xlib/nsDeviceContextSpecXlib.cpp +++ b/gfx/src/xlib/nsDeviceContextSpecXlib.cpp @@ -106,7 +106,7 @@ NS_IMPL_ISUPPORTS3(nsDeviceContextSpecXlib, NS_IMPL_ISUPPORTS2(nsDeviceContextSpecXlib, nsIDeviceContextSpec, nsIDeviceContextSpecPS) -#endif +#endif /* USE_XPRINT */ /** ------------------------------------------------------- */ @@ -190,12 +190,12 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings* aPS, PRBool aQuiet { nsresult rv = NS_ERROR_FAILURE; - NS_ASSERTION(nsnull != aPS, "No print settings."); - + mPrintSettings = aPS; + // if there is a current selection then enable the "Selection" radio button - if (aPS != nsnull) { + if (mPrintSettings) { PRBool isOn; - aPS->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); + mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { (void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn); @@ -208,7 +208,6 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings* aPS, PRBool aQuiet PRBool color = PR_FALSE; PRBool tofile = PR_FALSE; PRInt16 printRange = nsIPrintSettings::kRangeAllPages; - PRInt32 paper_size = NS_LETTER_SIZE; PRInt32 orientation = NS_PORTRAIT; PRInt32 fromPage = 1; PRInt32 toPage = 1; @@ -227,8 +226,8 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings* aPS, PRBool aQuiet } if (!aQuiet ) { - rv = DisplayXPDialog(aPS, - "chrome://global/content/printdialog.xul", canPrint); + rv = DisplayXPDialog(mPrintSettings, + "chrome://global/content/printdialog.xul", canPrint); } else { canPrint = PR_TRUE; @@ -241,7 +240,6 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings* aPS, PRBool aQuiet aPS->GetPrinterName(&printer); aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); - aPS->GetPaperSize(&paper_size); aPS->GetOrientation(&orientation); aPS->GetPrintCommand(&command); aPS->GetPrintRange(&printRange); @@ -257,67 +255,64 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings* aPS, PRBool aQuiet if (command != nsnull && printfile != nsnull) { // ToDo: Use LocalEncoding instead of UTF-8 (see bug 73446) - strcpy(mPrData.command, NS_ConvertUCS2toUTF8(command).get()); - strcpy(mPrData.path, NS_ConvertUCS2toUTF8(printfile).get()); + strcpy(mCommand, NS_ConvertUCS2toUTF8(command).get()); + strcpy(mPath, NS_ConvertUCS2toUTF8(printfile).get()); } if (printer != nsnull) - strcpy(mPrData.printer, NS_ConvertUCS2toUTF8(printer).get()); + strcpy(mPrinter, NS_ConvertUCS2toUTF8(printer).get()); #ifdef DEBUG_rods - printf("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright); + printf("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", + dtop, dleft, dbottom, dright); printf("printRange %d\n", printRange); printf("fromPage %d\n", fromPage); printf("toPage %d\n", toPage); + printf("tofile %d\n", tofile); + printf("printfile %s\n", + printfile? NS_ConvertUCS2toUTF8(printfile).get():"NULL"); + printf("command %s\n", + command? NS_ConvertUCS2toUTF8(command).get():"NULL"); + printf("printer %s\n", + printer? NS_ConvertUCS2toUTF8(printer).get():"NULL"); #endif /* DEBUG_rods */ } else { #ifdef VMS // Note to whoever puts the "lpr" into the prefs file. Please contact me // as I need to make the default be "print" instead of "lpr" for OpenVMS. - strcpy(mPrData.command, "print"); + strcpy(mCommand, "print"); #else - strcpy(mPrData.command, "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}"); + strcpy(mCommand, "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}"); #endif /* VMS */ } - mPrData.top = dtop; - mPrData.bottom = dbottom; - mPrData.left = dleft; - mPrData.right = dright; - mPrData.fpf = !reversed; - mPrData.grayscale = !color; - mPrData.size = paper_size; - mPrData.orientation = orientation; - mPrData.toPrinter = !tofile; - mPrData.copies = copies; + mTop = dtop; + mBottom = dbottom; + mLeft = dleft; + mRight = dright; + mFpf = !reversed; + mGrayscale = !color; + mOrientation = orientation; + mToPrinter = !tofile; + mCopies = copies; // PWD, HOME, or fail if (!printfile) { if ( ( path = PR_GetEnv( "PWD" ) ) == (char *) nsnull ) if ( ( path = PR_GetEnv( "HOME" ) ) == (char *) nsnull ) - strcpy(mPrData.path, "mozilla.ps"); + strcpy(mPath, "mozilla.ps"); if ( path != (char *) nsnull ) - sprintf(mPrData.path, "%s/mozilla.ps", path); + sprintf(mPath, "%s/mozilla.ps", path); else return NS_ERROR_FAILURE; } - -#ifdef NOT_IMPLEMENTED_YET - if (globalNumPrinters) { - for(int i = 0; (i < globalNumPrinters) && !mQueue; i++) { - if (!(mGlobalPrinterList->StringAt(i)->CompareWithConversion(mPrData.printer, TRUE, -1))) - mQueue = PrnDlg.SetPrinterQueue(i); - } - } -#endif /* NOT_IMPLEMENTED_YET */ - + if (command != nsnull) { nsMemory::Free(command); } if (printfile != nsnull) { nsMemory::Free(printfile); } - return NS_OK; } @@ -326,124 +321,92 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings* aPS, PRBool aQuiet NS_IMETHODIMP nsDeviceContextSpecXlib::GetToPrinter(PRBool &aToPrinter) { - aToPrinter = mPrData.toPrinter; + aToPrinter = mToPrinter; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecXlib::GetPrinterName ( char **aPrinter ) +NS_IMETHODIMP nsDeviceContextSpecXlib::GetPrinterName ( const char **aPrinter ) { - *aPrinter = &mPrData.printer[0]; + *aPrinter = mPrinter; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetCopies ( int &aCopies ) { - aCopies = mPrData.copies; + aCopies = mCopies; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetFirstPageFirst(PRBool &aFpf) { - aFpf = mPrData.fpf; + aFpf = mFpf; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetGrayscale(PRBool &aGrayscale) { - aGrayscale = mPrData.grayscale; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecXlib::GetSize(int &aSize) -{ - aSize = mPrData.size; - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextSpecXlib::GetPageDimensions(float &aWidth, float &aHeight) -{ - if (mPrData.size == NS_LETTER_SIZE) { - aWidth = 8.5; - aHeight = 11.0; - } else if (mPrData.size == NS_LEGAL_SIZE) { - aWidth = 8.5; - aHeight = 14.0; - } else if (mPrData.size == NS_EXECUTIVE_SIZE) { - aWidth = 7.5; - aHeight = 10.0; - } else if (mPrData.size == NS_A4_SIZE) { - // 210mm X 297mm == 8.27in X 11.69in - aWidth = 8.27; - aHeight = 11.69; - } else if (mPrData.size == NS_A3_SIZE) { - // 297mm X 420mm == 11.69in X 16.53in - aWidth = 11.69; - aHeight = 16.53; - } - - if (mPrData.orientation == NS_LANDSCAPE) { - float temp; - temp = aWidth; - aWidth = aHeight; - aHeight = temp; - } - + aGrayscale = mGrayscale; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetLandscape(PRBool &landscape) { - landscape = (mPrData.orientation == NS_LANDSCAPE); + landscape = (mOrientation == NS_LANDSCAPE); return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetTopMargin(float &value) { - value = mPrData.top; + value = mTop; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetBottomMargin(float &value) { - value = mPrData.bottom; + value = mBottom; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetRightMargin(float &value) { - value = mPrData.right; + value = mRight; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetLeftMargin(float &value) { - value = mPrData.left; + value = mLeft; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecXlib::GetCommand(char **aCommand) +NS_IMETHODIMP nsDeviceContextSpecXlib::GetCommand(const char **aCommand) { - *aCommand = &mPrData.command[0]; + *aCommand = mCommand; return NS_OK; } -NS_IMETHODIMP nsDeviceContextSpecXlib::GetPath(char **aPath) +NS_IMETHODIMP nsDeviceContextSpecXlib::GetPath(const char **aPath) { - *aPath = &mPrData.path[0]; + *aPath = mPath; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecXlib::GetUserCancelled(PRBool &aCancel) { - aCancel = mPrData.cancel; + aCancel = mCancel; return NS_OK; } +NS_IMETHODIMP nsDeviceContextSpecXlib::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) +{ + return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); +} + NS_IMETHODIMP nsDeviceContextSpecXlib::GetPrintMethod(PrintMethod &aMethod) { /* printer names for the PostScript module alwas start with * the NS_POSTSCRIPT_DRIVER_NAME string */ - if (strncmp(mPrData.printer, NS_POSTSCRIPT_DRIVER_NAME, + if (strncmp(mPrinter, NS_POSTSCRIPT_DRIVER_NAME, NS_POSTSCRIPT_DRIVER_NAME_LEN) != 0) aMethod = pmXprint; else diff --git a/gfx/src/xlib/nsDeviceContextSpecXlib.h b/gfx/src/xlib/nsDeviceContextSpecXlib.h index 38583af659fa..57d6cdcd9848 100644 --- a/gfx/src/xlib/nsDeviceContextSpecXlib.h +++ b/gfx/src/xlib/nsDeviceContextSpecXlib.h @@ -48,7 +48,9 @@ #ifdef USE_XPRINT #include "nsIDeviceContextSpecXPrint.h" #endif /* USE_XPRINT */ -#include "nsPrintdXlib.h" + +#define NS_PORTRAIT 0 +#define NS_LANDSCAPE 1 typedef enum { @@ -68,29 +70,41 @@ public: NS_DECL_ISUPPORTS - NS_IMETHOD Init(nsIPrintSettings* aPS, PRBool aQuiet); + NS_IMETHOD Init(nsIPrintSettings* aPS, PRBool aQuiet); NS_IMETHOD ClosePrintManager(); NS_IMETHOD GetToPrinter(PRBool &aToPrinter); - NS_IMETHOD GetPrinterName ( char **aPrinter ); + NS_IMETHOD GetPrinterName ( const char **aPrinter ); NS_IMETHOD GetCopies ( int &aCopies ); NS_IMETHOD GetFirstPageFirst(PRBool &aFpf); NS_IMETHOD GetGrayscale(PRBool &aGrayscale); - NS_IMETHOD GetSize(int &aSize); NS_IMETHOD GetTopMargin(float &value); NS_IMETHOD GetBottomMargin(float &value); NS_IMETHOD GetLeftMargin(float &value); NS_IMETHOD GetRightMargin(float &value); - NS_IMETHOD GetCommand(char **aCommand); - NS_IMETHOD GetPath (char **aPath); - NS_IMETHOD GetPageDimensions(float &aWidth, float &aHeight); + NS_IMETHOD GetCommand(const char **aCommand); + NS_IMETHOD GetPath (const char **aPath); NS_IMETHOD GetLandscape (PRBool &aLandscape); NS_IMETHOD GetUserCancelled(PRBool &aCancel); - NS_IMETHOD GetPrintMethod(PrintMethod &aMethod); + NS_IMETHOD GetPrintMethod(PrintMethod &aMethod); + NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight); virtual ~nsDeviceContextSpecXlib(); protected: - UnixPrData mPrData; + nsCOMPtr mPrintSettings; + PRBool mToPrinter; /* If PR_TRUE, print to printer */ + PRBool mFpf; /* If PR_TRUE, first page first */ + PRBool mGrayscale; /* If PR_TRUE, print grayscale */ + int mOrientation; /* Orientation e.g. Portrait */ + char mCommand[PATH_MAX]; /* Print command e.g., lpr */ + char mPath[PATH_MAX]; /* If toPrinter = PR_FALSE, dest file */ + char mPrinter[256]; /* Printer name */ + int mCopies; /* number of copies */ + PRBool mCancel; /* If PR_TRUE, user cancelled */ + float mLeft; /* left margin */ + float mRight; /* right margin */ + float mTop; /* top margin */ + float mBottom; /* bottom margin */ }; //------------------------------------------------------------------------- diff --git a/gfx/src/xlib/nsFontMetricsXlib.cpp b/gfx/src/xlib/nsFontMetricsXlib.cpp index ca8c0ff0c562..c3fa2f89364f 100644 --- a/gfx/src/xlib/nsFontMetricsXlib.cpp +++ b/gfx/src/xlib/nsFontMetricsXlib.cpp @@ -2688,9 +2688,6 @@ nsFontMetricsXlib::PickASizeAndLoad(nsFontStretchXlib* aStretch, bitmap_size = (*s)->mSize; } -#ifndef ABS -#define ABS(a) (((a) < 0) ? -(a) : (a)) -#endif /* !ABS */ // if we do not have the correct size // check if we can use a scaled font // (when the size of a hand tuned font is close to the desired size @@ -2702,7 +2699,7 @@ nsFontMetricsXlib::PickASizeAndLoad(nsFontStretchXlib* aStretch, // if it is allowed to be closer than the bitmap if (aStretch->mOutlineScaled) { scale_size = PR_MAX(mPixelSize, aCharSet->mOutlineScaleMin); - if (ABS(mPixelSize - scale_size) < ABS(mPixelSize - bitmap_size)) { + if (PR_ABS(mPixelSize - scale_size) < PR_ABS(mPixelSize - bitmap_size)) { use_scaled_font = PR_TRUE; } } @@ -2713,7 +2710,7 @@ nsFontMetricsXlib::PickASizeAndLoad(nsFontStretchXlib* aStretch, double ratio = (bitmap_size / ((double) mPixelSize)); if ((ratio < aCharSet->mBitmapUndersize) || (ratio > aCharSet->mBitmapOversize)) { - if ((ABS(mPixelSize - scale_size) < ABS(mPixelSize - bitmap_size))) { + if ((PR_ABS(mPixelSize - scale_size) < PR_ABS(mPixelSize - bitmap_size))) { use_scaled_font = PR_TRUE; } } diff --git a/gfx/src/xlib/nsPrintdXlib.cpp b/gfx/src/xlib/nsPrintdXlib.cpp index f6a492fc73d5..e69de29bb2d1 100644 --- a/gfx/src/xlib/nsPrintdXlib.cpp +++ b/gfx/src/xlib/nsPrintdXlib.cpp @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape 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/NPL/ - * - * 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 - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Modified: syd@netscape.com 10/18/99 wired in margins - * Vino Fernando Crescini - * - * - * 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 NPL, 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 NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include "nsPrintdXlib.h" - -void UnixPrDialog(UnixPrData *prData) -{ - // IMPLEMENT ME - // Draw a print dialog using Xlib - - return; -} diff --git a/gfx/src/xlib/nsPrintdXlib.h b/gfx/src/xlib/nsPrintdXlib.h index 79a2d341deda..e69de29bb2d1 100644 --- a/gfx/src/xlib/nsPrintdXlib.h +++ b/gfx/src/xlib/nsPrintdXlib.h @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape 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/NPL/ - * - * 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 - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Vino Fernando Crescini - * Roland Mainz - * - * - * 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 NPL, 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 NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsPrintdXlib_h___ -#define nsPrintdxlib_h___ - -#include - -PR_BEGIN_EXTERN_C - -#ifndef NS_LEGAL_SIZE -#define NS_LETTER_SIZE 0 -#define NS_LEGAL_SIZE 1 -#define NS_EXECUTIVE_SIZE 2 -#define NS_A4_SIZE 3 -#define NS_A3_SIZE 4 - -#define NS_PORTRAIT 0 -#define NS_LANDSCAPE 1 -#endif - -#ifndef PATH_MAX -#ifdef _POSIX_PATH_MAX -#define PATH_MAX _POSIX_PATH_MAX -#else -#define PATH_MAX 256 -#endif -#endif - -typedef struct unixprdata { - PRBool toPrinter; /* If PR_TRUE, print to printer */ - PRBool fpf; /* If PR_TRUE, first page first */ - PRBool grayscale; /* If PR_TRUE, print grayscale */ - int size; /* Paper size e.g., SizeLetter */ - int orientation; /* Orientation e.g. Portrait */ - char command[PATH_MAX]; /* Print command e.g., lpr */ - char path[PATH_MAX]; /* If toPrinter = PR_FALSE, dest file */ - char printer[256]; /* Printer name */ - int copies; /* number of copies */ - PRBool cancel; /* If PR_TRUE, user cancelled */ - float left; /* left margin */ - float right; /* right margin */ - float top; /* top margin */ - float bottom; /* bottom margin */ -} UnixPrData; - -void UnixPrDialog(UnixPrData *prData); - -PR_END_EXTERN_C - -#endif /* !nsPrintdXlib_h___ */ - diff --git a/gfx/src/xlib/nsRenderingContextXlib.cpp b/gfx/src/xlib/nsRenderingContextXlib.cpp index 5801745a20ad..814c4c7e6001 100644 --- a/gfx/src/xlib/nsRenderingContextXlib.cpp +++ b/gfx/src/xlib/nsRenderingContextXlib.cpp @@ -105,7 +105,6 @@ nsRenderingContextXlib::nsRenderingContextXlib() mFontMetrics = nsnull; mTranMatrix = nsnull; mP2T = 1.0f; - mStateCache = new nsVoidArray(); mCurrentFont = nsnull; mCurrentLineStyle = nsLineStyle_kSolid; mCurrentColor = NS_RGB(0, 0, 0); /* X11 intial bg color is always _black_... @@ -127,15 +126,11 @@ nsRenderingContextXlib::~nsRenderingContextXlib() { PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContextXlib::~nsRenderingContextXlib()\n")); NS_IF_RELEASE(mFontMetrics); - if (mStateCache) { - PRInt32 cnt = mStateCache->Count(); + PRInt32 cnt = mStateCache.Count(); - while (--cnt >= 0) { - PRBool clipstate; - PopState(clipstate); - } - delete mStateCache; - mStateCache = nsnull; + while (--cnt >= 0) { + PRBool clipstate; + PopState(clipstate); } if (mTranMatrix) @@ -161,8 +156,9 @@ nsRenderingContextXlib::Init(nsIDeviceContext* aContext, nsIWidget *aWindow) PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContextXlib::Init(DeviceContext, Widget)\n")); nsDrawingSurfaceXlibImpl *surf; // saves some cast stunts - mContext = do_QueryInterface(aContext); - NS_ASSERTION(nsnull != mContext, "Device context is null."); + NS_ENSURE_TRUE(aContext != nsnull, NS_ERROR_NULL_POINTER); + NS_ENSURE_TRUE(aWindow != nsnull, NS_ERROR_NULL_POINTER); + mContext = aContext; nsIDeviceContext *dc = mContext; NS_STATIC_CAST(nsDeviceContextX *, dc)->GetXlibRgbHandle(mXlibRgbHandle); @@ -175,7 +171,7 @@ nsRenderingContextXlib::Init(nsIDeviceContext* aContext, nsIWidget *aWindow) if (surf) { Drawable win = (Drawable)aWindow->GetNativeData(NS_NATIVE_WINDOW); - xGC *gc = (xGC*)aWindow->GetNativeData(NS_NATIVE_GRAPHIC); + xGC *gc = (xGC *)aWindow->GetNativeData(NS_NATIVE_GRAPHIC); surf->Init(mXlibRgbHandle, win, @@ -194,8 +190,8 @@ nsRenderingContextXlib::Init(nsIDeviceContext* aContext, nsDrawingSurface aSurfa { PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContxtXlib::Init(DeviceContext, DrawingSurface)\n")); - mContext = do_QueryInterface(aContext); - NS_ASSERTION(nsnull != mContext, "Device context is null."); + NS_ENSURE_TRUE(nsnull != aContext, NS_ERROR_NULL_POINTER); + mContext = aContext; nsIDeviceContext *dc = mContext; NS_STATIC_CAST(nsDeviceContextX *, dc)->GetXlibRgbHandle(mXlibRgbHandle); @@ -235,8 +231,9 @@ nsresult nsRenderingContextXlib::CommonInit(void) (long)mDisplay, (long)drawable, (long)root_win, (int)x, (int)y, (int)width, (int)height, (int)border, (int)depth)); - mClipRegion = do_QueryInterface(new nsRegionXlib()); - if (!mClipRegion) return NS_ERROR_OUT_OF_MEMORY; + mClipRegion = new nsRegionXlib(); + if (!mClipRegion) + return NS_ERROR_OUT_OF_MEMORY; mClipRegion->Init(); mClipRegion->SetTo(0, 0, width, height); @@ -332,7 +329,7 @@ nsRenderingContextXlib::PushState(void) state->mMatrix = mTranMatrix; - mStateCache->AppendElement(state); + mStateCache.AppendElement(state); if (nsnull == mTranMatrix) mTranMatrix = new nsTransform2D(); @@ -341,8 +338,9 @@ nsRenderingContextXlib::PushState(void) if (mClipRegion) { state->mClipRegion = mClipRegion; - mClipRegion = do_QueryInterface(new nsRegionXlib()); - if (!mClipRegion) return NS_ERROR_OUT_OF_MEMORY; + mClipRegion = new nsRegionXlib(); + if (!mClipRegion) + return NS_ERROR_OUT_OF_MEMORY; mClipRegion->Init(); mClipRegion->SetTo(*state->mClipRegion); } @@ -360,12 +358,12 @@ nsRenderingContextXlib::PopState(PRBool &aClipState) { PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContextXlib::PopState()\n")); - PRUint32 cnt = mStateCache->Count(); + PRUint32 cnt = mStateCache.Count(); GraphicsState *state; if (cnt > 0) { - state = (GraphicsState *)mStateCache->ElementAt(cnt - 1); - mStateCache->RemoveElementAt(cnt - 1); + state = (GraphicsState *)mStateCache.ElementAt(cnt - 1); + mStateCache.RemoveElementAt(cnt - 1); if (mTranMatrix) delete mTranMatrix; diff --git a/gfx/src/xlib/nsRenderingContextXlib.h b/gfx/src/xlib/nsRenderingContextXlib.h index 2ca04cd25b55..1d45e7c92950 100644 --- a/gfx/src/xlib/nsRenderingContextXlib.h +++ b/gfx/src/xlib/nsRenderingContextXlib.h @@ -247,7 +247,7 @@ protected: int mDepth; // graphics state stuff - nsVoidArray *mStateCache; + nsAutoVoidArray mStateCache; nsFontXlib *mCurrentFont; nsLineStyle mCurrentLineStyle; xGC *mGC; diff --git a/gfx/src/xprint/nsDeviceContextXP.cpp b/gfx/src/xprint/nsDeviceContextXP.cpp index 1747802c70cf..261bf749ae01 100644 --- a/gfx/src/xprint/nsDeviceContextXP.cpp +++ b/gfx/src/xprint/nsDeviceContextXP.cpp @@ -72,7 +72,7 @@ nsDeviceContextXp :: ~nsDeviceContextXp() NS_IMETHODIMP -nsDeviceContextXp :: SetSpec(nsIDeviceContextSpec* aSpec) +nsDeviceContextXp::SetSpec(nsIDeviceContextSpec* aSpec) { nsresult rv = NS_ERROR_FAILURE; @@ -82,11 +82,15 @@ nsDeviceContextXp :: SetSpec(nsIDeviceContextSpec* aSpec) mSpec = aSpec; - if(mPrintContext) DestroyXPContext(); // we cannot reuse that... + if (mPrintContext) + DestroyXPContext(); // we cannot reuse that... mPrintContext = new nsXPrintContext(); - xpSpec = do_QueryInterface(mSpec); - if(xpSpec) { + if (!mPrintContext) + return NS_ERROR_OUT_OF_MEMORY; + + xpSpec = do_QueryInterface(mSpec, &rv); + if (NS_SUCCEEDED(rv)) { rv = mPrintContext->Init(this, xpSpec); } @@ -140,20 +144,22 @@ nsDeviceContextXp::InitDeviceContextXP(nsIDeviceContext *aCreatingDeviceContext, */ NS_IMETHODIMP nsDeviceContextXp :: CreateRenderingContext(nsIRenderingContext *&aContext) { - nsresult rv = NS_ERROR_OUT_OF_MEMORY; + nsresult rv; + + aContext = nsnull; - nsCOMPtr xpContext; + nsCOMPtr renderingContext = new nsRenderingContextXp(); + if (!renderingContext) + return NS_ERROR_OUT_OF_MEMORY; + + rv = renderingContext->Init(this); - xpContext = new nsRenderingContextXp(); - if (xpContext) { - rv = xpContext->Init(this); - } + if (NS_SUCCEEDED(rv)) { + aContext = renderingContext; + NS_ADDREF(aContext); + } - if (NS_SUCCEEDED(rv)) { - aContext = xpContext; - NS_ADDREF(aContext); - } - return rv; + return rv; } /** --------------------------------------------------- diff --git a/gfx/src/xprint/nsIDeviceContextSpecXPrint.h b/gfx/src/xprint/nsIDeviceContextSpecXPrint.h index a82d2112b549..4e93db8dc314 100644 --- a/gfx/src/xprint/nsIDeviceContextSpecXPrint.h +++ b/gfx/src/xprint/nsIDeviceContextSpecXPrint.h @@ -74,14 +74,6 @@ public: **/ NS_IMETHOD GetGrayscale( PRBool &aGrayscale ) = 0; - /* - * Paper size e.g., NS_LETTER_SIZE - * @update - * @param aSize -- - * @return - **/ - NS_IMETHOD GetSize ( int &aSize ) = 0; - /* * Top margin * @update @@ -120,15 +112,7 @@ public: * @param aPrinter -- * @return **/ - NS_IMETHOD GetPrinterName ( char **aPrinter ) = 0; - - /* - * Get width and height based on user page size choice, e.g., 8.5 x 11.0 - * @update - * @param aWidth, aHeight - * @return - **/ - NS_IMETHOD GetPageDimensions ( float &aWidth, float &aHeight ) = 0; + NS_IMETHOD GetPrinterName ( const char **aPrinter ) = 0; /* * If PR_TRUE, user chose Landscape @@ -144,7 +128,7 @@ public: * @param aPath -- * @return **/ - NS_IMETHOD GetPath ( char **aPath ) = 0; + NS_IMETHOD GetPath ( const char **aPath ) = 0; /* * If PR_TRUE, user cancelled @@ -152,7 +136,20 @@ public: * @param aCancel -- * @return **/ - NS_IMETHOD GetUserCancelled( PRBool &aCancel ) = 0; + NS_IMETHOD GetUserCancelled( PRBool &aCancel ) = 0; + + /* + * Returns W/H in Twips from Paper Size H/W + */ + NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) = 0; + + /* + * Return number of copies to print + * @update + * @param aCopies + * @return + **/ + NS_IMETHOD GetCopies ( int &aCopies ) = 0; }; #endif /* !nsIDeviceContextSpecXP_h___ */ diff --git a/gfx/src/xprint/nsRenderingContextXp.cpp b/gfx/src/xprint/nsRenderingContextXp.cpp index d5645643326c..08901ddb08a8 100644 --- a/gfx/src/xprint/nsRenderingContextXp.cpp +++ b/gfx/src/xprint/nsRenderingContextXp.cpp @@ -70,13 +70,13 @@ nsRenderingContextXp::Init(nsIDeviceContext* aContext) { PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::Init(nsIDeviceContext *)\n")); - mContext = do_QueryInterface(aContext); - NS_ASSERTION(nsnull != mContext, "Device context is null."); + NS_ENSURE_TRUE(nsnull != aContext, NS_ERROR_NULL_POINTER); + mContext = aContext; if (mContext) { nsIDeviceContext *dc = mContext; NS_STATIC_CAST(nsDeviceContextXp *,dc)->GetPrintContext(mPrintContext); } - NS_ASSERTION(nsnull != mPrintContext, "mPrintContext is null."); + NS_ENSURE_TRUE(nsnull != mPrintContext, NS_ERROR_NULL_POINTER); mPrintContext->GetXlibRgbHandle(mXlibRgbHandle); mDisplay = xxlib_rgb_get_display(mXlibRgbHandle); diff --git a/gfx/src/xprint/nsXPrintContext.cpp b/gfx/src/xprint/nsXPrintContext.cpp index 462ca6991ba4..cff3f919ee8d 100644 --- a/gfx/src/xprint/nsXPrintContext.cpp +++ b/gfx/src/xprint/nsXPrintContext.cpp @@ -106,25 +106,24 @@ PR_END_EXTERN_C /** --------------------------------------------------- * Default Constructor */ -nsXPrintContext::nsXPrintContext() +nsXPrintContext::nsXPrintContext() : + mXlibRgbHandle(nsnull), + mPDisplay(nsnull), + mPContext(None), + mScreen(nsnull), + mVisual(nsnull), + mDrawable(None), + mGC(nsnull), + mDepth(0), + mIsGrayscale(PR_FALSE), /* default is color output */ + mIsAPrinter(PR_TRUE), /* default destination is printer */ + mPrintFile(nsnull), + mXpuPrintToFileHandle(nsnull), + mPrintResolution(0L), + mContext(nsnull) { NS_INIT_REFCNT(); PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::nsXPrintContext()\n")); - - mXlibRgbHandle = (XlibRgbHandle *)nsnull; - mPDisplay = (Display *)nsnull; - mPContext = (XPContext)None; - mScreen = (Screen *)nsnull; - mVisual = (Visual *)nsnull; - mDrawable = (Drawable)None; - mGC = nsnull; - mDepth = 0; - mIsGrayscale = PR_FALSE; /* default is color output */ - mIsAPrinter = PR_TRUE; /* default destination is printer */ - mPrintFile = nsnull; - mXpuPrintToFileHandle = nsnull; - mPrintResolution = 0L; - mContext = nsnull; } /** --------------------------------------------------- @@ -141,22 +140,16 @@ nsXPrintContext::~nsXPrintContext() mGC->Release(); mGC = nsnull; } - - if (mPContext != None) - { - XPU_TRACE(XpDestroyContext(mPDisplay, mPContext)); - mPContext = None; - } - + if (mXlibRgbHandle) { xxlib_rgb_destroy_handle(mXlibRgbHandle); mXlibRgbHandle = nsnull; } - - XPU_TRACE(XCloseDisplay(mPDisplay)); + XPU_TRACE(XpuClosePrinterDisplay(mPDisplay, mPContext)); mPDisplay = nsnull; + mPContext = None; } PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::~nsXPrintContext() done.\n")); @@ -366,26 +359,130 @@ nsXPrintContext::SetupWindow(int x, int y, int width, int height) } +nsresult nsXPrintContext::SetPageSize(float page_width_mm, float page_height_mm) +{ + nsresult rv = NS_ERROR_GFX_PRINTER_PAPER_SIZE_NOT_SUPPORTED; + XpuMediumSourceSizeList mlist; + int mlist_count; + int i; + + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("SetPageSize: Requested page width_mm=%f, page height_mm=%f\n", + (double)page_width_mm, (double)page_height_mm)); + + mlist = XpuGetMediumSourceSizeList(mPDisplay, mPContext, &mlist_count); + if( !mlist || mlist_count == 0 ) + { + return NS_ERROR_GFX_PRINTER_PAPER_SIZE_NOT_SUPPORTED; + } + + XpuMediumSourceSizeRec *match = nsnull; + +#ifdef PR_LOGGING + /* Print page sizes for the log... */ + for( i = 0 ; i < mlist_count ; i++ ) + { + XpuMediumSourceSizeRec *curr = &mlist[i]; + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("got '%s'/'%s'\t%d %f %f %f %f\n", + XPU_NULLXSTR(curr->tray_name), curr->medium_name, curr->mbool, + curr->ma1, curr->ma2, curr->ma3, curr->ma4)); + } +#endif /* PR_LOGGING */ + + /* Tolerate +/- 2mm due conversion/rounding errors and different notations */ + match = XpuFindMediumSourceSizeBySize(mlist, mlist_count, page_width_mm, page_height_mm, 2.0f); + + /* No match ? + * The "try again" with a tolerance if +/- 10mm + */ + if (!match) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, + ("No match found in first attempt, trying again with 10mm tolerance...\n")); + match = XpuFindMediumSourceSizeBySize(mlist, mlist_count, page_width_mm, page_height_mm, 10.0f); + } + + /* Found a match ? */ + if (match) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, + ("match %s/%s !\n", XPU_NULLXSTR(match->tray_name), match->medium_name)); + if( XpuSetDocMediumSourceSize(mPDisplay, mPContext, match) == 1 ) + rv = NS_OK; + } + + XpuFreeMediumSourceSizeList(mlist); + + return rv; +} + +nsresult nsXPrintContext::SetOrientation(int landscape) +{ + const char *orientation; + XpuOrientationList list; + int list_count; + XpuOrientationRec *match; + + /* which orientation ? */ + switch( landscape ) + { + case 1 /* NS_LANDSCAPE */: orientation = "landscape"; break; + case 0 /* NS_PORTRAIT */: orientation = "portrait"; break; + default: + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, + ("Unsupported orientation %d.\n", landscape)); + return NS_ERROR_GFX_PRINTER_ORIENTATION_NOT_SUPPORTED; + } + + /* Print the used orientation to the log... */ + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("orientation=%s\n", orientation)); + + /* Get list of supported orientations */ + list = XpuGetOrientationList(mPDisplay, mPContext, &list_count); + if( !list || list_count == 0 ) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuGetOrientationList() failure.\n")); + return NS_ERROR_GFX_PRINTER_ORIENTATION_NOT_SUPPORTED; + } + + /* Find requested orientation */ + match = XpuFindOrientationByName(list, list_count, orientation ); + if (!match) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuFindOrientationByName() failure.\n")); + return NS_ERROR_GFX_PRINTER_ORIENTATION_NOT_SUPPORTED; + } + + /* Set orientation */ + if (XpuSetDocOrientation(mPDisplay, mPContext, match) != 1) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuSetDocOrientation() failure.\n")); + return NS_ERROR_GFX_PRINTER_ORIENTATION_NOT_SUPPORTED; + } + + return NS_OK; +} + + nsresult nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetupPrintContext()\n")); - int printSize; - float top, bottom, left, right; - int landscape; - char *buf; - nsresult rv; + float top, bottom, left, right; + int landscape; + int num_copies; + const char *printername; + nsresult rv; // Get the Attributes aSpec->GetToPrinter(mIsAPrinter); aSpec->GetGrayscale(mIsGrayscale); - aSpec->GetSize(printSize); aSpec->GetTopMargin(top); aSpec->GetBottomMargin(bottom); aSpec->GetLeftMargin(left); aSpec->GetRightMargin(right); aSpec->GetLandscape(landscape); + aSpec->GetCopies(num_copies); PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetupPrintContext: borders top=%f, bottom=%f, left=%f, right=%f\n", @@ -394,7 +491,7 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) /* get destination printer (we need this when printing to file as * the printer DDX in Xprt generates the data...) */ - aSpec->GetPrinterName(&buf); + aSpec->GetPrinterName(&printername); /* Are we "printing" to a file instead to the print queue ? */ if (!mIsAPrinter) @@ -421,12 +518,12 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) /* get printer, either by "name" (foobar) or "name@display" (foobar@gaja:5) * ToDo: report error to user (dialog) */ - if( XpuGetPrinter(buf, &mPDisplay, &mPContext) != 1 ) + if( XpuGetPrinter(printername, &mPDisplay, &mPContext) != 1 ) return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND; PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetupPrintContext: name='%s', display='%s', vendor='%s', release=%ld\n", - buf, + printername, XDisplayString(mPDisplay), XServerVendor(mPDisplay), (long)XVendorRelease(mPDisplay))); @@ -434,32 +531,31 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) if (NS_FAILED(rv = AlertBrokenXprt(mPDisplay))) return rv; + if( XpQueryExtension(mPDisplay, &mXpEventBase, &mXpErrorBase) == False ) + return NS_ERROR_UNEXPECTED; + #ifdef XPRINT_DEBUG_SOMETIMES_USEFULL dumpXpAttributes(mPDisplay, mPContext); -#endif /* DEBUG */ +#endif /* XPRINT_DEBUG_SOMETIMES_USEFULL */ + + PRInt32 page_width_in_twips, + page_height_in_twips; + float page_width_mm, + page_height_mm; - /* which orientation ? */ - switch (landscape) - { - case 1 /* NS_LANDSCAPE */: - if (XpuSetContentOrientation(mPDisplay,mPContext, XPDocAttr, "landscape") != 1) - { - NS_WARNING("orientation 'landscape' not supported on this printer"); - return NS_ERROR_FAILURE; - } - break; - case 0 /* NS_PORTRAIT */: - if (XpuSetContentOrientation(mPDisplay,mPContext, XPDocAttr, "portrait") != 1) - { - NS_WARNING("orientation 'portrait' not supported on this printer"); - return NS_ERROR_FAILURE; - } - break; - default: - NS_WARNING("unsupported orientation"); - return NS_ERROR_FAILURE; - } + aSpec->GetPageSizeInTwips(&page_width_in_twips, &page_height_in_twips); + page_width_mm = NS_TWIPS_TO_MILLIMETERS(page_width_in_twips); + page_height_mm = NS_TWIPS_TO_MILLIMETERS(page_height_in_twips); + + if (NS_FAILED(XPU_TRACE(rv = SetPageSize(page_width_mm, page_height_mm)))) + return rv; + + if (NS_FAILED(XPU_TRACE(rv = SetOrientation(landscape)))) + return rv; + if (XPU_TRACE(XpuSetDocumentCopies(mPDisplay, mPContext, num_copies)) != 1) + return NS_ERROR_GFX_PRINTER_TOO_MANY_COPIES; + /* set printer context * WARNING: after this point it is no longer allows to change job attributes * only after the XpSetContext() call the alllication is allowed to make @@ -468,6 +564,10 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) */ XPU_TRACE(XpSetContext(mPDisplay, mPContext)); +#ifdef XPRINT_DEBUG_SOMETIMES_USEFULL + dumpXpAttributes(mPDisplay, mPContext); +#endif /* XPRINT_DEBUG_SOMETIMES_USEFULL */ + /* get default printer resolution. May fail if Xprt is misconfigured. * ToDo: Report error to user (dialog) */ @@ -524,24 +624,22 @@ nsXPrintContext::BeginDocument( PRUnichar *aTitle ) // Check the output type if(mIsAPrinter) { - XPU_TRACE(XpStartJob(mPDisplay, XPSpool)); - XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartJobNotify)); + XPU_TRACE(XpuStartJobToSpooler(mPDisplay)); } else { - XPU_TRACE(XpStartJob(mPDisplay, XPGetData)); - - if( XPU_TRACE(mXpuPrintToFileHandle = XpuPrintToFile(mPDisplay, mPContext, mPrintFile)) == nsnull ) + if( XPU_TRACE(mXpuPrintToFileHandle = XpuStartJobToFile(mPDisplay, mPContext, mPrintFile)) == nsnull ) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::BeginDocument(): XpuPrintToFile failure %s/(%d)\n", strerror(errno), errno)); return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; - } - - XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartJobNotify)); + } } + + XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, mXpEventBase, XPStartJobNotify)); + return NS_OK; } @@ -553,7 +651,7 @@ nsXPrintContext::BeginPage() // XMoveWindow(mPDisplay, mDrawable, 100, 100); XPU_TRACE(XpStartPage(mPDisplay, mDrawable)); - XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartPageNotify)); + XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, mXpEventBase, XPStartPageNotify)); return NS_OK; } @@ -562,7 +660,7 @@ NS_IMETHODIMP nsXPrintContext::EndPage() { XPU_TRACE(XpEndPage(mPDisplay)); - XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPEndPageNotify)); + XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, mXpEventBase, XPEndPageNotify)); return NS_OK; } @@ -571,7 +669,7 @@ NS_IMETHODIMP nsXPrintContext::EndDocument() { XPU_TRACE(XpEndJob(mPDisplay)); - XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPEndJobNotify)); + XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, mXpEventBase, XPEndJobNotify)); /* Are we printing to a file ? */ if( !mIsAPrinter ) @@ -696,8 +794,8 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, int prev_res = 0, dummy; long imageResolution; - PRInt32 aDWidth_scaled; - PRInt32 aDHeight_scaled; + PRInt32 aDWidth_scaled, + aDHeight_scaled; nsresult rv = NS_OK; PRInt32 aSrcWidth = aImage->GetWidth(); @@ -731,17 +829,20 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, scalingFactor *= (scale_x < scale_y)?(scale_x):(scale_y); /* Adjust destination size to the match the scaling factor */ - imageResolution = double(mPrintResolution) * scalingFactor; - aDWidth_scaled = double(aDWidth) * scalingFactor; - aDHeight_scaled = double(aDHeight) * scalingFactor; - - NS_ASSERTION(!((aDWidth_scaled <= 0) || (aDHeight_scaled <= 0)), - "Image scaled to zero width/height"); - NS_ASSERTION(!(imageResolution <= 0), - "Image resolution must not be 0"); + imageResolution = long( double(mPrintResolution) * scalingFactor); + aDWidth_scaled = PRInt32(double(aDWidth) * scalingFactor); + aDHeight_scaled = PRInt32(double(aDHeight) * scalingFactor); /* Image scaled to 0 width/height ? */ - if( (aDWidth_scaled <= 0) || (aDHeight_scaled <= 0) || (imageResolution <= 0)) + NS_ASSERTION(!((aDWidth_scaled <= 0) || (aDHeight_scaled <= 0)), + "Image scaled to zero width/height"); + if( (aDWidth_scaled <= 0) || (aDHeight_scaled <= 0) ) + return NS_OK; + + /* Image scaled to zero-width/height ? */ + NS_ASSERTION(imageResolution != 0, "Image resolution must not be 0"); + NS_ASSERTION(imageResolution >= 0, "Image resolution must not be negative"); + if( imageResolution <= 0 ) return NS_OK; /* Set image resolution */ diff --git a/gfx/src/xprint/nsXPrintContext.h b/gfx/src/xprint/nsXPrintContext.h index d4ec800b8b8e..e898c3d93e2b 100644 --- a/gfx/src/xprint/nsXPrintContext.h +++ b/gfx/src/xprint/nsXPrintContext.h @@ -113,6 +113,8 @@ private: Visual *mVisual; Drawable mDrawable; /* window */ xGC *mGC; + int mXpEventBase, /* XpExtension X event base */ + mXpErrorBase; /* XpExtension X error base */ int mDepth; int mScreenNumber; int mWidth; @@ -120,13 +122,16 @@ private: XPContext mPContext; PRBool mIsGrayscale; /* color or grayscale ? */ PRBool mIsAPrinter; /* destination: printer or file ? */ - char *mPrintFile; /* file to "print" to */ + const char *mPrintFile; /* file to "print" to */ void *mXpuPrintToFileHandle; /* handle for XpuPrintToFile/XpuWaitForPrintFileChild when printing to file */ long mPrintResolution; nsDeviceContextXp *mContext; /* DeviceContext which created this object */ nsresult SetupWindow(int x, int y, int width, int height); nsresult SetupPrintContext(nsIDeviceContextSpecXp *aSpec); + nsresult SetPageSize(float page_width_mm, float page_height_mm); + nsresult SetOrientation(int landscape); + }; diff --git a/gfx/src/xprint/xprintutil.c b/gfx/src/xprint/xprintutil.c index c6e4a9a10244..a5ff87304eec 100644 --- a/gfx/src/xprint/xprintutil.c +++ b/gfx/src/xprint/xprintutil.c @@ -41,6 +41,8 @@ #include #ifdef XPU_USE_NSPR +#include "plstr.h" +#undef strtok_r #define strtok_r(s1, s2, x) PL_strtok_r((s1), (s2), (x)) #endif /* USE_MOZILLA_TYPES */ @@ -52,6 +54,19 @@ #define FREE_WRITABLE_STRING(str) free((void *)(str)) #define STRING_AS_WRITABLE(str) ((char *)(str)) +/* Local prototypes */ +static const char *XpuGetDefaultXpPrintername(void); +static const char *XpuGetXpServerList( void ); +static const char *XpuEnumerateXpAttributeValue( const char *value, void **vcptr ); +static const char *XpuGetCurrentAttributeGroup( void **vcptr ); +static void XpuDisposeEnumerateXpAttributeValue( void **vc ); +static Bool XpuEnumerateMediumSourceSizes( Display *pdpy, XPContext pcontext, + const char **tray_name, + const char **medium_name, int *mbool, + float *ma1, float *ma2, float *ma3, float *ma4, + void **vcptr ); +static void XpuDisposeEnumerateMediumSourceSizes( void **vc ); + /* ** XprintUtil functions start with Xpu ** @@ -76,7 +91,33 @@ int XpuCheckExtension( Display *pdpy ) return(0); } +/* Get the default printer name from the XPRINTER env var. + * If XPRINTER env var is not present looks for PDPRINTER, LPDEST, and + * PRINTER (in that order) + * See CDE's DtPrintSetupBox(3) manual page, too... + */ +static +const char *XpuGetDefaultXpPrintername(void) +{ + const char *s; + /* BUG/TODO: XpPrinter resource needs to be sourced, too... */ + s = getenv("XPRINTER"); + if( !s ) + { + s = getenv("PDPRINTER"); + if( !s ) + { + s = getenv("LPDEST"); + if( !s ) + { + s = getenv("PRINTER"); + } + } + } + return s; +} +static const char *XpuGetXpServerList( void ) { const char *s; @@ -203,11 +244,22 @@ int XpuGetPrinter( const char *arg_printername, Display **pdpyptr, XPContext *pc } +void XpuClosePrinterDisplay(Display *pdpy, XPContext pcontext) +{ + if( pdpy ) + { + if( pcontext != None ) + XpDestroyContext(pdpy, pcontext); + + XCloseDisplay(pdpy); + } +} + void XpuSetOneAttribute( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name, const char *value, XPAttrReplacement replacement_rule ) { /* Alloc buffer for sprintf() stuff below */ - char *buffer = malloc(strlen(attribute_name)+strlen(value)+4); + char *buffer = (char *)malloc(strlen(attribute_name)+strlen(value)+4); if( buffer != NULL ) { @@ -217,6 +269,20 @@ void XpuSetOneAttribute( Display *pdpy, XPContext pcontext, } } +void XpuSetOneLongAttribute( Display *pdpy, XPContext pcontext, + XPAttributes type, const char *attribute_name, long value, XPAttrReplacement replacement_rule ) +{ + /* Alloc buffer for sprintf() stuff below */ + char *buffer = (char *)malloc(strlen(attribute_name)+32+4); + + if( buffer != NULL ) + { + sprintf(buffer, "%s: %ld", attribute_name, value); + XpSetAttributes(pdpy, pcontext, type, buffer, replacement_rule); + free(buffer); + } +} + /* check if attribute value is supported or not */ int XpuCheckSupported( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name, const char *query ) { @@ -237,18 +303,18 @@ int XpuCheckSupported( Display *pdpy, XPContext pcontext, XPAttributes type, con { const char *s; - for( s = XpuEmumerateXpAttributeValue(value, &tok_lasts) ; s != NULL ; s = XpuEmumerateXpAttributeValue(NULL, &tok_lasts) ) + for( s = XpuEnumerateXpAttributeValue(value, &tok_lasts) ; s != NULL ; s = XpuEnumerateXpAttributeValue(NULL, &tok_lasts) ) { XPU_DEBUG_ONLY(printf("XpuCheckSupported: probing '%s'=='%s'\n", XPU_NULLXSTR(s), XPU_NULLXSTR(query))); if( !strcmp(s, query) ) { XFree(value); - XpuDisposeEmumerateXpAttributeValue(&tok_lasts); + XpuDisposeEnumerateXpAttributeValue(&tok_lasts); return(1); } } - XpuDisposeEmumerateXpAttributeValue(&tok_lasts); + XpuDisposeEnumerateXpAttributeValue(&tok_lasts); XFree(value); } @@ -270,30 +336,6 @@ int XpuSetJobTitle( Display *pdpy, XPContext pcontext, const char *title ) } } - -int XpuSetContentOrientation( Display *pdpy, XPContext pcontext, XPAttributes type, const char *orientation ) -{ - /* fixme: check whether the given |orientation| is supported or not... */ - if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "content-orientations-supported", orientation) ) - { - XpuSetOneAttribute(pdpy, pcontext, type, "*content-orientation", orientation, XPAttrMerge); - return(1); - } - else - { - XPU_DEBUG_ONLY(printf("XpuSetContentOrientation: XpuCheckSupported failed for '%s'\n", XPU_NULLXSTR(orientation))); - return(0); - } -} - -/* ToDo: Implement -const char *XpuGetContentOrientation( Display *pdpy, XPContext pcontext, XPAttributes type ); -*/ - -/* ToDo: -.* XpuGetPlex(), XpuSetPlex() - */ - int XpuGetOneLongAttribute( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name, long *result ) { char *s; @@ -325,7 +367,6 @@ int XpuGetOneLongAttribute( Display *pdpy, XPContext pcontext, XPAttributes type if( s != NULL ) XFree(s); - XPU_DEBUG_ONLY(puts("XpuGetOneLongAttribute failed\n")); FREE_WRITABLE_STRING(attribute_name); return(0); @@ -336,84 +377,52 @@ int XpuGetOneLongAttribute( Display *pdpy, XPContext pcontext, XPAttributes type /* debug only */ void dumpXpAttributes( Display *pdpy, XPContext pcontext ) { - /* BUG: values from XpuGet*Attributes should be passed to XFree() after use... :-) */ + char *s; printf("------------------------------------------------\n"); - printf("--> Job\n%s\n", XpuGetJobAttributes(pdpy, pcontext)); - printf("--> Doc\n%s\n", XpuGetDocAttributes(pdpy, pcontext)); - printf("--> Page\n%s\n", XpuGetPageAttributes(pdpy, pcontext)); - printf("--> Printer\n%s\n", XpuGetPrinterAttributes(pdpy, pcontext)); - printf("--> Server\n%s\n", XpuGetServerAttributes(pdpy, pcontext)); + printf("--> Job\n%s\n", s=XpuGetJobAttributes(pdpy, pcontext)); XFree(s); + printf("--> Doc\n%s\n", s=XpuGetDocAttributes(pdpy, pcontext)); XFree(s); + printf("--> Page\n%s\n", s=XpuGetPageAttributes(pdpy, pcontext)); XFree(s); + printf("--> Printer\n%s\n", s=XpuGetPrinterAttributes(pdpy, pcontext)); XFree(s); + printf("--> Server\n%s\n", s=XpuGetServerAttributes(pdpy, pcontext)); XFree(s); printf("image resolution %d\n", (int)XpGetImageResolution(pdpy, pcontext)); printf("------------------------------------------------\n"); } #endif /* DEBUG */ -/* BUG: Is it really neccesary that this function eats-up all other events ? */ -void XpuWaitForPrintNotify( Display *pdpy, int detail ) +typedef struct XpuIsNotifyEventContext_ { - /* Xprt |Display *| for which "event_base_return" and "error_base_return" are valid */ - static Display *ext_display = NULL; - static int event_base_return = -1, - error_base_return = -1; - XEvent ev; + int event_base; + int detail; +} XpuIsNotifyEventContext; + +static +Bool IsXpNotifyEvent( Display *pdpy, XEvent *ev, XPointer arg ) +{ + Bool match; + XpuIsNotifyEventContext *context = (XpuIsNotifyEventContext *)arg; + XPPrintEvent *pev = (XPPrintEvent *)ev; - /* get extension event_base if we did not get it yet (and if Xserver does not - * support extension do not wait for events which will never be send... :-) - */ - if( ((event_base_return == -1) && (error_base_return == -1)) || (ext_display != pdpy) ) - { - int myevent_base_return, myerror_base_return; - - if( XpQueryExtension(pdpy, &myevent_base_return, &myerror_base_return) == False ) - { - XPU_DEBUG_ONLY(printf("XpuWaitForPrintNotify: XpQueryExtension failed\n")); - return; - } - - /* be sure we don't get in trouble if two threads try the same thing :-) - */ - event_base_return = myevent_base_return; - error_base_return = myerror_base_return; - ext_display = pdpy; - } - - do - { - XNextEvent(pdpy, &ev); - if( ev.type != (event_base_return+XPPrintNotify) ) - { - XPU_DEBUG_ONLY(printf("XpuWaitForPrintNotify: Killing non-PrintNotify event %d/%d while waiting for %d/%d\n", - (int)ev.type, (int)((XPPrintEvent *)(&ev))->detail, - (int)(event_base_return+XPPrintNotify), detail)); - } - } while( !((ev.type == (event_base_return+XPPrintNotify)) && (((XPPrintEvent *)(&ev))->detail == detail)) ); + match = pev->type == (context->event_base+XPPrintNotify) && + pev->detail == context->detail; + + XPU_DEBUG_ONLY(printf("XpuWaitForPrintNotify: %d=IsXpNotifyEvent(%d,%d)\n", + (int)match, + (int)pev->type, + (int)pev->detail)); + return match; +} + +void XpuWaitForPrintNotify( Display *pdpy, int xp_event_base, int detail ) +{ + XEvent dummy; + XpuIsNotifyEventContext matchcontext; + + matchcontext.event_base = xp_event_base; + matchcontext.detail = detail; + XIfEvent(pdpy, &dummy, IsXpNotifyEvent, (XPointer)&matchcontext); } -/* set print resolution - * Retun error if printer does not support this resolution - */ -Bool XpuSetResolution( Display *pdpy, XPContext pcontext, long dpi ) -{ - /* not implemented yet */ - return False; -} - -/* get default printer reolution - * this function may fail in the following conditions: - * - Xprt misconfiguration - * - X DPI != Y DPI (not yet implemented in Xprt) - */ -Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi_ptr ) -{ - if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", dpi_ptr) == 1 ) - { - return True; - } - - return False; -} - static const char *skip_matching_brackets(const char *start) { @@ -432,6 +441,8 @@ const char *skip_matching_brackets(const char *start) case '}': level--; break; } } while(level > 0); + + return(s); } @@ -456,18 +467,24 @@ const char *search_next_space(const char *start) } } -/* PRIVATE context data for XpuEmumerateXpAttributeValue() */ +/* PRIVATE context data for XpuEnumerateXpAttributeValue() */ typedef struct _XpuAttributeValueEnumeration { - char *value; - char *start; - char *s; + char *value; + size_t original_value_len; /* original length of value */ + char *group; + char *start; + char *s; } XpuAttributeValueEnumeration; -const char *XpuEmumerateXpAttributeValue( const char *value, void **vcptr ) + +/* Hacked parser for Xp values and enumerations */ +static +const char *XpuEnumerateXpAttributeValue( const char *value, void **vcptr ) { XpuAttributeValueEnumeration **cptr = (XpuAttributeValueEnumeration **)vcptr; XpuAttributeValueEnumeration *context; + const char *tmp; if( !cptr ) return(NULL); @@ -476,20 +493,43 @@ const char *XpuEmumerateXpAttributeValue( const char *value, void **vcptr ) { XpuAttributeValueEnumeration *e; const char *s = value; + Bool isGroup = FALSE; - e = malloc(sizeof(XpuAttributeValueEnumeration)); + e = (XpuAttributeValueEnumeration *)malloc(sizeof(XpuAttributeValueEnumeration)); if( !e ) return NULL; - /* skip leading '{'. */ - while(*s=='{') + /* Skip leading '{'. */ + while(*s=='{' && isGroup==FALSE) + { s++; - /* skip leading blanks or '\''. */ - while(isspace(*s) || *s=='\'') + isGroup = TRUE; + } + /* Skip leading blanks. */ + while(isspace(*s)) s++; - - e->start = e->s = e->value = strdup(s); + + e->group = NULL; + + /* Read group name. */ + if( isGroup ) + { + tmp = s; + while(!isspace(*s)) + s++; + if(strncmp(tmp, "''", s-tmp) != 0) + { + e->group = strdup(tmp); + e->group[s-tmp] = '\0'; + } + } + e->original_value_len = strlen(s); + e->value = (char *)malloc(e->original_value_len+4); /* We may look up to three bytes beyond the string */ + strcpy(e->value, s); + memset(e->value+e->original_value_len+1, 0, 3); /* quad termination */ + e->start = e->s = e->value; + *cptr = e; } @@ -499,7 +539,7 @@ const char *XpuEmumerateXpAttributeValue( const char *value, void **vcptr ) return(NULL); /* Skip leading blanks, '\'' or '}' */ - while(isspace(*(context->s)) || *(context->s)=='\'' || *(context->s)=='}' ) + while(isspace(*(context->s)) || *(context->s)=='\'' /*|| *(context->s)=='}'*/ ) context->s++; if( *(context->s) == '\0' ) @@ -518,24 +558,69 @@ const char *XpuEmumerateXpAttributeValue( const char *value, void **vcptr ) context->s++; } + /* Check if we reached a new attribute group */ + tmp = context->start; + while(isspace(*tmp)) + tmp++; + if( *tmp=='}' ) + { + void *prev_cptr = *vcptr; + + tmp+=2; /* We have 3*'\0' at the end of the string - this is legal! */ + if( *tmp!='\0' ) + { + const char *ret; + + /* Start the parser again */ + *vcptr = NULL; + ret = XpuEnumerateXpAttributeValue(tmp, vcptr); + + /* Free old context */ + XpuDisposeEnumerateXpAttributeValue(&prev_cptr); + + return(ret); + } + else + { + return(NULL); + } + } + return(context->start); } +/* Get enumeration group for last string returned by |XpuEnumerateXpAttributeValue|... */ +static +const char *XpuGetCurrentAttributeGroup( void **vcptr ) +{ + XpuAttributeValueEnumeration **cptr = (XpuAttributeValueEnumeration **)vcptr; + if( !cptr ) + return(NULL); + if( !*cptr ) + return(NULL); + + return((*cptr)->group); +} -void XpuDisposeEmumerateXpAttributeValue( void **vc ) + +static +void XpuDisposeEnumerateXpAttributeValue( void **vc ) { if( vc ) { XpuAttributeValueEnumeration *context = *((XpuAttributeValueEnumeration **)vc); free(context->value); + if(context->group) + free(context->group); free(context); } } /* parse a paper size string * (example: '{na-letter False {6.3500 209.5500 6.3500 273.0500}}') */ +static Bool XpuParseMediumSourceSize( const char *value, - const char **media_name, Bool *mbool, + const char **medium_name, int *mbool, float *ma1, float *ma2, float *ma3, float *ma4 ) { const char *s; @@ -549,9 +634,9 @@ Bool XpuParseMediumSourceSize( const char *value, value_len = strlen(value); - /* alloc buffer for "media_name" and |boolbuf| in one step + /* alloc buffer for |medium_name| and |boolbuf| in one step * (both must be large enougth to hold at least |strlen(value)+1| bytes) */ - name = malloc(value_len*2 + 4); + name = (char *)malloc(value_len*2 + 4); boolbuf = name + value_len+2; /* |boolbuf| starts directly after |name| */ /* remove '{' && '}' */ @@ -568,7 +653,7 @@ Bool XpuParseMediumSourceSize( const char *value, } while(*s); - /* seperate media name from string */ + /* seperate medium name from string */ d = (char *)search_next_space(name); if( !d ) { @@ -576,7 +661,7 @@ Bool XpuParseMediumSourceSize( const char *value, return(False); } *d = '\0'; - *media_name = name; + *medium_name = name; /* ... continue to parse the remaining string... */ d++; @@ -586,7 +671,7 @@ Bool XpuParseMediumSourceSize( const char *value, free(name); return(False); } - + if( !strcmp(boolbuf, "true") ) *mbool = True; else if( !strcmp(boolbuf, "false") ) @@ -596,22 +681,80 @@ Bool XpuParseMediumSourceSize( const char *value, free(name); return(False); } - return(True); } + +/* parse a paper size string + * (example: '{na-letter False {6.3500 209.5500 6.3500 273.0500}}') */ +static +Bool XpuEnumerateMediumSourceSizes( Display *pdpy, XPContext pcontext, + const char **tray_name, + const char **medium_name, int *mbool, + float *ma1, float *ma2, float *ma3, float *ma4, + void **vcptr ) +{ + const char *medium_spec; + const char *value = NULL; + + if( pdpy && pcontext ) + { + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "medium-source-sizes-supported"); + if( !value ) + return(False); + } + + while(1) + { + medium_spec = XpuEnumerateXpAttributeValue(value, vcptr); + + if( value ) + { + XFree((void *)value); + value = NULL; + } + + /* enumeration done? */ + if( !medium_spec ) + return(False); + + if (XpuParseMediumSourceSize(medium_spec, + medium_name, mbool, + ma1, ma2, ma3, ma4)) + { + *tray_name = XpuGetCurrentAttributeGroup(vcptr); + return(True); + } + else + { + /* Should never ever happen! */ + fprintf(stderr, "XpuEnumerateMediumSourceSize: error parsing '%s'", medium_spec); + } + } + /* not reached */ +} + +static +void XpuDisposeEnumerateMediumSourceSizes( void **vc ) +{ + XpuDisposeEnumerateXpAttributeValue(vc); +} + + /* future: Migrate this functionality into |XpGetPrinterList| - just do * not pass a |Display *| to |XpGetPrinterList| */ XPPrinterList XpuGetPrinterList( const char *printer, int *res_list_count ) { XPPrinterRec *rec = NULL; - int rec_count = 1; /* allocate one more XPPrinterRec structure + int rec_count = 1; /* Allocate one more |XPPrinterRec| structure * as terminator */ char *sl; - + const char *default_printer_name = XpuGetDefaultXpPrintername(); + int default_printer_rec_index = -1; + if( !res_list_count ) - return(NULL); + return(NULL); sl = strdup(XpuGetXpServerList()); MAKE_STRING_WRITABLE(printer); @@ -643,15 +786,30 @@ XPPrinterList XpuGetPrinterList( const char *printer, int *res_list_count ) for( i = 0 ; i < list_count ; i++ ) { char *s; - rec_count++; - rec = realloc(rec, sizeof(XPPrinterRec)*rec_count); + rec_count++; + rec = (XPPrinterRec *)realloc(rec, sizeof(XPPrinterRec)*rec_count); if( !rec ) /* failure */ break; - s = malloc(strlen(list[i].name)+display_len+4); + s = (char *)malloc(strlen(list[i].name)+display_len+4); sprintf(s, "%s@%s", list[i].name, display); rec[rec_count-2].name = s; rec[rec_count-2].desc = (list[i].desc)?(strdup(list[i].desc)):(NULL); + + /* Test for default printer (if the user set one).*/ + if( default_printer_name ) + { + /* Default_printer_name may either contain the FQPN(=full + * qualified printer name ("foo@myhost:5") or just the name + * ("foo")) */ + if( (!strcmp(list[i].name, default_printer_name)) || + (!strcmp(s, default_printer_name)) ) + { + /* Remember index of default printer that we can swap it to + * the head of the array below... */ + default_printer_rec_index = rec_count-2; + } + } } XpFreePrinterList(list); @@ -667,7 +825,10 @@ XPPrinterList XpuGetPrinterList( const char *printer, int *res_list_count ) if( rec ) { /* users: DO NOT COUNT ON THIS DETAIL - * (this is only to make current impl. of XpuFreePrinterList() easier) */ + * (this is only to make current impl. of XpuFreePrinterList() easier) + * I may remove this implementation detail in a later revision of + * the library! + */ rec[rec_count-1].name = NULL; rec[rec_count-1].desc = NULL; rec_count--; @@ -676,6 +837,15 @@ XPPrinterList XpuGetPrinterList( const char *printer, int *res_list_count ) { rec_count = 0; } + + /* The default printer is always the first one in the printer list... */ + if( (default_printer_rec_index != -1) && rec ) + { + XPPrinterRec tmp; + tmp = rec[0]; + rec[0] = rec[default_printer_rec_index]; + rec[default_printer_rec_index] = tmp; + } *res_list_count = rec_count; FREE_WRITABLE_STRING(printer); @@ -687,12 +857,15 @@ void XpuFreePrinterList( XPPrinterList list ) { if( list ) { - XPPrinterList curr = list; + XPPrinterRec *curr = list; - while(curr->name!=NULL) + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->name != NULL ) { free(curr->name); - free(curr->desc); + if(curr->desc) + free(curr->desc); curr++; } @@ -700,4 +873,666 @@ void XpuFreePrinterList( XPPrinterList list ) } } +/* Set number of copies to print from this document */ +int XpuSetDocumentCopies( Display *pdpy, XPContext pcontext, long num_copies ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "document-attributes-supported", "copy-count") ) + { + XpuSetOneLongAttribute(pdpy, pcontext, XPDocAttr, "*copy-count", num_copies, XPAttrMerge); + return(1); + } + else + { + XPU_DEBUG_ONLY(printf("XpuSetContentOrientation: XpuCheckSupported failed for 'copy-count'\n")); + + /* We may safely assume that the device prints at least one copy if + * |copy-count| is not supported for this printer device. + */ + if (num_copies == 1) + return(1); + + /* Failure... */ + return(0); + } +} + +XpuMediumSourceSizeList XpuGetMediumSourceSizeList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ) +{ + XpuMediumSourceSizeList list = NULL; + int rec_count = 1; /* allocate one more |XpuMediumSourceSizeRec| structure + * as terminator */ + Bool status; + float ma1, + ma2, + ma3, + ma4; + char *value; + void *tok_lasts; + const char *tray_name, + *medium_name; + int mbool; + const char *default_tray, + *default_medium; + int default_medium_rec_index = -1; + + default_tray = XpGetOneAttribute(pdpy, pcontext, XPDocAttr, "default-input-tray"); + if(!default_tray) + { + fprintf(stderr, "XpuGetMediumSourceSizeList: Internal error, no 'default-input-tray' found.\n"); + return(NULL); + } + default_medium = XpGetOneAttribute(pdpy, pcontext, XPDocAttr, "default-medium"); + if(!default_medium) + { + fprintf(stderr, "XpuGetMediumSourceSizeList: Internal error, no 'default-medium' found.\n"); + XFree((void *)default_tray); + return(NULL); + } + + for( status = XpuEnumerateMediumSourceSizes(pdpy, pcontext, &tray_name, &medium_name, &mbool, + &ma1, &ma2, &ma3, &ma4, &tok_lasts) ; + status != False ; + status = XpuEnumerateMediumSourceSizes(NULL, NULL, &tray_name, &medium_name, &mbool, + &ma1, &ma2, &ma3, &ma4, &tok_lasts) ) + { + rec_count++; + list = (XpuMediumSourceSizeRec *)realloc(list, sizeof(XpuMediumSourceSizeRec)*rec_count); + if( !list ) + return(NULL); + + list[rec_count-2].tray_name = (tray_name)?(strdup(tray_name)):(NULL); + list[rec_count-2].medium_name = strdup(medium_name); + list[rec_count-2].mbool = mbool; + list[rec_count-2].ma1 = ma1; + list[rec_count-2].ma2 = ma2; + list[rec_count-2].ma3 = ma3; + list[rec_count-2].ma4 = ma4; + + /* Default medium ? */ + if( (!strcmp(medium_name, default_medium)) && + ((tray_name && (strlen(default_tray) > 0))?(!strcmp(tray_name, default_tray)):(True)) ) + { + default_medium_rec_index = rec_count-2; + } + } + + XpuDisposeEnumerateMediumSourceSizes(&tok_lasts); + + if( list ) + { + /* users: DO NOT COUNT ON THIS DETAIL + * (this is only to make current impl. of XpuFreeMediumSourceSizeList() easier) + * I may remove this implementation detail in a later revision of + * the library! */ + list[rec_count-1].tray_name = NULL; + list[rec_count-1].medium_name = NULL; + rec_count--; + } + else + { + rec_count = 0; + } + + /* Make the default medium always the first item in the list... */ + if( (default_medium_rec_index != -1) && list ) + { + XpuMediumSourceSizeRec tmp; + tmp = list[0]; + list[0] = list[default_medium_rec_index]; + list[default_medium_rec_index] = tmp; + } + + *numEntriesPtr = rec_count; + return(list); +} + +void XpuFreeMediumSourceSizeList( XpuMediumSourceSizeList list ) +{ + if( list ) + { + XpuMediumSourceSizeRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->medium_name != NULL ) + { + if( curr->tray_name) + free((void *)curr->tray_name); + free((void *)curr->medium_name); + curr++; + } + + free(list); + } +} + +static +int XpuSetMediumSourceSize( Display *pdpy, XPContext pcontext, XPAttributes type, XpuMediumSourceSizeRec *medium_spec ) +{ + /* Set the "default-medium" and "*default-input-tray" + * (if |XpuEnumerateMediumSourceSizes| returned one) XPDocAttr's + * attribute and return */ + if (medium_spec->tray_name) + { + XpuSetOneAttribute(pdpy, pcontext, type, "*default-input-tray", medium_spec->tray_name, XPAttrMerge); + } + XpuSetOneAttribute(pdpy, pcontext, type, "*default-medium", medium_spec->medium_name, XPAttrMerge); + + return( 1 ); +} + +/* Set document medium size */ +int XpuSetDocMediumSourceSize( Display *pdpy, XPContext pcontext, XpuMediumSourceSizeRec *medium_spec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "document-attributes-supported", "default-medium") == 0 ) + return( 0 ); + + if (medium_spec->tray_name) + { + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "document-attributes-supported", "default-input-tray") == 0 ) + return( 0 ); + } + + return XpuSetMediumSourceSize(pdpy, pcontext, XPDocAttr, medium_spec); +} + +/* Set page medium size */ +int XpuSetPageMediumSourceSize( Display *pdpy, XPContext pcontext, XpuMediumSourceSizeRec *medium_spec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported", "default-medium") == 0 ) + return( 0 ); + + if (medium_spec->tray_name) + { + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported", "default-input-tray") == 0 ) + return( 0 ); + } + + return XpuSetMediumSourceSize(pdpy, pcontext, XPPageAttr, medium_spec); +} + +#ifndef ABS +#define ABS(x) ((x)<0?-(x):(x)) +#endif /* ABS */ +#define MORE_OR_LESS_EQUAL(a, b, tolerance) (ABS((a) - (b)) <= (tolerance)) + +XpuMediumSourceSizeRec * +XpuFindMediumSourceSizeBySize( XpuMediumSourceSizeList mlist, int mlist_count, + float page_width_mm, float page_height_mm, float tolerance ) +{ + int i; + for( i = 0 ; i < mlist_count ; i++ ) + { + XpuMediumSourceSizeRec *curr = &mlist[i]; + float total_width = curr->ma1 + curr->ma2, + total_height = curr->ma3 + curr->ma4; + + /* Match width/height*/ + if( ((page_width_mm !=-1.f)?(MORE_OR_LESS_EQUAL(total_width, page_width_mm, tolerance)):(True)) && + ((page_height_mm!=-1.f)?(MORE_OR_LESS_EQUAL(total_height, page_height_mm, tolerance)):(True)) ) + { + return(curr); + } + } + + return(NULL); +} + +XpuMediumSourceSizeRec * +XpuFindMediumSourceSizeByBounds( XpuMediumSourceSizeList mlist, int mlist_count, + float m1, float m2, float m3, float m4, float tolerance ) +{ + int i; + for( i = 0 ; i < mlist_count ; i++ ) + { + XpuMediumSourceSizeRec *curr = &mlist[i]; + + /* Match bounds */ + if( ((m1!=-1.f)?(MORE_OR_LESS_EQUAL(curr->ma1, m1, tolerance)):(True)) && + ((m2!=-1.f)?(MORE_OR_LESS_EQUAL(curr->ma2, m2, tolerance)):(True)) && + ((m3!=-1.f)?(MORE_OR_LESS_EQUAL(curr->ma3, m3, tolerance)):(True)) && + ((m4!=-1.f)?(MORE_OR_LESS_EQUAL(curr->ma4, m4, tolerance)):(True)) ) + { + return(curr); + } + } + + return(NULL); +} + +XpuMediumSourceSizeRec * +XpuFindMediumSourceSizeByName( XpuMediumSourceSizeList mlist, int mlist_count, + const char *tray_name, const char *medium_name ) +{ + int i; + for( i = 0 ; i < mlist_count ; i++ ) + { + XpuMediumSourceSizeRec *curr = &mlist[i]; + + /* Match by tray name and/or medium name */ + if( ((tray_name && curr->tray_name)?(!strcasecmp(curr->tray_name, tray_name)):(tray_name==NULL)) && + ((medium_name)?(!strcasecmp(curr->medium_name, medium_name)):(True)) ) + { + return(curr); + } + } + + return(NULL); +} + +XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ) +{ + XpuResolutionList list = NULL; + int rec_count = 1; /* Allocate one more |XpuResolutionRec| structure + * as terminator */ + char *value; + char *tok_lasts; + const char *s; + long default_resolution = 0; + int default_resolution_rec_index = -1; + + /* Get default document resolution */ + if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", &default_resolution) != 1 ) + { + fprintf(stderr, "XpuGetResolutionList: Internal error, no 'default-printer-resolution' XPDocAttr found.\n"); + return(NULL); + } + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "printer-resolutions-supported"); + if (!value) + { + fprintf(stderr, "XpuGetResolutionList: Internal error, no 'printer-resolutions-supported' XPPrinterAttr found.\n"); + return(NULL); + } + + for( s = strtok_r(value, " ", &tok_lasts) ; + s != NULL ; + s = strtok_r(NULL, " ", &tok_lasts) ) + { + long tmp; + + tmp = strtol(s, (char **)NULL, 10); + + if( ((tmp == 0L) || (tmp == LONG_MIN) || (tmp == LONG_MAX)) && + ((errno == ERANGE) || (errno == EINVAL)) ) + { + fprintf(stderr, "XpuGetResolutionList: Internal parser errror for '%s'.\n", s); + continue; + } + + rec_count++; + list = (XpuResolutionRec *)realloc(list, sizeof(XpuResolutionRec)*rec_count); + if( !list ) + return(NULL); + + list[rec_count-2].dpi = tmp; + + /* Default resolution ? */ + if( list[rec_count-2].dpi == default_resolution ) + { + default_resolution_rec_index = rec_count-2; + } + } + + XFree(value); + + if( list ) + { + /* users: DO NOT COUNT ON THIS DETAIL + * (this is only to make current impl. of XpuFreeMediumSourceSizeList() easier) + * I may remove this implementation detail in a later revision of + * the library! */ + list[rec_count-1].dpi = -1; + rec_count--; + } + else + { + rec_count = 0; + } + + /* Make the default resolution always the first item in the list... */ + if( (default_resolution_rec_index != -1) && list ) + { + XpuResolutionRec tmp; + tmp = list[0]; + list[0] = list[default_resolution_rec_index]; + list[default_resolution_rec_index] = tmp; + } + + *numEntriesPtr = rec_count; + return(list); +} + +void XpuFreeResolutionList( XpuResolutionList list ) +{ + if( list ) + { + free(list); + } +} + +/* Get default page (if defined) or document resolution + * this function may fail in the following conditions: + * - Xprt misconfiguration + * - X DPI != Y DPI (not yet implemented in Xprt) + */ +Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi_ptr ) +{ + /* Try to get the current page's resolution (pages may differ in resolution if the DDX supports this) */ + if( XpuGetOneLongAttribute(pdpy, pcontext, XPPageAttr, "default-printer-resolution", dpi_ptr) == 1 ) + { + return True; + } + + /* Get document resolution */ + if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", dpi_ptr) == 1 ) + { + return True; + } + + return False; +} + +static +int XpuSetResolution( Display *pdpy, XPContext pcontext, XPAttributes type, XpuResolutionRec *rec ) +{ + XpuSetOneLongAttribute(pdpy, pcontext, type, "*default-printer-resolution", rec->dpi, XPAttrMerge); + return( 1 ); +} + +/* Set document resolution + * Retun error if printer does not support setting a resolution + */ +int XpuSetDocResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec *rec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "document-attributes-supported", "default-printer-resolution") == 0 ) + return( 0 ); + + return XpuSetResolution(pdpy, pcontext, XPDocAttr, rec); +} + +/* Set page medium size + * Retun error if printer does not support setting a resolution or if per-page + * resolution changes are not allowed. + */ +int XpuSetPageResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec *rec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported", "default-printer-resolution") == 0 ) + return( 0 ); + + return XpuSetResolution(pdpy, pcontext, XPPageAttr, rec); +} + +XpuOrientationList XpuGetOrientationList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ) +{ + XpuOrientationList list = NULL; + int rec_count = 1; /* Allocate one more |XpuOrientationRec| + * structure as terminator */ + char *value; + char *tok_lasts; + const char *s; + const char *default_orientation = NULL; + int default_orientation_rec_index = -1; + + /* Get default document orientation */ + default_orientation = XpGetOneAttribute(pdpy, pcontext, XPDocAttr, "content-orientation"); + if( !default_orientation ) + { + fprintf(stderr, "XpuGetOrientationList: Internal error, no 'content-orientation' XPDocAttr found.\n"); + return(NULL); + } + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "content-orientations-supported"); + if (!value) + { + fprintf(stderr, "XpuGetOrientationList: Internal error, no 'content-orientations-supported' XPPrinterAttr found.\n"); + return(NULL); + } + + for( s = strtok_r(value, " ", &tok_lasts) ; + s != NULL ; + s = strtok_r(NULL, " ", &tok_lasts) ) + { + rec_count++; + list = (XpuOrientationRec *)realloc(list, sizeof(XpuOrientationRec)*rec_count); + if( !list ) + return(NULL); + + list[rec_count-2].orientation = strdup(s); + + /* Default resolution ? */ + if( !strcmp(list[rec_count-2].orientation, default_orientation) ) + { + default_orientation_rec_index = rec_count-2; + } + } + + XFree(value); + XFree((void *)default_orientation); + + if( list ) + { + /* users: DO NOT COUNT ON THIS DETAIL + * (this is only to make current impl. of XpuFreeOrientationList() easier) + * I may remove this implementation detail in a later revision of + * the library! */ + list[rec_count-1].orientation = NULL; + rec_count--; + } + else + { + rec_count = 0; + } + + /* Make the default orientation always the first item in the list... */ + if( (default_orientation_rec_index != -1) && list ) + { + XpuOrientationRec tmp; + tmp = list[0]; + list[0] = list[default_orientation_rec_index]; + list[default_orientation_rec_index] = tmp; + } + + *numEntriesPtr = rec_count; + return(list); +} + +void XpuFreeOrientationList( XpuOrientationList list ) +{ + if( list ) + { + XpuOrientationRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->orientation != NULL ) + { + free((void *)curr->orientation); + curr++; + } + free(list); + } +} + +XpuOrientationRec * +XpuFindOrientationByName( XpuOrientationList list, int list_count, const char *orientation ) +{ + int i; + + for( i = 0 ; i < list_count ; i++ ) + { + XpuOrientationRec *curr = &list[i]; + if (!strcasecmp(curr->orientation, orientation)) + return curr; + } + + return(NULL); +} + +static +int XpuSetOrientation( Display *pdpy, XPContext pcontext, XPAttributes type, XpuOrientationRec *rec ) +{ + XpuSetOneAttribute(pdpy, pcontext, type, "*content-orientation", rec->orientation, XPAttrMerge); + return(1); +} + +/* Set document orientation + * Retun error if printer does not support setting an orientation + */ +int XpuSetDocOrientation( Display *pdpy, XPContext pcontext, XpuOrientationRec *rec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "document-attributes-supported", "content-orientation") == 0 ) + return( 0 ); + + return XpuSetOrientation(pdpy, pcontext, XPDocAttr, rec); +} + +/* Set page orientation + * Retun error if printer does not support setting an orientation or if + * per-page orientations changes are not allowed + */ +int XpuSetPageOrientation( Display *pdpy, XPContext pcontext, XpuOrientationRec *rec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported", "content-orientation") == 0 ) + return( 0 ); + + return XpuSetOrientation(pdpy, pcontext, XPPageAttr, rec); +} + +XpuPlexList XpuGetPlexList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ) +{ + XpuPlexList list = NULL; + int rec_count = 1; /* Allocate one more |XpuPlexList| structure + * as terminator */ + char *value; + char *tok_lasts; + const char *s; + const char *default_plex = NULL; + int default_plex_rec_index = -1; + + /* Get default document plex */ + default_plex = XpGetOneAttribute(pdpy, pcontext, XPDocAttr, "plex"); + if( !default_plex ) + { + fprintf(stderr, "XpuGetPlexList: Internal error, no 'plex' XPDocAttr found.\n"); + return(NULL); + } + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "plexes-supported"); + if (!value) + { + fprintf(stderr, "XpuGetPlexList: Internal error, no 'plexes-supported' XPPrinterAttr found.\n"); + return(NULL); + } + + for( s = strtok_r(value, " ", &tok_lasts) ; + s != NULL ; + s = strtok_r(NULL, " ", &tok_lasts) ) + { + rec_count++; + list = (XpuPlexRec *)realloc(list, sizeof(XpuPlexRec)*rec_count); + if( !list ) + return(NULL); + + list[rec_count-2].plex = strdup(s); + + /* Default plex ? */ + if( !strcmp(list[rec_count-2].plex, default_plex) ) + { + default_plex_rec_index = rec_count-2; + } + } + + XFree(value); + XFree((void *)default_plex); + + if( list ) + { + /* users: DO NOT COUNT ON THIS DETAIL + * (this is only to make current impl. of XpuFreePlexList() easier) + * I may remove this implementation detail in a later revision of + * the library! */ + list[rec_count-1].plex = NULL; + rec_count--; + } + else + { + rec_count = 0; + } + + /* Make the default plex always the first item in the list... */ + if( (default_plex_rec_index != -1) && list ) + { + XpuPlexRec tmp; + tmp = list[0]; + list[0] = list[default_plex_rec_index]; + list[default_plex_rec_index] = tmp; + } + + *numEntriesPtr = rec_count; + return(list); +} + +void XpuFreePlexList( XpuPlexList list ) +{ + if( list ) + { + XpuPlexRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->plex != NULL ) + { + free((void *)curr->plex); + curr++; + } + free(list); + } +} + +XpuPlexRec * +XpuFindPlexByName( XpuPlexList list, int list_count, const char *plex ) +{ + int i; + + for( i = 0 ; i < list_count ; i++ ) + { + XpuPlexRec *curr = &list[i]; + if (!strcasecmp(curr->plex, plex)) + return curr; + } + + return(NULL); +} + +static +int XpuSetContentPlex( Display *pdpy, XPContext pcontext, XPAttributes type, XpuPlexRec *rec ) +{ + XpuSetOneAttribute(pdpy, pcontext, type, "*plex", rec->plex, XPAttrMerge); + return(1); +} + +/* Set document plex + * Retun error if printer does not support setting an plex + */ +int XpuSetDocPlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "document-attributes-supported", "plex") == 0 ) + return( 0 ); + + return XpuSetContentPlex(pdpy, pcontext, XPDocAttr, rec); +} + +/* Set page plex + * Retun error if printer does not support setting an plex or if + * per-page plex changes are not allowed + */ +int XpuSetPagePlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ) +{ + if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported", "plex") == 0 ) + return( 0 ); + + return XpuSetContentPlex(pdpy, pcontext, XPPageAttr, rec); +} + /* EOF. */ diff --git a/gfx/src/xprint/xprintutil.h b/gfx/src/xprint/xprintutil.h index 12f0f59e92a5..9f20b6366bfd 100644 --- a/gfx/src/xprint/xprintutil.h +++ b/gfx/src/xprint/xprintutil.h @@ -44,6 +44,7 @@ /* I don't know how to make this "better" yet... ;-( */ #ifdef USE_MOZILLA_TYPES +#include #include #include #define XPU_USE_NSPR 1 @@ -63,34 +64,122 @@ #define XPU_DEBUG_ONLY(EX) #endif /* DEBUG */ -/* debug: replace NULLptrs with "" string */ +/* debug/logging: replace NULLptrs with "" string */ #define XPU_NULLXSTR(s) (((s)!=NULL)?(s):("")) +/* + * Struct for XpuGetMediumSourceSizeList(), XpuFreeMediumSourceSizeList(), + * XpuSetDocMediumSourceSize(), XpuSetPageMediumSourceSize(), + * XpuFindMediumSourceSizeBy*() + */ +typedef struct { + const char *tray_name; + const char *medium_name; + int mbool; + float ma1; + float ma2; + float ma3; + float ma4; +} XpuMediumSourceSizeRec, *XpuMediumSourceSizeList; + +/* + * Struct for XpuGetResolutionList(), XpuFreeResolutionList(), + * XpuGetResolution(), XpuSetPageResolution(), XpuSetDocResolution() + */ +typedef struct { + long dpi; + /* ToDo: Support for Xdpi != Ydpi */ +} XpuResolutionRec, *XpuResolutionList; + +/* + * Struct for XpuGetOrientationList(), XpuFreeOrientationList(), + * XpuFindOrientationBy*(), XpuSetPageResolution(), + * XpuSetDocOrientation() + */ +typedef struct { + const char *orientation; +} XpuOrientationRec, *XpuOrientationList; + +/* + * Struct for XpuGetPlexList(), XpuFreePlexList(), XpuFindPlexBy*(), + * XpuSetDocPlex(), XpuSetPagePlex() + */ +typedef struct { + const char *plex; +} XpuPlexRec, *XpuPlexList; + /* prototypes */ _XFUNCPROTOBEGIN int XpuCheckExtension( Display *pdpy ); -const char *XpuGetXpServerList( void ); + +/* Create/destroy connection to printer */ int XpuGetPrinter( const char *printername, Display **pdpyptr, XPContext *pcontextptr ); +void XpuClosePrinterDisplay(Display *pdpy, XPContext pcontext); + +/* Misc. functions */ void XpuSetOneAttribute( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name, const char *value, XPAttrReplacement replacement_rule ); +void XpuSetOneLongAttribute( Display *pdpy, XPContext pcontext, + XPAttributes type, const char *attribute_name, long value, XPAttrReplacement replacement_rule ); int XpuCheckSupported( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name, const char *query ); int XpuSetJobTitle( Display *pdpy, XPContext pcontext, const char *title ); -int XpuSetContentOrientation( Display *pdpy, XPContext pcontext, XPAttributes type, const char *orientation ); int XpuGetOneLongAttribute( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name, long *result ); +#ifdef DEBUG void dumpXpAttributes( Display *pdpy, XPContext pcontext ); -void XpuSetContext( Display *pdpy, XPContext pcontext ); -void XpuWaitForPrintNotify( Display *pdpy, int detail ); -Bool XpuSetResolution( Display *pdpy, XPContext pcontext, long dpi ); -Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi ); -const char *XpuEmumerateXpAttributeValue( const char *value, void **vcptr ); -void XpuDisposeEmumerateXpAttributeValue( void **vc ); -Bool XpuParseMediumSourceSize( const char *value, - const char **media_name, Bool *mbool, - float *ma1, float *ma2, float *ma3, float *ma4 ); +#endif /* DEBUG */ +void XpuWaitForPrintNotify( Display *pdpy, int xp_event_base, int detail ); + +/* Get list of printers */ XPPrinterList XpuGetPrinterList( const char *printer, int *res_list_count ); void XpuFreePrinterList( XPPrinterList list ); +/* Set number of document copies */ +int XpuSetDocumentCopies( Display *pdpy, XPContext pcontext, long num_copies ); + +/* Get/Set/Query supported mediums (paper sizes) */ +XpuMediumSourceSizeList XpuGetMediumSourceSizeList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); +void XpuFreeMediumSourceSizeList( XpuMediumSourceSizeList list ); +int XpuSetDocMediumSourceSize( Display *pdpy, XPContext pcontext, XpuMediumSourceSizeRec *medium_spec ); +int XpuSetPageMediumSourceSize( Display *pdpy, XPContext pcontext, XpuMediumSourceSizeRec *medium_spec ); +XpuMediumSourceSizeRec * +XpuFindMediumSourceSizeBySize( XpuMediumSourceSizeList mlist, int mlist_count, + float page_width_mm, float page_height_mm, float tolerance ); +XpuMediumSourceSizeRec * +XpuFindMediumSourceSizeByBounds( XpuMediumSourceSizeList mlist, int mlist_count, + float m1, float m2, float m3, float m4, float tolerance ); +XpuMediumSourceSizeRec * +XpuFindMediumSourceSizeByName( XpuMediumSourceSizeList mlist, int mlist_count, + const char *tray_name, const char *medium_name ); + +/* Get/Set resolution */ +XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); +void XpuFreeResolutionList( XpuResolutionList list ); +Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi ); +Bool XpuSetPageResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec * ); +Bool XpuSetDocResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec * ); + +/* Get/Set orientation */ +XpuOrientationList XpuGetOrientationList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); +void XpuFreeOrientationList( XpuOrientationList list ); +XpuOrientationRec * +XpuFindOrientationByName( XpuOrientationList list, int list_count, const char *orientation ); +int XpuSetDocOrientation( Display *pdpy, XPContext pcontext, XpuOrientationRec *rec ); +int XpuSetPageOrientation( Display *pdpy, XPContext pcontext, XpuOrientationRec *rec ); + +/* Get/set plex modes */ +XpuPlexList XpuGetPlexList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); +void XpuFreePlexList( XpuPlexList list ); +XpuPlexRec *XpuFindPlexByName( XpuPlexList list, int list_count, const char *plex ); +int XpuSetDocPlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ); +int XpuSetPagePlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ); + +/* Start job to printer (spooler) or file */ +void XpuStartJobToSpooler(Display *pdpy); +void *XpuStartJobToFile( Display *pdpy, XPContext pcontext, const char *filename ); +XPGetDocStatus XpuWaitForPrintFileChild( void *handle ); + +_XFUNCPROTOEND #define XpuGetJobAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPJobAttr ) #define XpuGetDocAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPDocAttr ) @@ -98,10 +187,5 @@ void XpuFreePrinterList( XPPrinterList list ); #define XpuGetPrinterAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPPrinterAttr ) #define XpuGetServerAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPServerAttr ) -void *XpuPrintToFile( Display *pdpy, XPContext pcontext, const char *filename ); -XPGetDocStatus XpuWaitForPrintFileChild( void *handle ); - -_XFUNCPROTOEND - #endif /* !XPRINTUTIL_H */ /* EOF. */ diff --git a/gfx/src/xprint/xprintutil_printtofile.c b/gfx/src/xprint/xprintutil_printtofile.c index ae93f3baad73..4a595325d421 100644 --- a/gfx/src/xprint/xprintutil_printtofile.c +++ b/gfx/src/xprint/xprintutil_printtofile.c @@ -58,6 +58,7 @@ static void PrintXPGetDocStatus( XPGetDocStatus status ); #endif static Bool XNextEventTimeout( Display *display, XEvent *event_return, struct timeval *timeout ); +static void *XpuPrintToFile( Display *pdpy, XPContext pcontext, const char *filename ); static void MyPrintToFileProc( Display *pdpy, XPContext pcontext, unsigned char *data, unsigned int data_len, XPointer client_data ); static void MyFinishProc( Display *pdpy, XPContext pcontext, XPGetDocStatus status, XPointer client_data ); #ifdef XPU_USE_NSPR @@ -66,6 +67,21 @@ static void PrintToFile_Consumer( void *handle ); static void *PrintToFile_Consumer( void *handle ); #endif +void XpuStartJobToSpooler(Display *pdpy) +{ + XpStartJob(pdpy, XPSpool); +} + +void *XpuStartJobToFile( Display *pdpy, XPContext pcontext, const char *filename ) +{ + void *handle; + + XpStartJob(pdpy, XPGetData); + handle = XpuPrintToFile(pdpy, pcontext, filename); + + return(handle); +} + #ifdef DEBUG /* DEBUG: Print XPGetDocStatus */ static @@ -167,6 +183,7 @@ typedef struct } MyPrintFileData; +static void *XpuPrintToFile( Display *pdpy, XPContext pcontext, const char *filename ) { MyPrintFileData *mpfd; /* warning: shared between threads !! */ @@ -174,7 +191,7 @@ void *XpuPrintToFile( Display *pdpy, XPContext pcontext, const char *filename ) if( (mpfd = malloc(sizeof(MyPrintFileData))) == NULL ) return(NULL); - mpfd->displayname = DisplayString(pdpy); + mpfd->displayname = XDisplayString(pdpy); mpfd->pdpy = NULL; mpfd->pcontext = pcontext; mpfd->file_name = filename; @@ -256,21 +273,22 @@ typedef struct { pid_t pid; int pipe[2]; /* child-->parent communication pipe */ - char *displayname; + const char *displayname; Display *pdpy; XPContext pcontext; - char *file_name; + const char *file_name; FILE *file; XPGetDocStatus status; Bool done; } MyPrintFileData; +static void *XpuPrintToFile( Display *pdpy, XPContext pcontext, const char *filename ) { MyPrintFileData *mpfd; - if( (mpfd = malloc(sizeof(MyPrintFileData))) == NULL ) + if( (mpfd = (MyPrintFileData *)malloc(sizeof(MyPrintFileData))) == NULL ) return(NULL); /* create pipe */ @@ -282,7 +300,7 @@ void *XpuPrintToFile( Display *pdpy, XPContext pcontext, const char *filename ) return(NULL); } - mpfd->displayname = DisplayString(pdpy); + mpfd->displayname = XDisplayString(pdpy); mpfd->pcontext = pcontext; mpfd->file_name = filename; mpfd->file = NULL;