diff --git a/content/base/src/nsPrintEngine.cpp b/content/base/src/nsPrintEngine.cpp index 63865e31ea59..f35d60444853 100644 --- a/content/base/src/nsPrintEngine.cpp +++ b/content/base/src/nsPrintEngine.cpp @@ -2257,6 +2257,7 @@ nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrinting) NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY) NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED) NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_RESOLUTION_NOT_SUPPORTED) default: NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE) diff --git a/gfx/idl/nsIPrintSettings.idl b/gfx/idl/nsIPrintSettings.idl index 08e0c71e20e3..a99c711e6c02 100644 --- a/gfx/idl/nsIPrintSettings.idl +++ b/gfx/idl/nsIPrintSettings.idl @@ -23,6 +23,7 @@ * Don Cone * Rod Spears * Roland Mainz + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -57,7 +58,7 @@ interface nsIPrintSession; * * @status UNDER_REVIEW */ -[scriptable, uuid(83427530-F790-11d4-A869-00105A183419)] +[scriptable, uuid(f1094df6-ce0e-42c9-9847-2f663172c38d)] interface nsIPrintSettings : nsISupports { @@ -94,6 +95,9 @@ interface nsIPrintSettings : nsISupports const unsigned long kInitSavePlexName = 0x04000000; const unsigned long kInitSaveShrinkToFit = 0x08000000; const unsigned long kInitSaveScaling = 0x10000000; + const unsigned long kInitSaveColorspace = 0x20000000; + const unsigned long kInitSaveResolutionName = 0x40000000; + const unsigned long kInitSaveDownloadFonts = 0x80000000; const unsigned long kInitSaveAll = 0xFFFFFFFF; /* Print Option Flags for Bit Field*/ @@ -230,13 +234,21 @@ interface nsIPrintSettings : nsISupports attribute wstring plexName; /* name of plex mode (like "simplex", "duplex", * "tumble" and various custom values) */ + attribute wstring colorspace; /* device-specific name of colorspace, overrides |printInColor| */ + attribute wstring resolutionName;/* device-specific identifer of resolution or quality + * (like "600", "600x300", "600x300x12", "high-res", + * "med-res". "low-res", etc.) */ + attribute boolean downloadFonts; /* enable font download to printer? */ + attribute boolean printReversed; attribute boolean printInColor; /* a false means grayscale */ attribute long paperSize; /* see page size consts */ attribute long orientation; /* see orientation consts */ attribute wstring printCommand; attribute long numCopies; - attribute wstring printerName; + + attribute wstring printerName; /* name of destination printer */ + attribute boolean printToFile; attribute wstring toFileName; diff --git a/gfx/public/nsIDeviceContext.h b/gfx/public/nsIDeviceContext.h index 58a1932b4bae..293699229be7 100644 --- a/gfx/public/nsIDeviceContext.h +++ b/gfx/public/nsIDeviceContext.h @@ -158,6 +158,9 @@ typedef void * nsNativeDeviceContext; /* Cannot load the matching print module */ #define NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+34) +/* requested resolution/quality mode not supported by printer */ +#define NS_ERROR_GFX_PRINTER_RESOLUTION_NOT_SUPPORTED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+35) /** * Conts need for Print Preview diff --git a/gfx/src/gtk/nsDeviceContextSpecG.cpp b/gfx/src/gtk/nsDeviceContextSpecG.cpp index 6a54fa3b233a..63d53e0230c0 100644 --- a/gfx/src/gtk/nsDeviceContextSpecG.cpp +++ b/gfx/src/gtk/nsDeviceContextSpecG.cpp @@ -22,6 +22,7 @@ * Contributor(s): * Roland Mainz * Ken Herron + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -133,6 +134,37 @@ public: /* Set number of plex records and the records itself */ void SetNumPlexRecords( PRInt32 aCount ); void SetPlexRecord( PRInt32 aIndex, const char *aName ); + + /* Does this printer allow to set/change the resolution name ? */ + void SetCanChangeResolutionName( PRBool aCanSetResolutionName ); + /* Does this Mozilla print module allow set/change the resolution name ? */ + void SetSupportsResolutionNameChange( PRBool aSupportsResolutionChange ); + /* Set number of resolution records and the records itself */ + void SetNumResolutionNameRecords( PRInt32 aCount ); + void SetResolutionNameRecord( PRInt32 aIndex, const char *aName ); + + /* Does this printer allow to set/change the colorspace ? */ + void SetCanChangeColorspace( PRBool aCanSetColorspace ); + /* Does this Mozilla print module allow set/change the colorspace ? */ + void SetSupportsColorspaceChange( PRBool aSupportsColorspace ); + /* Set number of colorspace records and the records itself */ + void SetNumColorspaceRecords( PRInt32 aCount ); + void SetColorspaceRecord( PRInt32 aIndex, const char *aName ); + + /* Does this device allow to set/change the usage of the internal grayscale mode ? */ + void SetCanChangePrintInColor( PRBool aCanSetPrintInColor ); + /* Does this printer allow to set/change the usage of the internal grayscale mode ? */ + void SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange ); + + /* Does this device allow to set/change the usage of font download to the printer? */ + void SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts ); + /* Does this printer allow to set/change the usage of font download to the printer? */ + void SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange ); + + /* Does this device allow to set/change the job title ? */ + void SetCanChangeJobTitle( PRBool aCanSetJobTitle ); + /* Does this printer allow to set/change the job title ? */ + void SetSupportsJobTitleChange( PRBool aSupportJobTitleChange ); /* Does this device allow to set/change the spooler command ? */ void SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ); @@ -245,6 +277,66 @@ void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName ) SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName); } +void nsPrinterFeatures::SetCanChangeResolutionName( PRBool aCanSetResolutionName ) +{ + SetBoolValue("can_change_resolution", aCanSetResolutionName); +} + +void nsPrinterFeatures::SetSupportsResolutionNameChange( PRBool aSupportsResolutionNameChange ) +{ + SetBoolValue("supports_resolution_change", aSupportsResolutionNameChange); +} + +void nsPrinterFeatures::SetNumResolutionNameRecords( PRInt32 aCount ) +{ + SetIntValue("resolution.count", aCount); +} + +void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName ) +{ + SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName); +} + +void nsPrinterFeatures::SetCanChangeColorspace( PRBool aCanSetColorspace ) +{ + SetBoolValue("can_change_colorspace", aCanSetColorspace); +} + +void nsPrinterFeatures::SetSupportsColorspaceChange( PRBool aSupportsColorspaceChange ) +{ + SetBoolValue("supports_colorspace_change", aSupportsColorspaceChange); +} + +void nsPrinterFeatures::SetNumColorspaceRecords( PRInt32 aCount ) +{ + SetIntValue("colorspace.count", aCount); +} + +void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace ) +{ + SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace); +} + +void nsPrinterFeatures::SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts ) +{ + SetBoolValue("can_change_downloadfonts", aCanSetDownloadFonts); +} + +void nsPrinterFeatures::SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange ) +{ + SetBoolValue("supports_downloadfonts_change", aSupportDownloadFontsChange); +} + +void nsPrinterFeatures::SetCanChangePrintInColor( PRBool aCanSetPrintInColor ) +{ + SetBoolValue("can_change_printincolor", aCanSetPrintInColor); +} + +void nsPrinterFeatures::SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange ) +{ + SetBoolValue("supports_printincolor_change", aSupportPrintInColorChange); +} + void nsPrinterFeatures::SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ) { SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand); @@ -255,6 +347,16 @@ void nsPrinterFeatures::SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerC SetBoolValue("supports_spoolercommand_change", aSupportSpoolerCommandChange); } +void nsPrinterFeatures::SetCanChangeJobTitle( PRBool aCanSetJobTitle ) +{ + SetBoolValue("can_change_jobtitle", aCanSetJobTitle); +} + +void nsPrinterFeatures::SetSupportsJobTitleChange( PRBool aSupportsJobTitle ) +{ + SetBoolValue("supports_jobtitle_change", aSupportsJobTitle); +} + void nsPrinterFeatures::SetCanChangeNumCopies( PRBool aCanSetNumCopies ) { SetBoolValue("can_change_num_copies", aCanSetNumCopies); @@ -352,6 +454,9 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings *aPS, PRUnichar *printer = nsnull; PRUnichar *papername = nsnull; PRUnichar *plexname = nsnull; + PRUnichar *resolutionname = nsnull; + PRUnichar *colorspace = nsnull; + PRBool downloadfonts = PR_TRUE; PRUnichar *printfile = nsnull; double dleft = 0.5; double dright = 0.5; @@ -362,6 +467,9 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings *aPS, aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); aPS->GetPaperName(&papername); + aPS->GetResolutionName(&resolutionname); + aPS->GetColorspace(&colorspace); + aPS->GetDownloadFonts(&downloadfonts); aPS->GetPlexName(&plexname); aPS->GetOrientation(&orientation); aPS->GetPrintCommand(&command); @@ -386,6 +494,10 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings *aPS, PL_strncpyz(mPaperName, NS_ConvertUCS2toUTF8(papername).get(), sizeof(mPaperName)); if (plexname) PL_strncpyz(mPlexName, NS_ConvertUCS2toUTF8(plexname).get(), sizeof(mPlexName)); + if (resolutionname) + PL_strncpyz(mResolutionName, NS_ConvertUCS2toUTF8(resolutionname).get(), sizeof(mResolutionName)); + if (colorspace) + PL_strncpyz(mColorspace, NS_ConvertUCS2toUTF8(colorspace).get(), sizeof(mColorspace)); DO_PR_DEBUG_LOG(("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright)); DO_PR_DEBUG_LOG(("printRange %d\n", printRange)); @@ -397,12 +509,15 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings *aPS, DO_PR_DEBUG_LOG(("printer '%s'\n", printer? NS_ConvertUCS2toUTF8(printer).get():"")); DO_PR_DEBUG_LOG(("papername '%s'\n", papername? NS_ConvertUCS2toUTF8(papername).get():"")); DO_PR_DEBUG_LOG(("plexname '%s'\n", plexname? NS_ConvertUCS2toUTF8(plexname).get():"")); + DO_PR_DEBUG_LOG(("resolution '%s'\n", resolutionname? NS_ConvertUCS2toUTF8(resolutionname).get():"")); + DO_PR_DEBUG_LOG(("colorspace '%s'\n", colorspace? NS_ConvertUCS2toUTF8(colorspace).get():"")); mTop = dtop; mBottom = dbottom; mLeft = dleft; mRight = dright; mFpf = !reversed; + mDownloadFonts = downloadfonts; mGrayscale = !color; mOrientation = orientation; mToPrinter = !tofile; @@ -510,6 +625,24 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetPlexName( const char **aPlexName ) return NS_OK; } +NS_IMETHODIMP nsDeviceContextSpecGTK::GetResolutionName( const char **aResolutionName ) +{ + *aResolutionName = mResolutionName; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecGTK::GetColorspace( const char **aColorspace ) +{ + *aColorspace = mColorspace; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecGTK::GetDownloadFonts(PRBool &aDownloadFonts) +{ + aDownloadFonts = mDownloadFonts; + return NS_OK; +} + NS_IMETHODIMP nsDeviceContextSpecGTK::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) { return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); @@ -752,6 +885,9 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnich printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_TRUE); + printerFeatures.SetSupportsResolutionNameChange(PR_TRUE); + printerFeatures.SetSupportsColorspaceChange(PR_TRUE); + printerFeatures.SetSupportsJobTitleChange(PR_TRUE); printerFeatures.SetSupportsSpoolerCommandChange(PR_FALSE); /* won't work by design and very good reasons! */ #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ @@ -904,11 +1040,89 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnich XpuFreeMediumSourceSizeList(mlist); } + /* Setup resolution/quality stuff */ + XpuResolutionList rlist; + int rcount; + XpuResolutionRec *default_resolution; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + PRBool canSetResolutionName = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_PRINTER_RESOLUTION); + printerFeatures.SetCanChangeResolutionName(canSetResolutionName); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + rlist = XpuGetResolutionList(pdpy, pcontext, &rcount); + if (rlist) { + default_resolution = &rlist[0]; /* First entry is the default one */ + + DO_PR_DEBUG_LOG(("setting default resolution to '%s'/%ldx%ld\n", + default_resolution->name, + default_resolution->x_dpi, + default_resolution->y_dpi)); + aPrintSettings->SetResolutionName(NS_ConvertUTF8toUCS2(default_resolution->name).get()); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; i < rcount ; i++ ) + { + XpuResolutionRec *curr = &rlist[i]; + printerFeatures.SetResolutionNameRecord(i, curr->name); + } + printerFeatures.SetNumResolutionNameRecords(rcount); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuFreeResolutionList(rlist); + } + + /* We still support the old print-in-color boolean */ + printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); + printerFeatures.SetCanChangePrintInColor(PR_TRUE); + + /* Setup colorspace stuff */ + XpuColorspaceList cslist; + int cscount; + XpuColorspaceRec *default_colorspace; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeColorspace(PR_TRUE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + cslist = XpuGetColorspaceList(pdpy, pcontext, &cscount); + if (cslist) { + default_colorspace = &cslist[0]; /* First entry is the default one */ + + DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", default_colorspace->name)); + aPrintSettings->SetColorspace(NS_ConvertUTF8toUCS2(default_colorspace->name).get()); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; i < cscount ; i++ ) + { + XpuColorspaceRec *curr = &cslist[i]; + printerFeatures.SetColorspaceRecord(i, curr->name); + } + printerFeatures.SetNumColorspaceRecords(cscount); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuFreeColorspaceList(cslist); + } + + /* Fonts */ + PRBool canSetListFontsMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_LISTFONTS_MODES); + printerFeatures.SetCanChangeDownloadFonts(canSetListFontsMode); + printerFeatures.SetSupportsDownloadFontsChange(PR_TRUE); + + Bool downloadFonts = XpuGetEnableFontDownload(pdpy, pcontext); + aPrintSettings->SetDownloadFonts(downloadFonts); + #ifdef SET_PRINTER_FEATURES_VIA_PREFS /* Xprint does not allow the client to set a spooler command. * Job spooling is the job of the server side (=Xprt) */ printerFeatures.SetCanChangeSpoolerCommand(PR_FALSE); + /* Check whether printer/driver allow changes of the job name */ + PRBool canSetJobName = MAKE_PR_BOOL(XpuGetSupportedJobAttributes(pdpy, pcontext) & XPUATTRIBUTESUPPORTED_JOB_NAME); + printerFeatures.SetCanChangeJobTitle(canSetJobName); + /* Mozilla's Xprint support allows multiple nsIDeviceContext instances * be used in parallel */ printerFeatures.SetMultipleConcurrentDeviceContextsSupported(PR_TRUE); @@ -931,6 +1145,8 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnich printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_FALSE); + printerFeatures.SetSupportsResolutionNameChange(PR_FALSE); + printerFeatures.SetSupportsColorspaceChange(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS @@ -968,7 +1184,29 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnich printerFeatures.SetPlexRecord(0, "default"); printerFeatures.SetNumPlexRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ - + + /* PostScript module does not support changing the resolution mode... */ +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeResolutionName(PR_FALSE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default")); + aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get()); +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetResolutionNameRecord(0, "default"); + printerFeatures.SetNumResolutionNameRecords(1); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + /* PostScript module does not support changing the colorspace... */ +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeColorspace(PR_FALSE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default")); + aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get()); +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetColorspaceRecord(0, "default"); + printerFeatures.SetNumColorspaceRecords(1); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangePaperSize(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ @@ -1007,6 +1245,17 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnich #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd); printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd); + + /* Postscript module does not pass the job title to lpr */ + printerFeatures.SetSupportsJobTitleChange(PR_FALSE); + printerFeatures.SetCanChangeJobTitle(PR_FALSE); + /* Postscript module has no control over builtin fonts yet */ + printerFeatures.SetSupportsDownloadFontsChange(PR_FALSE); + printerFeatures.SetCanChangeDownloadFonts(PR_FALSE); + /* Postscript module does not support multiple colorspaces + * so it has to use the old way */ + printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); + printerFeatures.SetCanChangePrintInColor(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ if (hasSpoolerCmd) { diff --git a/gfx/src/gtk/nsDeviceContextSpecG.h b/gfx/src/gtk/nsDeviceContextSpecG.h index 7cb25d217f50..1c6e5ed310f7 100644 --- a/gfx/src/gtk/nsDeviceContextSpecG.h +++ b/gfx/src/gtk/nsDeviceContextSpecG.h @@ -97,6 +97,9 @@ public: NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight); NS_IMETHOD GetPaperName(const char **aPaperName); NS_IMETHOD GetPlexName(const char **aPlexName); + NS_IMETHOD GetResolutionName(const char **aResolutionName); + NS_IMETHOD GetColorspace(const char **aColorspace); + NS_IMETHOD GetDownloadFonts(PRBool &aDownloadFonts); virtual ~nsDeviceContextSpecGTK(); protected: @@ -105,6 +108,7 @@ protected: PRPackedBool mIsPPreview : 1; /* If PR_TRUE, is print preview */ PRPackedBool mFpf : 1; /* If PR_TRUE, first page first */ PRPackedBool mGrayscale : 1; /* If PR_TRUE, print grayscale */ + PRPackedBool mDownloadFonts : 1; /* If PR_TRUE, download fonts to printer */ PRPackedBool mCancel : 1; /* If PR_TRUE, user cancelled */ int mOrientation; /* Orientation e.g. Portrait */ char mCommand[PATH_MAX]; /* Print command e.g., lpr */ @@ -112,6 +116,8 @@ protected: char mPrinter[256]; /* Printer name */ char mPaperName[256]; /* Printer name */ char mPlexName[256]; /* Plex mode name */ + char mResolutionName[256];/* Resolution name */ + char mColorspace[256]; /* Colorspace */ int mCopies; /* number of copies */ float mLeft; /* left margin */ float mRight; /* right margin */ diff --git a/gfx/src/nsPrintOptionsImpl.cpp b/gfx/src/nsPrintOptionsImpl.cpp index 13c511e3362e..4c057f1752a7 100644 --- a/gfx/src/nsPrintOptionsImpl.cpp +++ b/gfx/src/nsPrintOptionsImpl.cpp @@ -95,6 +95,9 @@ static const char kPrintPaperData[] = "print_paper_data"; static const char kPrintPaperSizeUnit[] = "print_paper_size_unit"; static const char kPrintPaperWidth[] = "print_paper_width"; static const char kPrintPaperHeight[] = "print_paper_height"; +static const char kPrintColorspace[] = "print_colorspace"; +static const char kPrintResolutionName[]= "print_resolution_name"; +static const char kPrintDownloadFonts[] = "print_downloadfonts"; static const char kPrintOrientation[] = "print_orientation"; static const char kPrintCommand[] = "print_command"; static const char kPrinterName[] = "print_printer"; @@ -538,6 +541,27 @@ nsPrintOptions::ReadPrefs(nsIPrintSettings* aPS, const nsString& aPrefName, PRUi } } + if (aFlags & nsIPrintSettings::kInitSaveColorspace) { + if (NS_SUCCEEDED(ReadPrefString(GetPrefName(kPrintColorspace, aPrefName), str))) { + aPS->SetColorspace(str.get()); + DUMP_STR(kReadStr, kPrintColorspace, str.get()); + } + } + + if (aFlags & nsIPrintSettings::kInitSaveResolutionName) { + if (NS_SUCCEEDED(ReadPrefString(GetPrefName(kPrintResolutionName, aPrefName), str))) { + aPS->SetResolutionName(str.get()); + DUMP_STR(kReadStr, kPrintResolutionName, str.get()); + } + } + + if (aFlags & nsIPrintSettings::kInitSaveDownloadFonts) { + if (NS_SUCCEEDED(mPrefBranch->GetBoolPref(GetPrefName(kPrintDownloadFonts, aPrefName), &b))) { + aPS->SetDownloadFonts(b); + DUMP_BOOL(kReadStr, kPrintDownloadFonts, b); + } + } + if (aFlags & nsIPrintSettings::kInitSaveOrientation) { if (NS_SUCCEEDED(mPrefBranch->GetIntPref(GetPrefName(kPrintOrientation, aPrefName), &iVal))) { aPS->SetOrientation(iVal); @@ -770,6 +794,27 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsString& aPrefName, PRU } } + if (aFlags & nsIPrintSettings::kInitSaveColorspace) { + if (NS_SUCCEEDED(aPS->GetColorspace(&uStr))) { + DUMP_STR(kWriteStr, kPrintColorspace, uStr); + WritePrefString(uStr, GetPrefName(kPrintColorspace, aPrefName)); + } + } + + if (aFlags & nsIPrintSettings::kInitSaveResolutionName) { + if (NS_SUCCEEDED(aPS->GetResolutionName(&uStr))) { + DUMP_STR(kWriteStr, kPrintResolutionName, uStr); + WritePrefString(uStr, GetPrefName(kPrintResolutionName, aPrefName)); + } + } + + if (aFlags & nsIPrintSettings::kInitSaveDownloadFonts) { + if (NS_SUCCEEDED(aPS->GetDownloadFonts(&b))) { + DUMP_BOOL(kWriteStr, kPrintDownloadFonts, b); + mPrefBranch->SetBoolPref(GetPrefName(kPrintDownloadFonts, aPrefName), b); + } + } + if (aFlags & nsIPrintSettings::kInitSaveOrientation) { if (NS_SUCCEEDED(aPS->GetOrientation(&iVal))) { DUMP_INT(kWriteStr, kPrintOrientation, iVal); @@ -1302,6 +1347,9 @@ Tester::Tester() {kPrintPaperHeight, nsIPrintSettings::kInitSavePaperHeight}, {kPrintReversed, nsIPrintSettings::kInitSaveReversed}, {kPrintInColor, nsIPrintSettings::kInitSaveInColor}, + {kPrintColorspace, nsIPrintSettings::kInitSaveColorspace}, + {kPrintResolutionName, nsIPrintSettings::kInitSaveResolutionName}, + {kPrintDownloadFonts, nsIPrintSettings::kInitSaveDownloadFonts}, {kPrintOrientation, nsIPrintSettings::kInitSaveOrientation}, {kPrintCommand, nsIPrintSettings::kInitSavePrintCommand}, {kPrinterName, nsIPrintSettings::kInitSavePrinterName}, diff --git a/gfx/src/nsPrintSettingsImpl.cpp b/gfx/src/nsPrintSettingsImpl.cpp index 78b7b1828f49..d0458b3a57e6 100644 --- a/gfx/src/nsPrintSettingsImpl.cpp +++ b/gfx/src/nsPrintSettingsImpl.cpp @@ -216,6 +216,61 @@ NS_IMETHODIMP nsPrintSettings::SetOrientation(PRInt32 aOrientation) return NS_OK; } +/* attribute wstring colorspace; */ +NS_IMETHODIMP nsPrintSettings::GetColorspace(PRUnichar * *aColorspace) +{ + NS_ENSURE_ARG_POINTER(aColorspace); + if (!mColorspace.IsEmpty()) { + *aColorspace = ToNewUnicode(mColorspace); + } else { + *aColorspace = nsnull; + } + return NS_OK; +} +NS_IMETHODIMP nsPrintSettings::SetColorspace(const PRUnichar * aColorspace) +{ + if (aColorspace) { + mColorspace = aColorspace; + } else { + mColorspace.SetLength(0); + } + return NS_OK; +} + +/* attribute wstring resolutionname; */ +NS_IMETHODIMP nsPrintSettings::GetResolutionName(PRUnichar * *aResolutionName) +{ + NS_ENSURE_ARG_POINTER(aResolutionName); + if (!mResolutionName.IsEmpty()) { + *aResolutionName = ToNewUnicode(mResolutionName); + } else { + *aResolutionName = nsnull; + } + return NS_OK; +} +NS_IMETHODIMP nsPrintSettings::SetResolutionName(const PRUnichar * aResolutionName) +{ + if (aResolutionName) { + mResolutionName = aResolutionName; + } else { + mResolutionName.SetLength(0); + } + return NS_OK; +} + +/* attribute boolean downloadFonts; */ +NS_IMETHODIMP nsPrintSettings::GetDownloadFonts(PRBool *aDownloadFonts) +{ + //NS_ENSURE_ARG_POINTER(aDownloadFonts); + *aDownloadFonts = mDownloadFonts; + return NS_OK; +} +NS_IMETHODIMP nsPrintSettings::SetDownloadFonts(PRBool aDownloadFonts) +{ + mDownloadFonts = aDownloadFonts; + return NS_OK; +} + /* attribute wstring printer; */ NS_IMETHODIMP nsPrintSettings::GetPrinterName(PRUnichar * *aPrinter) { diff --git a/gfx/src/nsPrintSettingsImpl.h b/gfx/src/nsPrintSettingsImpl.h index bc11bd229a9b..8fabd2d7e2dd 100644 --- a/gfx/src/nsPrintSettingsImpl.h +++ b/gfx/src/nsPrintSettingsImpl.h @@ -123,6 +123,9 @@ protected: PRBool mPrintInColor; // a false means grayscale PRInt32 mPaperSize; // see page size consts PRInt32 mOrientation; // see orientation consts + nsString mColorspace; + nsString mResolutionName; + PRBool mDownloadFonts; nsString mPrintCommand; PRInt32 mNumCopies; nsXPIDLString mPrinter; diff --git a/gfx/src/xlib/nsDeviceContextSpecXlib.cpp b/gfx/src/xlib/nsDeviceContextSpecXlib.cpp index c4215281b268..7c9fc8ec47fb 100644 --- a/gfx/src/xlib/nsDeviceContextSpecXlib.cpp +++ b/gfx/src/xlib/nsDeviceContextSpecXlib.cpp @@ -22,6 +22,7 @@ * Contributor(s): * Roland Mainz * Ken Herron + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -133,6 +134,37 @@ public: /* Set number of plex records and the records itself */ void SetNumPlexRecords( PRInt32 aCount ); void SetPlexRecord( PRInt32 aIndex, const char *aName ); + + /* Does this printer allow to set/change the resolution name ? */ + void SetCanChangeResolutionName( PRBool aCanSetResolutionName ); + /* Does this Mozilla print module allow set/change the resolution name ? */ + void SetSupportsResolutionNameChange( PRBool aSupportsResolutionChange ); + /* Set number of resolution records and the records itself */ + void SetNumResolutionNameRecords( PRInt32 aCount ); + void SetResolutionNameRecord( PRInt32 aIndex, const char *aName ); + + /* Does this printer allow to set/change the colorspace ? */ + void SetCanChangeColorspace( PRBool aCanSetColorspace ); + /* Does this Mozilla print module allow set/change the colorspace ? */ + void SetSupportsColorspaceChange( PRBool aSupportsColorspace ); + /* Set number of colorspace records and the records itself */ + void SetNumColorspaceRecords( PRInt32 aCount ); + void SetColorspaceRecord( PRInt32 aIndex, const char *aName ); + + /* Does this device allow to set/change the usage of the internal grayscale mode ? */ + void SetCanChangePrintInColor( PRBool aCanSetPrintInColor ); + /* Does this printer allow to set/change the usage of the internal grayscale mode ? */ + void SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange ); + + /* Does this device allow to set/change the usage of font download to the printer? */ + void SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts ); + /* Does this printer allow to set/change the usage of font download to the printer? */ + void SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange ); + + /* Does this device allow to set/change the job title ? */ + void SetCanChangeJobTitle( PRBool aCanSetJobTitle ); + /* Does this printer allow to set/change the job title ? */ + void SetSupportsJobTitleChange( PRBool aSupportJobTitleChange ); /* Does this device allow to set/change the spooler command ? */ void SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ); @@ -245,6 +277,66 @@ void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName ) SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName); } +void nsPrinterFeatures::SetCanChangeResolutionName( PRBool aCanSetResolutionName ) +{ + SetBoolValue("can_change_resolution", aCanSetResolutionName); +} + +void nsPrinterFeatures::SetSupportsResolutionNameChange( PRBool aSupportsResolutionNameChange ) +{ + SetBoolValue("supports_resolution_change", aSupportsResolutionNameChange); +} + +void nsPrinterFeatures::SetNumResolutionNameRecords( PRInt32 aCount ) +{ + SetIntValue("resolution.count", aCount); +} + +void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName ) +{ + SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName); +} + +void nsPrinterFeatures::SetCanChangeColorspace( PRBool aCanSetColorspace ) +{ + SetBoolValue("can_change_colorspace", aCanSetColorspace); +} + +void nsPrinterFeatures::SetSupportsColorspaceChange( PRBool aSupportsColorspaceChange ) +{ + SetBoolValue("supports_colorspace_change", aSupportsColorspaceChange); +} + +void nsPrinterFeatures::SetNumColorspaceRecords( PRInt32 aCount ) +{ + SetIntValue("colorspace.count", aCount); +} + +void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace ) +{ + SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace); +} + +void nsPrinterFeatures::SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts ) +{ + SetBoolValue("can_change_downloadfonts", aCanSetDownloadFonts); +} + +void nsPrinterFeatures::SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange ) +{ + SetBoolValue("supports_downloadfonts_change", aSupportDownloadFontsChange); +} + +void nsPrinterFeatures::SetCanChangePrintInColor( PRBool aCanSetPrintInColor ) +{ + SetBoolValue("can_change_printincolor", aCanSetPrintInColor); +} + +void nsPrinterFeatures::SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange ) +{ + SetBoolValue("supports_printincolor_change", aSupportPrintInColorChange); +} + void nsPrinterFeatures::SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ) { SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand); @@ -255,6 +347,16 @@ void nsPrinterFeatures::SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerC SetBoolValue("supports_spoolercommand_change", aSupportSpoolerCommandChange); } +void nsPrinterFeatures::SetCanChangeJobTitle( PRBool aCanSetJobTitle ) +{ + SetBoolValue("can_change_jobtitle", aCanSetJobTitle); +} + +void nsPrinterFeatures::SetSupportsJobTitleChange( PRBool aSupportsJobTitle ) +{ + SetBoolValue("supports_jobtitle_change", aSupportsJobTitle); +} + void nsPrinterFeatures::SetCanChangeNumCopies( PRBool aCanSetNumCopies ) { SetBoolValue("can_change_num_copies", aCanSetNumCopies); @@ -352,6 +454,9 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings *aPS, PRUnichar *printer = nsnull; PRUnichar *papername = nsnull; PRUnichar *plexname = nsnull; + PRUnichar *resolutionname = nsnull; + PRUnichar *colorspace = nsnull; + PRBool downloadfonts = PR_TRUE; PRUnichar *printfile = nsnull; double dleft = 0.5; double dright = 0.5; @@ -362,6 +467,9 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings *aPS, aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); aPS->GetPaperName(&papername); + aPS->GetResolutionName(&resolutionname); + aPS->GetColorspace(&colorspace); + aPS->GetDownloadFonts(&downloadfonts); aPS->GetPlexName(&plexname); aPS->GetOrientation(&orientation); aPS->GetPrintCommand(&command); @@ -386,6 +494,10 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings *aPS, PL_strncpyz(mPaperName, NS_ConvertUCS2toUTF8(papername).get(), sizeof(mPaperName)); if (plexname) PL_strncpyz(mPlexName, NS_ConvertUCS2toUTF8(plexname).get(), sizeof(mPlexName)); + if (resolutionname) + PL_strncpyz(mResolutionName, NS_ConvertUCS2toUTF8(resolutionname).get(), sizeof(mResolutionName)); + if (colorspace) + PL_strncpyz(mColorspace, NS_ConvertUCS2toUTF8(colorspace).get(), sizeof(mColorspace)); DO_PR_DEBUG_LOG(("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright)); DO_PR_DEBUG_LOG(("printRange %d\n", printRange)); @@ -397,12 +509,15 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings *aPS, DO_PR_DEBUG_LOG(("printer '%s'\n", printer? NS_ConvertUCS2toUTF8(printer).get():"")); DO_PR_DEBUG_LOG(("papername '%s'\n", papername? NS_ConvertUCS2toUTF8(papername).get():"")); DO_PR_DEBUG_LOG(("plexname '%s'\n", plexname? NS_ConvertUCS2toUTF8(plexname).get():"")); + DO_PR_DEBUG_LOG(("resolution '%s'\n", resolutionname? NS_ConvertUCS2toUTF8(resolutionname).get():"")); + DO_PR_DEBUG_LOG(("colorspace '%s'\n", colorspace? NS_ConvertUCS2toUTF8(colorspace).get():"")); mTop = dtop; mBottom = dbottom; mLeft = dleft; mRight = dright; mFpf = !reversed; + mDownloadFonts = downloadfonts; mGrayscale = !color; mOrientation = orientation; mToPrinter = !tofile; @@ -510,6 +625,24 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::GetPlexName( const char **aPlexName ) return NS_OK; } +NS_IMETHODIMP nsDeviceContextSpecXlib::GetResolutionName( const char **aResolutionName ) +{ + *aResolutionName = mResolutionName; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecXlib::GetColorspace( const char **aColorspace ) +{ + *aColorspace = mColorspace; + return NS_OK; +} + +NS_IMETHODIMP nsDeviceContextSpecXlib::GetDownloadFonts(PRBool &aDownloadFonts) +{ + aDownloadFonts = mDownloadFonts; + return NS_OK; +} + NS_IMETHODIMP nsDeviceContextSpecXlib::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) { return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); @@ -752,6 +885,9 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter(const PRUnic printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_TRUE); + printerFeatures.SetSupportsResolutionNameChange(PR_TRUE); + printerFeatures.SetSupportsColorspaceChange(PR_TRUE); + printerFeatures.SetSupportsJobTitleChange(PR_TRUE); printerFeatures.SetSupportsSpoolerCommandChange(PR_FALSE); /* won't work by design and very good reasons! */ #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ @@ -904,11 +1040,89 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter(const PRUnic XpuFreeMediumSourceSizeList(mlist); } + /* Setup resolution/quality stuff */ + XpuResolutionList rlist; + int rcount; + XpuResolutionRec *default_resolution; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + PRBool canSetResolutionName = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_PRINTER_RESOLUTION); + printerFeatures.SetCanChangeResolutionName(canSetResolutionName); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + rlist = XpuGetResolutionList(pdpy, pcontext, &rcount); + if (rlist) { + default_resolution = &rlist[0]; /* First entry is the default one */ + + DO_PR_DEBUG_LOG(("setting default resolution to '%s'/%ldx%ld\n", + default_resolution->name, + default_resolution->x_dpi, + default_resolution->y_dpi)); + aPrintSettings->SetResolutionName(NS_ConvertUTF8toUCS2(default_resolution->name).get()); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; i < rcount ; i++ ) + { + XpuResolutionRec *curr = &rlist[i]; + printerFeatures.SetResolutionNameRecord(i, curr->name); + } + printerFeatures.SetNumResolutionNameRecords(rcount); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuFreeResolutionList(rlist); + } + + /* We still support the old print-in-color boolean */ + printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); + printerFeatures.SetCanChangePrintInColor(PR_TRUE); + + /* Setup colorspace stuff */ + XpuColorspaceList cslist; + int cscount; + XpuColorspaceRec *default_colorspace; + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeColorspace(PR_TRUE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + cslist = XpuGetColorspaceList(pdpy, pcontext, &cscount); + if (cslist) { + default_colorspace = &cslist[0]; /* First entry is the default one */ + + DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", default_colorspace->name)); + aPrintSettings->SetColorspace(NS_ConvertUTF8toUCS2(default_colorspace->name).get()); + +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + int i; + for( i = 0 ; i < cscount ; i++ ) + { + XpuColorspaceRec *curr = &cslist[i]; + printerFeatures.SetColorspaceRecord(i, curr->name); + } + printerFeatures.SetNumColorspaceRecords(cscount); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + XpuFreeColorspaceList(cslist); + } + + /* Fonts */ + PRBool canSetListFontsMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_LISTFONTS_MODES); + printerFeatures.SetCanChangeDownloadFonts(canSetListFontsMode); + printerFeatures.SetSupportsDownloadFontsChange(PR_TRUE); + + Bool downloadFonts = XpuGetEnableFontDownload(pdpy, pcontext); + aPrintSettings->SetDownloadFonts(downloadFonts); + #ifdef SET_PRINTER_FEATURES_VIA_PREFS /* Xprint does not allow the client to set a spooler command. * Job spooling is the job of the server side (=Xprt) */ printerFeatures.SetCanChangeSpoolerCommand(PR_FALSE); + /* Check whether printer/driver allow changes of the job name */ + PRBool canSetJobName = MAKE_PR_BOOL(XpuGetSupportedJobAttributes(pdpy, pcontext) & XPUATTRIBUTESUPPORTED_JOB_NAME); + printerFeatures.SetCanChangeJobTitle(canSetJobName); + /* Mozilla's Xprint support allows multiple nsIDeviceContext instances * be used in parallel */ printerFeatures.SetMultipleConcurrentDeviceContextsSupported(PR_TRUE); @@ -931,6 +1145,8 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter(const PRUnic printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_FALSE); + printerFeatures.SetSupportsResolutionNameChange(PR_FALSE); + printerFeatures.SetSupportsColorspaceChange(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS @@ -968,18 +1184,39 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter(const PRUnic printerFeatures.SetPlexRecord(0, "default"); printerFeatures.SetNumPlexRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ - + + /* PostScript module does not support changing the resolution mode... */ +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeResolutionName(PR_FALSE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default")); + aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get()); +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetResolutionNameRecord(0, "default"); + printerFeatures.SetNumResolutionNameRecords(1); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + + /* PostScript module does not support changing the colorspace... */ +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetCanChangeColorspace(PR_FALSE); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default")); + aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get()); +#ifdef SET_PRINTER_FEATURES_VIA_PREFS + printerFeatures.SetColorspaceRecord(0, "default"); + printerFeatures.SetNumColorspaceRecords(1); +#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ + #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangePaperSize(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ nsXPIDLCString papername; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) { nsPaperSizePS paper; - + if (paper.Find(papername)) { DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n", paper.Name(), paper.Width_mm(), paper.Height_mm())); - aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined); aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ? (int)nsIPrintSettings::kPaperSizeMillimeters : (int)nsIPrintSettings::kPaperSizeInches); @@ -1003,11 +1240,22 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter(const PRUnic #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ } - PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS == + PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS == nsPSPrinterList::GetPrinterType(fullPrinterName)); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd); printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd); + + /* Postscript module does not pass the job title to lpr */ + printerFeatures.SetSupportsJobTitleChange(PR_FALSE); + printerFeatures.SetCanChangeJobTitle(PR_FALSE); + /* Postscript module has no control over builtin fonts yet */ + printerFeatures.SetSupportsDownloadFontsChange(PR_FALSE); + printerFeatures.SetCanChangeDownloadFonts(PR_FALSE); + /* Postscript module does not support multiple colorspaces + * so it has to use the old way */ + printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); + printerFeatures.SetCanChangePrintInColor(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ if (hasSpoolerCmd) { diff --git a/gfx/src/xlib/nsDeviceContextSpecXlib.h b/gfx/src/xlib/nsDeviceContextSpecXlib.h index 59f243c3c7e9..e3e2f51c1c20 100644 --- a/gfx/src/xlib/nsDeviceContextSpecXlib.h +++ b/gfx/src/xlib/nsDeviceContextSpecXlib.h @@ -21,6 +21,7 @@ * * Contributor(s): * Roland Mainz + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -97,6 +98,9 @@ public: NS_IMETHOD GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight); NS_IMETHOD GetPaperName(const char **aPaperName); NS_IMETHOD GetPlexName(const char **aPlexName); + NS_IMETHOD GetResolutionName(const char **aResolutionName); + NS_IMETHOD GetColorspace(const char **aColorspace); + NS_IMETHOD GetDownloadFonts(PRBool &aDownloadFonts); virtual ~nsDeviceContextSpecXlib(); protected: @@ -105,6 +109,7 @@ protected: PRPackedBool mIsPPreview : 1; /* If PR_TRUE, is print preview */ PRPackedBool mFpf : 1; /* If PR_TRUE, first page first */ PRPackedBool mGrayscale : 1; /* If PR_TRUE, print grayscale */ + PRPackedBool mDownloadFonts : 1; /* If PR_TRUE, download fonts to printer */ PRPackedBool mCancel : 1; /* If PR_TRUE, user cancelled */ int mOrientation; /* Orientation e.g. Portrait */ char mCommand[PATH_MAX]; /* Print command e.g., lpr */ @@ -112,6 +117,8 @@ protected: char mPrinter[256]; /* Printer name */ char mPaperName[256]; /* Printer name */ char mPlexName[256]; /* Plex mode name */ + char mResolutionName[256];/* Resolution name */ + char mColorspace[256]; /* Colorspace */ int mCopies; /* number of copies */ float mLeft; /* left margin */ float mRight; /* right margin */ diff --git a/gfx/src/xlib/nsFontMetricsXlib.cpp b/gfx/src/xlib/nsFontMetricsXlib.cpp index 73470b2e258b..9fe07738f9d2 100644 --- a/gfx/src/xlib/nsFontMetricsXlib.cpp +++ b/gfx/src/xlib/nsFontMetricsXlib.cpp @@ -4698,10 +4698,12 @@ GetFontNames(nsFontMetricsXlibContext *aFmctx, const char* aPattern, PRBool aAny #ifdef USE_XPRINT if (aFmctx->mPrinterMode) { Bool success; - long dpi = 0; - success = XpuGetResolution(dpy, XpGetContext(dpy), &dpi); - NS_ASSERTION(success, "XpuGetResolution(dpy, XpGetContext(dpy), &dpi); failure!"); - screen_xres = screen_yres = dpi; + long x_dpi = 0, + y_dpi = 0; + success = XpuGetResolution(dpy, XpGetContext(dpy), &x_dpi, &y_dpi); + NS_ASSERTION(success, "XpuGetResolution(dpy, XpGetContext(dpy), &x_dpi, &y_dpi)!"); + screen_xres = x_dpi; + screen_yres = y_dpi; } else #endif /* USE_XPRINT */ diff --git a/gfx/src/xlib/nsGCCache.h b/gfx/src/xlib/nsGCCache.h index 884e3b01d3e2..16de97ceb058 100644 --- a/gfx/src/xlib/nsGCCache.h +++ b/gfx/src/xlib/nsGCCache.h @@ -45,14 +45,14 @@ #include #include -#include #include "nscore.h" #include "nsDebug.h" #include "prclist.h" #include +#include #define countof(x) ((int)(sizeof(x) / sizeof (*x))) -#define GC_CACHE_SIZE 32 +#define GC_CACHE_SIZE 64 #ifdef DEBUG #define DEBUG_METER(x) x diff --git a/gfx/src/xlib/nsRenderingContextXlib.cpp b/gfx/src/xlib/nsRenderingContextXlib.cpp index 29e3617081b9..35095b10a561 100644 --- a/gfx/src/xlib/nsRenderingContextXlib.cpp +++ b/gfx/src/xlib/nsRenderingContextXlib.cpp @@ -73,12 +73,6 @@ static void Widen8To16AndDraw(Drawable drawable, int text_length); -class nsRenderingContextXlibContext -{ -public: - nsGCCacheXlib mGcCache; -}; - nsresult CreateRenderingContextXlibContext(nsIDeviceContext *aDevice, nsRenderingContextXlibContext **aContext) { nsRenderingContextXlibContext *rcctx; diff --git a/gfx/src/xlib/nsRenderingContextXlib.h b/gfx/src/xlib/nsRenderingContextXlib.h index d77518f64102..736eb19e6ac0 100644 --- a/gfx/src/xlib/nsRenderingContextXlib.h +++ b/gfx/src/xlib/nsRenderingContextXlib.h @@ -59,6 +59,12 @@ class nsFontXlib; +class nsRenderingContextXlibContext +{ +public: + nsGCCacheXlib mGcCache; +}; + /* Note |nsRenderingContextXp| may override some of these methods here */ class nsRenderingContextXlib : public nsRenderingContextImpl { @@ -229,7 +235,7 @@ protected: nsresult CommonInit(void); nsCOMPtr mContext; - nsCOMPtr mOffscreenSurface; /* not supported for printers */ + nsCOMPtr mOffscreenSurface; nsCOMPtr mSurface; nsCOMPtr mFontMetrics; nsCOMPtr mClipRegion; diff --git a/gfx/src/xprint/nsDeviceContextXP.cpp b/gfx/src/xprint/nsDeviceContextXP.cpp index 5ced7f89a0db..e18b879ca180 100644 --- a/gfx/src/xprint/nsDeviceContextXP.cpp +++ b/gfx/src/xprint/nsDeviceContextXP.cpp @@ -123,11 +123,17 @@ nsDeviceContextXp::InitDeviceContextXP(nsIDeviceContext *aCreatingDeviceContext, // Initialization moved to SetSpec to be done after creating the Print Context float origscale, newscale; float t2d, a2d; - int print_resolution; + int print_x_resolution, + print_y_resolution; - mPrintContext->GetPrintResolution(print_resolution); + mPrintContext->GetPrintResolution(print_x_resolution, print_y_resolution); + + if (print_x_resolution != print_y_resolution) { + PR_LOG(nsDeviceContextXpLM, PR_LOG_DEBUG, ("print_x_resolution != print_y_resolution not yet supported by Mozilla's layout engine\n")); + return NS_ERROR_NOT_IMPLEMENTED; /* this error code should be more detailed */ + } - mPixelsToTwips = (float)NSIntPointsToTwips(72) / (float)print_resolution; + mPixelsToTwips = (float)NSIntPointsToTwips(72) / (float)print_x_resolution; mTwipsToPixels = 1.0f / mPixelsToTwips; newscale = TwipsToDevUnits(); diff --git a/gfx/src/xprint/nsIDeviceContextSpecXPrint.h b/gfx/src/xprint/nsIDeviceContextSpecXPrint.h index 10288cc64774..456084c3a613 100644 --- a/gfx/src/xprint/nsIDeviceContextSpecXPrint.h +++ b/gfx/src/xprint/nsIDeviceContextSpecXPrint.h @@ -21,6 +21,7 @@ * * Contributor(s): * Roland Mainz + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -41,7 +42,8 @@ #include "nsISupports.h" -#define NS_IDEVICE_CONTEXT_SPEC_XP_IID { 0xa4ef8910, 0xdd65, 0x11d2, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } } +/* UUID=12ab7845-a341-41ba-bc12-6025e0b11e0e */ +#define NS_IDEVICE_CONTEXT_SPEC_XP_IID { 0x12ab7845, 0xa341, 0x41ba, { 0x60, 0x25, 0xe0, 0xb1, 0x1e, 0x0e } } class nsIDeviceContextSpecXp : public nsISupports { @@ -153,7 +155,35 @@ public: * @return **/ NS_IMETHOD GetPlexName ( const char **aPlexName ) = 0; + + /* + * Resolution/quality name e.g., "600", "600x300", "high-res", + * "med-res" + * driver/printer-specific custom value + * @update + * @param aResolutionName -- + * @return + **/ + NS_IMETHOD GetResolutionName ( const char **aResolutionName ) = 0; + /* + * Colorspace name e.g., "TrueColor", "Grayscale/10bit", "b/w", + * "CYMK" + * driver/printer-specific custom value + * @update + * @param aColorspace -- + * @return + **/ + NS_IMETHOD GetColorspace ( const char **aColorspace ) = 0; + + /* + * If PR_TRUE, enable font download to printer + * @update + * @param aDownloadFonts -- + * @return + **/ + NS_IMETHOD GetDownloadFonts( PRBool &aDownloadFonts ) = 0; + /* * Return number of copies to print * @update diff --git a/gfx/src/xprint/nsRenderingContextXp.cpp b/gfx/src/xprint/nsRenderingContextXp.cpp index e527ecfbcc7c..4846ef124123 100644 --- a/gfx/src/xprint/nsRenderingContextXp.cpp +++ b/gfx/src/xprint/nsRenderingContextXp.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Roland Mainz + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -85,13 +86,8 @@ nsRenderingContextXp::Init(nsIDeviceContext* aContext) /* A printer usually does not support things like multiple drawing surfaces * (nor "offscreen" drawing surfaces... would be quite difficult to - * implement (however - Xprint API supports offscreen surfaces but Mozilla - * does not make use of them, see bug 124761 ("RFE: Make use of "offpaper" - * drawing surfaces in some printing APIs")) =:-) ... - * We just feed the nsXPContext object here directly - this is the only - * "surface" the Mozilla printer API can "draw" on ... - * |mOffscreenSurface| is just set for bug 251136 ("nsRenderingContextGTK - * uses mSurface after it's been freed") + * implement) - however the Xprint API supports offscreen surfaces for + * all DDX implementations. */ mOffscreenSurface = mSurface = mPrintContext; UpdateGC(); /* Fill |mGC| */ @@ -133,29 +129,6 @@ nsRenderingContextXp::UnlockDrawingSurface(void) return NS_OK; } -NS_IMETHODIMP -nsRenderingContextXp::SelectOffScreenDrawingSurface(nsIDrawingSurface* aSurface) -{ - PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::SelectOffScreenDrawingSurface()\n")); - return NS_OK; -} - -NS_IMETHODIMP -nsRenderingContextXp::GetDrawingSurface(nsIDrawingSurface* *aSurface) -{ - PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::GetDrawingSurface()\n")); - *aSurface = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsRenderingContextXp::CreateDrawingSurface(const nsRect& aBounds, PRUint32 aSurfFlags, nsIDrawingSurface* &aSurface) -{ - PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::CreateDrawingSurface()\n")); - aSurface = nsnull; - return NS_OK; -} - NS_IMETHODIMP nsRenderingContextXp::DrawImage(imgIContainer *aImage, const nsRect & aSrcRect, const nsRect & aDestRect) { PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::DrawImage()\n")); @@ -182,21 +155,113 @@ NS_IMETHODIMP nsRenderingContextXp::DrawImage(imgIContainer *aImage, const nsRec mTranMatrix->TransformNoXLateCoord(&sr.x, &sr.y); UpdateGC(); - return mPrintContext->DrawImage(mGC, img, + return mPrintContext->DrawImage(mSurface->GetDrawable(), + mGC, img, sr.x, sr.y, sr.width, sr.height, dr.x, dr.y, dr.width, dr.height); } -NS_IMETHODIMP -nsRenderingContextXp::CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, - const nsRect &aDestBounds, PRUint32 aCopyFlags) +#ifdef JULIEN_NOTNOW +static +void TilePixmap(Display *dpy, Pixmap src, Pixmap dest, PRInt32 aSXOffset, + PRInt32 aSYOffset, const nsRect &destRect, + const nsRect &clipRect, PRBool useClip) { - PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::CopyOffScreenBits()\n")); + GC gc; + XGCValues values; + unsigned long valuesMask; + memset(&values, 0, sizeof(XGCValues)); + values.fill_style = FillTiled; + values.tile = src; + values.ts_x_origin = destRect.x - aSXOffset; + values.ts_y_origin = destRect.y - aSYOffset; + valuesMask = GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle; + gc = XCreateGC(dpy, src, valuesMask, &values); - NS_NOTREACHED("nsRenderingContextXp::CopyOffScreenBits() not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; + if (useClip) { + XRectangle xrectangle; + xrectangle.x = clipRect.x; + xrectangle.y = clipRect.y; + xrectangle.width = clipRect.width; + xrectangle.height = clipRect.height; + XSetClipRectangles(dpy, gc, 0, 0, &xrectangle, 1, Unsorted); + } + + XFillRectangle(dpy, dest, gc, destRect.x, destRect.y, + destRect.width, destRect.height); + + XFreeGC(dpy, gc); +} +#endif /* JULIEN_NOTNOW */ + +NS_IMETHODIMP +nsRenderingContextXp::DrawTile(imgIContainer *aImage, + nscoord aSXOffset, + nscoord aSYOffset, + const nsRect *aTileRect) +{ + PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, + ("nsRenderingContextXp::DrawTile(imgIContainer *aImage, nscoord aXImageStart, nscoord aYImageStart, const nsRect *aTargetRect)\n")); + +/* xxx_julien: Either this code or the PDF DDX needs a fix */ +#ifdef JULIEN_NOTNOW + nsCOMPtr iframe; + aImage->GetCurrentFrame(getter_AddRefs(iframe)); + if (!iframe) + return NS_ERROR_FAILURE; + + nsCOMPtr img(do_GetInterface(iframe)); + if (!img) + return NS_ERROR_FAILURE; + + PushState(); + + nscoord imgwidth, imgheight; + aImage->GetWidth(&imgwidth); + aImage->GetHeight(&imgheight); + + imgwidth = NSToCoordRound(imgwidth*mP2T); + imgheight = NSToCoordRound(imgheight*mP2T); + + Drawable srcdrawable; + Drawable destdrawable; + mSurface->GetDrawable(destdrawable); + + UpdateGC(); + srcdrawable = XCreatePixmap(mDisplay, destdrawable, + imgwidth, imgheight, + xxlib_rgb_get_depth(mXlibRgbHandle)); + + XGCValues values; + unsigned long valuesMask = 0; + nsRenderingContextXlibContext *rcContext; + nsIDeviceContext *dc = mContext; + NS_STATIC_CAST(nsDeviceContextX *, dc)->GetRCContext(rcContext); + xGC *xgc = rcContext->mGcCache.GetGC(mDisplay, srcdrawable, valuesMask, &values, NULL); + + mPrintContext->DrawImage(srcdrawable, + xgc, img, + 0, 0, + img->GetWidth(), img->GetHeight(), + 0, 0, + imgwidth, imgheight); + + /* Xlib API can tile for us */ + nsRect clipRect; + PRBool isValid; + + GetClipRect(clipRect, isValid); + TilePixmap(mDisplay, srcdrawable, destdrawable, aSXOffset, aSYOffset, + *aTileRect, clipRect, PR_FALSE); + + xgc->Release(); + XFreePixmap(mDisplay, srcdrawable); + + PopState(); +#endif /* JULIEN_NOTNOW */ + return NS_OK; } NS_IMETHODIMP @@ -238,7 +303,7 @@ nsRenderingContextXp::RenderEPS(const nsRect& aRect, FILE *aDataFile) nsRect trect = aRect; mTranMatrix->TransformCoord(&trect.x, &trect.y, &trect.width, &trect.height); UpdateGC(); - rv = mPrintContext->RenderEPS(trect, data, datalen); + rv = mPrintContext->RenderEPS(mSurface->GetDrawable(), trect, data, datalen); PopState(); diff --git a/gfx/src/xprint/nsRenderingContextXp.h b/gfx/src/xprint/nsRenderingContextXp.h index e3f76586bfe1..39eea6c46f80 100644 --- a/gfx/src/xprint/nsRenderingContextXp.h +++ b/gfx/src/xprint/nsRenderingContextXp.h @@ -62,16 +62,10 @@ class nsRenderingContextXp : public nsRenderingContextXlib void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes, PRUint32 aFlags); NS_IMETHOD UnlockDrawingSurface(void); - - NS_IMETHOD SelectOffScreenDrawingSurface(nsIDrawingSurface* aSurface); - NS_IMETHOD GetDrawingSurface(nsIDrawingSurface* *aSurface); - - NS_IMETHOD CreateDrawingSurface(const nsRect& aBounds, PRUint32 aSurfFlags, nsIDrawingSurface* &aSurface); - + NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect & aSrcRect, const nsRect & aDestRect); - NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, - const nsRect &aDestBounds, PRUint32 aCopyFlags); + NS_IMETHOD DrawTile(imgIContainer *aImage, nscoord aXImageStart, nscoord aYImageStart, const nsRect *aTargetRect); NS_IMETHOD RenderEPS(const nsRect& aRect, FILE *aDataFile); diff --git a/gfx/src/xprint/nsXPrintContext.cpp b/gfx/src/xprint/nsXPrintContext.cpp index cd86ca0ca9ca..5a184d4472ff 100644 --- a/gfx/src/xprint/nsXPrintContext.cpp +++ b/gfx/src/xprint/nsXPrintContext.cpp @@ -22,6 +22,7 @@ * Contributor(s): * Roland Mainz * Leon Sha + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -60,7 +61,9 @@ #include "prprf.h" #include "plstr.h" #include "nsPrintfCString.h" - +#include "nsIServiceManager.h" +#include "nsIEnvironment.h" + /* NS_XPRINT_RGB_DITHER: Macro to check whether we should dither or not. * In theory we only have to look at the visual and depth ("TrueColor" with * enougth bits for the colors or GrayScale/StaticGray with enougth bits for @@ -112,7 +115,8 @@ nsXPrintContext::nsXPrintContext() : mIsAPrinter(PR_TRUE), /* default destination is printer */ mPrintFile(nsnull), mXpuPrintToFileHandle(nsnull), - mPrintResolution(0L), + mPrintXResolution(0L), + mPrintYResolution(0L), mContext(nsnull) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::nsXPrintContext()\n")); @@ -186,20 +190,16 @@ nsXPrintContext::Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec) PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::Init()\n")); nsresult rv = NS_ERROR_FAILURE; - int prefDepth = 24; /* 24 or 8 for PS DDX, 24, 8, 1 for PCL DDX... - * I wish current Xprt would have a 1bit/8bit StaticGray - * visual for the PS DDX... ;-( - */ - /* Safeguard for production use (see bug 80562), - * Make sure we can switch back to the - * extensively tested 8bit Pseudocolor visual on demand... */ - if( PR_GetEnv("MOZILLA_XPRINT_EXPERIMENTAL_DISABLE_24BIT_VISUAL") != nsnull ) - { - prefDepth = 8; - } - - unsigned short width, height; - XRectangle rect; + + unsigned short width, + height; + XRectangle rect; + const char *colorspace; + XpuColorspaceList cslist; + int cscount; + XpuColorspaceRec *cs; + VisualID csvid; + int cs_class; if (NS_FAILED(XPU_TRACE(rv = SetupPrintContext(aSpec)))) return rv; @@ -207,70 +207,91 @@ nsXPrintContext::Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec) mScreen = XpGetScreenOfContext(mPDisplay, mPContext); mScreenNumber = XScreenNumberOfScreen(mScreen); + /* Convert colorspace name into visualid */ + aSpec->GetColorspace(&colorspace); + cslist = XpuGetColorspaceList(mPDisplay, mPContext, &cscount); + if (!cslist) { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuGetColorspaceList() failed.\n")); + return NS_ERROR_GFX_PRINTER_COLORSPACE_NOT_SUPPORTED; + } + cs = XpuFindColorspaceByName(cslist, cscount, colorspace); + if (!cs) { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuFindColorspaceByName() failed.\n")); + XpuFreeColorspaceList(cslist); + return NS_ERROR_GFX_PRINTER_COLORSPACE_NOT_SUPPORTED; + } + csvid = cs->visualinfo.visualid; + cs_class = cs->visualinfo.c_class; + XpuFreeColorspaceList(cslist); + XlibRgbArgs xargs; memset(&xargs, 0, sizeof(xargs)); xargs.handle_name = nsnull; xargs.disallow_image_tiling = True; /* XlibRGB's "Image tiling"-hack is * incompatible to Xprint API */ - /* What about B/W-only printers ?! */ if (mIsGrayscale) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("printing grayscale\n")); - /* 1st attempt using StaticGray */ - xargs.xtemplate.c_class = StaticGray; - xargs.xtemplate.depth = 8; - xargs.xtemplate_mask = VisualClassMask|VisualDepthMask; - mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); - if (!mXlibRgbHandle) + + /* This is compliciated: Older versions of Xprt do not always have + * Grayscale/StaticGray visual for a chosen printer so we only use + * the selected visual when it really represents gray color values. + * If the selected visual does not match that requirement we jump + * into an "emulation" codepath which tries to find a visual which + * matches the requirement for grayscale or b/w output */ + if ((cs_class | GrayScale) == GrayScale) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("using selected gray visual\n")); + xargs.xtemplate_mask = VisualIDMask; + xargs.xtemplate.visualid = csvid; + mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); + } + else { - /* 2nd attempt using GrayScale */ - xargs.xtemplate.c_class = GrayScale; + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("using fallback codepath\n")); + /* 1st attempt using GrayScale */ + xargs.xtemplate.c_class = StaticGray; xargs.xtemplate.depth = 8; xargs.xtemplate_mask = VisualClassMask|VisualDepthMask; mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); - if (!mXlibRgbHandle) - { - /* Last attempt: Emulate StaticGray via Pseudocolor colormap */ - xargs.xtemplate_mask = 0L; - xargs.xtemplate.depth = 0; - xargs.pseudogray = True; - mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); - } if (!mXlibRgbHandle) - { - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("trying black/white\n")); - - /* Last attempt using StaticGray 1bit (b/w printer) */ - xargs.xtemplate.c_class = StaticGray; - xargs.xtemplate.depth = 1; + { + /* 2nd attempt using GrayScale */ + xargs.xtemplate.c_class = GrayScale; + xargs.xtemplate.depth = 8; xargs.xtemplate_mask = VisualClassMask|VisualDepthMask; - xargs.pseudogray = False; - mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); + mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); + if (!mXlibRgbHandle) + { + /* Last attempt: Emulate StaticGray via Pseudocolor colormap */ + xargs.xtemplate_mask = 0L; + xargs.xtemplate.depth = 0; + xargs.pseudogray = True; + mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); + } + + if (!mXlibRgbHandle) + { + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("trying black/white\n")); + + /* Last attempt using StaticGray 1bit (b/w printer) */ + xargs.xtemplate.c_class = StaticGray; + xargs.xtemplate.depth = 1; + xargs.xtemplate_mask = VisualClassMask|VisualDepthMask; + xargs.pseudogray = False; + mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); + } } - } + } } else { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("printing color\n")); - if (prefDepth > 12) - { - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("trying TrueColor %d bit\n", prefDepth)); - xargs.xtemplate.depth = prefDepth; - xargs.xtemplate.c_class = TrueColor; - xargs.xtemplate_mask = VisualDepthMask|VisualClassMask; - mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); - } - - if (!mXlibRgbHandle) - { - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("trying PseudoColor 8 bit\n")); - xargs.xtemplate.depth = 8; - xargs.xtemplate.c_class = PseudoColor; - xargs.xtemplate_mask = VisualDepthMask|VisualClassMask; - mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); - } + xargs.xtemplate_mask = VisualIDMask; + xargs.xtemplate.visualid = csvid; + mXlibRgbHandle = xxlib_rgb_create_handle(mPDisplay, mScreen, &xargs); } /* No XlibRgb handle ? Either we do not have a matching visual or no memory... */ @@ -301,6 +322,66 @@ nsXPrintContext::Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec) return NS_OK; } +NS_IMETHODIMP +nsXPrintContext::GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight) +{ + *aWidth = mWidth; + *aHeight = mHeight; + return NS_OK; +} + +NS_IMETHODIMP +nsXPrintContext::IsOffscreen(PRBool *aOffScreen) +{ + *aOffScreen = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsXPrintContext::IsPixelAddressable(PRBool *aAddressable) +{ + *aAddressable = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsXPrintContext::GetPixelFormat(nsPixelFormat *aFormat) +{ + *aFormat = mPixFormat; + return NS_OK; +} + +PRUint8 +nsXPrintContext::GetShiftForMask(unsigned long val) +{ + PRUint8 cur_bit = 0; + // walk through the number, looking for the first 1 + while (cur_bit < (sizeof(unsigned long) * 8)) { + if ((val >> cur_bit) & 0x1) { + return cur_bit; + } + cur_bit++; + } + return cur_bit; +} + +PRUint8 +nsXPrintContext::ConvertMaskToCount(unsigned long val) +{ + PRUint8 retval = 0; + PRUint8 cur_bit = 0; + // walk through the number, incrementing the value if + // the bit in question is set. + while (cur_bit < (sizeof(unsigned long) * 8)) { + if ((val >> cur_bit) & 0x1) { + retval++; + } + cur_bit++; + } + return retval; +} + + nsresult nsXPrintContext::SetupWindow(int x, int y, int width, int height) { @@ -321,6 +402,19 @@ nsXPrintContext::SetupWindow(int x, int y, int width, int height) visual_info = xxlib_rgb_get_visual_info(mXlibRgbHandle); mVisual = xxlib_rgb_get_visual(mXlibRgbHandle); mDepth = xxlib_rgb_get_depth(mXlibRgbHandle); + + mPixFormat.mRedMask = visual_info->red_mask; + mPixFormat.mGreenMask = visual_info->green_mask; + mPixFormat.mBlueMask = visual_info->blue_mask; + mPixFormat.mAlphaMask = 0; + mPixFormat.mRedCount = ConvertMaskToCount(visual_info->red_mask); + mPixFormat.mGreenCount = ConvertMaskToCount(visual_info->green_mask); + mPixFormat.mBlueCount = ConvertMaskToCount(visual_info->blue_mask); + mPixFormat.mAlphaCount = 0; + mPixFormat.mRedShift = GetShiftForMask(visual_info->red_mask); + mPixFormat.mGreenShift = GetShiftForMask(visual_info->green_mask); + mPixFormat.mBlueShift = GetShiftForMask(visual_info->blue_mask); + mPixFormat.mAlphaShift = 0; background = xxlib_rgb_xpixel_from_rgb(mXlibRgbHandle, NS_TO_XXLIB_RGB(NS_RGB(0xFF, 0xFF, 0xFF))); /* white */ foreground = xxlib_rgb_xpixel_from_rgb(mXlibRgbHandle, NS_TO_XXLIB_RGB(NS_RGB(0x00, 0x00, 0x00))); /* black */ @@ -349,8 +443,8 @@ nsXPrintContext::SetupWindow(int x, int y, int width, int height) /* %p would be better instead of %lx for pointers - but does PR_LOG() support that ? */ PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, - ("nsXPrintContext::SetupWindow: mDepth=%d, mScreenNumber=%d, colormap=%lx, mDrawable=%lx\n", - (int)mDepth, (int)mScreenNumber, (long)xattributes.colormap, (long)mDrawable)); + ("nsXPrintContext::SetupWindow: mVisual->visualid=%x, mVisual->c_class=%x, mDepth=%d, mScreenNumber=%d, colormap=%lx, mDrawable=%lx\n", + (int)mVisual->visualid, (int)mVisual->c_class, (int)mDepth, (int)mScreenNumber, (long)xattributes.colormap, (long)mDrawable)); return NS_OK; } @@ -567,6 +661,10 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) const char *printername; nsresult rv; + nsCOMPtr uEnv = do_GetService("@mozilla.org/process/environment;1", &rv); + if (NS_FAILED(rv)) + return rv; + // Get the Attributes aSpec->GetToPrinter(mIsAPrinter); aSpec->GetGrayscale(mIsGrayscale); @@ -606,12 +704,16 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) * shared memory transport is used XCloseDisplay() tries to free() the * shared memory segment - causing heap corruption and/or SEGV. */ - PR_SetEnv("XSUNTRANSPORT=xxx"); + uEnv->Set(NS_LITERAL_STRING("XSUNTRANSPORT"), NS_LITERAL_STRING("xxx")); /* Get printer, either by "name" (foobar) or "name@display" (foobar@gaja:5) */ if( XpuGetPrinter(printername, &mPDisplay, &mPContext) != 1 ) return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND; + /* Remember the last used printer as new "default" printer as long this + * Mozilla instance is running */ + uEnv->Set(NS_LITERAL_STRING("XPRINTER"), NS_ConvertUTF8toUCS2(printername)); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetupPrintContext: name='%s', display='%s', vendor='%s', release=%ld\n", printername, @@ -629,10 +731,14 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) dumpXpAttributes(mPDisplay, mPContext); #endif /* XPRINT_DEBUG_SOMETIMES_USEFULL */ - const char *paper_name = nsnull, - *plex_name = nsnull; + const char *paper_name = nsnull, + *plex_name = nsnull, + *resolution_name = nsnull; + PRBool downloadfonts = PR_TRUE; aSpec->GetPaperName(&paper_name); aSpec->GetPlexName(&plex_name); + aSpec->GetResolutionName(&resolution_name); + aSpec->GetDownloadFonts(downloadfonts); if (NS_FAILED(XPU_TRACE(rv = SetMediumSize(paper_name)))) return rv; @@ -643,11 +749,14 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) if (NS_FAILED(XPU_TRACE(rv = SetPlexMode(plex_name)))) return rv; - if (NS_FAILED(XPU_TRACE(rv = SetResolution()))) + if (NS_FAILED(XPU_TRACE(rv = SetResolution(resolution_name)))) return rv; if (XPU_TRACE(XpuSetDocumentCopies(mPDisplay, mPContext, num_copies)) != 1) return NS_ERROR_GFX_PRINTER_TOO_MANY_COPIES; + + if (XPU_TRACE(XpuSetEnableFontDownload(mPDisplay, mPContext, downloadfonts)) != 1) + return NS_ERROR_GFX_PRINTER_DRIVER_CONFIGURATION_ERROR; /* set printer context * WARNING: after this point it is no longer allows to change job attributes @@ -662,10 +771,11 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) #endif /* XPRINT_DEBUG_SOMETIMES_USEFULL */ /* Get default printer resolution. May fail if Xprt is misconfigured.*/ - if( XpuGetResolution(mPDisplay, mPContext, &mPrintResolution) != 1 ) + if( XpuGetResolution(mPDisplay, mPContext, &mPrintXResolution, &mPrintYResolution) != 1 ) return NS_ERROR_GFX_PRINTER_DRIVER_CONFIGURATION_ERROR; - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("print resolution %ld\n", (long)mPrintResolution)); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, + ("print resolution %ld%x%ld\n", mPrintXResolution, mPrintYResolution)); /* We want to get events when Xp(Start|End)(Job|Page) requests are processed... */ XpSelectInput(mPDisplay, mPContext, XPPrintMask); @@ -674,14 +784,13 @@ nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXp *aSpec) } NS_IMETHODIMP -nsXPrintContext::SetResolution( void ) +nsXPrintContext::SetResolution(const char *resolution_name) { XpuResolutionList list; int list_count; XpuResolutionRec *match; int i; - long default_resolution; - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetResolution().\n")); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetResolution('resolution_name=%s').\n", resolution_name)); list = XpuGetResolutionList(mPDisplay, mPContext, &list_count); if( !list ) @@ -692,42 +801,22 @@ nsXPrintContext::SetResolution( void ) for( i = 0 ; i < list_count ; i++ ) { XpuResolutionRec *curr = &list[i]; - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("got resolution=%ld\n", (long)curr->dpi)); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, + ("got resolution='%s'/%ldx%ld\n", curr->name, curr->x_dpi, curr->y_dpi)); } #endif /* PR_LOGGING */ - /* We rely on printer default resolution if we have one... */ - if( XpuGetResolution(mPDisplay, mPContext, &default_resolution) == 1 ) - { - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("using printers default resolution=%ld.\n", default_resolution)); - XpuFreeResolutionList(list); - return NS_OK; - } - - /* XXX: Hardcoded resolution values... */ - match = XpuFindResolution(list, list_count, 300, 300); + /* Find requested resolution mode */ + match = XpuFindResolutionByName(list, list_count, resolution_name); if (!match) { - /* Find a match between 300-600, lower resolution is better */ - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("searching between 300-600, lower resolution is better...\n")); - match = XpuFindResolution(list, list_count, 300, 600); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuFindResolutionByName() failure.\n")); + XpuFreeResolutionList(list); + return NS_ERROR_GFX_PRINTER_RESOLUTION_NOT_SUPPORTED; + } - if (!match) - { - /* Find a match between 150-300, higher resolution is better */ - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("searching between 150-300, higher resolution is better...\n")); - match = XpuFindResolution(list, list_count, 300, 150); - - if (!match) - { - /* If there is still no match then use the first one from the matches we - * obtained...*/ - match = &list[0]; - } - } - } - - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("setting resolution to %ld DPI.\n", match->dpi)); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("setting resolution to '%s'/%ldx%ld DPI.\n", + match->name, match->x_dpi, match->y_dpi)); if (XpuSetDocResolution(mPDisplay, mPContext, match) != 1) { @@ -762,11 +851,7 @@ nsXPrintContext::BeginDocument( PRUnichar * aTitle, PRUnichar* aPrintToFileName, { /* Note that this is _only_ a _hack_ until bug 73446 * ("RFE: Need NS_ConvertUCS2ToLocalEncoding() and - * NS_ConvertLocalEncodingToUCS2()") is implemented... - * Below we need COMPOUNT_TEXT which usually is the same as the Xserver's - * local encoding - this hack should at least work for C/POSIX - * and *.UTF-8 locales... - */ + * NS_ConvertLocalEncodingToUCS2()") is implemented...) */ job_title.Assign(NS_ConvertUCS2toUTF8(aTitle)); } else @@ -848,6 +933,36 @@ nsXPrintContext::EndDocument() mXpuPrintToFileHandle = nsnull; } + /* + * end of spooled job - get spooler command results + */ + const char *results, + *lresults; + results = XpGetOneAttribute(mPDisplay, mPContext, XPJobAttr, + "xp-spooler-command-results"); + + if( results && + (strlen(results) != 0) ) + { + lresults = XpuCompoundTextToXmb(mPDisplay, results); + } + else + { + lresults = NULL; + } + /* present spooler command results + * TODO: Open a dialog and present the message there. + */ + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, + ("Printing complete - spooler command result '%s'/'%s'\n", + results ? results : "", + lresults ? lresults : "")); + if( lresults ) + XpuFreeXmbString(lresults); + + if( results ) + XFree((void *)results); + mJobStarted = PR_FALSE; return NS_OK; @@ -982,12 +1097,13 @@ PRUint8 *ComposeAlphaImage( NS_IMETHODIMP -nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, +nsXPrintContext::DrawImage(Drawable aDrawable, xGC *xgc, nsIImage *aImage, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, - ("nsXPrintContext::DrawImage(%d/%d/%d/%d - %d/%d/%d/%d)\n", + ("nsXPrintContext::DrawImage(%lx, %d/%d/%d/%d - %d/%d/%d/%d)\n", + (long)aDrawable, (int)aSX, (int)aSY, (int)aSWidth, (int)aSHeight, (int)aDX, (int)aDY, (int)aDWidth, (int)aDHeight)); @@ -1030,9 +1146,9 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, scalingFactor *= PR_MIN(scale_x, scale_y); /* Adjust destination size to the match the scaling factor */ - imageResolution = long( double(mPrintResolution) * scalingFactor); - aDWidth_scaled = PRInt32(double(aDWidth) * scalingFactor); - aDHeight_scaled = PRInt32(double(aDHeight) * scalingFactor); + imageResolution = long( double(mPrintXResolution) * scalingFactor); + aDWidth_scaled = PRInt32(double(aDWidth) * scalingFactor); + aDHeight_scaled = PRInt32(double(aDHeight) * scalingFactor); /* Check if we scaled the image to zero width/height - if "yes" then use the * smaller scaling factor and try again ... */ @@ -1043,9 +1159,9 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, scalingFactor *= PR_MAX(scale_x, scale_y); /* Adjust destination size to the match the (new) scaling factor */ - imageResolution = long( double(mPrintResolution) * scalingFactor); - aDWidth_scaled = PRInt32(double(aDWidth) * scalingFactor); - aDHeight_scaled = PRInt32(double(aDHeight) * scalingFactor); + imageResolution = long( double(mPrintXResolution) * scalingFactor); + aDWidth_scaled = PRInt32(double(aDWidth) * scalingFactor); + aDHeight_scaled = PRInt32(double(aDHeight) * scalingFactor); } /* Image scaled to 0 width/height ? */ @@ -1071,12 +1187,12 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, if( (aSX != 0) || (aSY != 0) || (aSWidth != aDWidth_scaled) || (aSHeight != aDHeight_scaled) ) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("using DrawImageBitsScaled()\n")); - rv = DrawImageBitsScaled(xgc, aImage, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth_scaled, aDHeight_scaled); + rv = DrawImageBitsScaled(aDrawable, xgc, aImage, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth_scaled, aDHeight_scaled); } else { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("using DrawImage() [shortcut]\n")); - rv = DrawImage(xgc, aImage, aDX, aDY, aDWidth_scaled, aDHeight_scaled); + rv = DrawImage(aDrawable, xgc, aImage, aDX, aDY, aDWidth_scaled, aDHeight_scaled); } /* reset image resolution to previous resolution */ @@ -1089,7 +1205,7 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, (void)XpSetImageResolution(mPDisplay, mPContext, prev_res, &dummy); /* scale image on our side (bad) */ - rv = DrawImageBitsScaled(xgc, aImage, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight); + rv = DrawImageBitsScaled(aDrawable, xgc, aImage, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight); } return rv; @@ -1098,12 +1214,13 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, // use DeviceContextImpl :: GetCanonicalPixelScale(float &aScale) // to get the pixel scale of the device context nsresult -nsXPrintContext::DrawImageBitsScaled(xGC *xgc, nsIImage *aImage, +nsXPrintContext::DrawImageBitsScaled(Drawable aDrawable, xGC *xgc, nsIImage *aImage, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, - ("nsXPrintContext::DrawImageBitsScaled(%d/%d/%d/%d - %d/%d/%d/%d)\n", + ("nsXPrintContext::DrawImageBitsScaled(%lx, %d/%d/%d/%d - %d/%d/%d/%d)\n", + (long)aDrawable, (int)aSX, (int)aSY, (int)aSWidth, (int)aSHeight, (int)aDX, (int)aDY, (int)aDWidth, (int)aDHeight)); @@ -1180,7 +1297,7 @@ nsXPrintContext::DrawImageBitsScaled(xGC *xgc, nsIImage *aImage, /* ToDo: scale alpha image */ #endif /* XPRINT_SERVER_SIDE_ALPHA_COMPOSING */ - rv = DrawImageBits(xgc, alphaBits, alphaRowBytes, alphaDepth, + rv = DrawImageBits(aDrawable, xgc, alphaBits, alphaRowBytes, alphaDepth, dstimg_data, dstimg_bytes_per_line, aDX, aDY, aDWidth, aDHeight); @@ -1196,11 +1313,12 @@ nsXPrintContext::DrawImageBitsScaled(xGC *xgc, nsIImage *aImage, NS_IMETHODIMP -nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, +nsXPrintContext::DrawImage(Drawable aDrawable, xGC *xgc, nsIImage *aImage, PRInt32 aX, PRInt32 aY, PRInt32 dummy1, PRInt32 dummy2) { - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::DrawImage(%d/%d/%d(=dummy)/%d(=dummy))\n", + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::DrawImage(%lx, %d/%d/%d(=dummy)/%d(=dummy))\n", + (long)aDrawable, (int)aX, (int)aY, (int)dummy1, (int)dummy2)); aImage->LockImagePixels(PR_FALSE); @@ -1239,7 +1357,7 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, alphaBits = nsnull; } - rv = DrawImageBits(xgc, alphaBits, alphaRowBytes, alphaDepth, + rv = DrawImageBits(aDrawable, xgc, alphaBits, alphaRowBytes, alphaDepth, image_bits, row_bytes, aX, aY, width, height); @@ -1254,14 +1372,14 @@ nsXPrintContext::DrawImage(xGC *xgc, nsIImage *aImage, // Draw the bitmap, this draw just has destination coordinates nsresult -nsXPrintContext::DrawImageBits(xGC *xgc, +nsXPrintContext::DrawImageBits(Drawable aDrawable, xGC *xgc, PRUint8 *alphaBits, PRInt32 alphaRowBytes, PRUint8 alphaDepth, PRUint8 *image_bits, PRInt32 row_bytes, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { - PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::DrawImageBits(%d/%d/%d/%d)\n", - (int)aX, (int)aY, (int)aWidth, (int)aHeight)); + PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::DrawImageBits(%lx, %d/%d/%d/%d)\n", + (long)aDrawable, (int)aX, (int)aY, (int)aWidth, (int)aHeight)); Pixmap alpha_pixmap = None; GC image_gc; @@ -1282,7 +1400,7 @@ nsXPrintContext::DrawImageBits(xGC *xgc, XGCValues gcv; alpha_pixmap = XCreatePixmap(mPDisplay, - mDrawable, + aDrawable, aWidth, aHeight, 1); /* ToDo: Check for error */ /* Make an image out of the alpha-bits created by the image library (ToDo: check for error) */ @@ -1335,7 +1453,7 @@ nsXPrintContext::DrawImageBits(xGC *xgc, gcv.clip_x_origin = aX; gcv.clip_y_origin = aY; - image_gc = XCreateGC(mPDisplay, mDrawable, + image_gc = XCreateGC(mPDisplay, aDrawable, (GCForeground|GCBackground|GCFunction| GCClipXOrigin|GCClipYOrigin|GCClipMask), &gcv); @@ -1349,8 +1467,8 @@ nsXPrintContext::DrawImageBits(xGC *xgc, xxlib_draw_xprint_scaled_rgb_image(mXlibRgbHandle, - mDrawable, - mPrintResolution, XpGetImageResolution(mPDisplay, mPContext), + aDrawable, + mPrintXResolution, XpGetImageResolution(mPDisplay, mPContext), image_gc, aX, aY, aWidth, aHeight, NS_XPRINT_RGB_DITHER, @@ -1365,19 +1483,20 @@ nsXPrintContext::DrawImageBits(xGC *xgc, return NS_OK; } -NS_IMETHODIMP nsXPrintContext::GetPrintResolution(int &aPrintResolution) +NS_IMETHODIMP nsXPrintContext::GetPrintResolution(int &aXres, int &aYres) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, - ("nsXPrintContext::GetPrintResolution() res=%d, mPContext=%lx\n", - (int)mPrintResolution, (long)mPContext)); + ("nsXPrintContext::GetPrintResolution() res=%ldx%ld, mPContext=%lx\n", + mPrintXResolution, mPrintYResolution,(long)mPContext)); if(mPContext!=None) { - aPrintResolution = mPrintResolution; + aXres = mPrintXResolution; + aYres = mPrintYResolution; return NS_OK; } - aPrintResolution = 0; + aXres = aYres = 0; return NS_ERROR_FAILURE; } @@ -1534,7 +1653,9 @@ class nsEPSObjectXp { } }; -NS_IMETHODIMP nsXPrintContext::RenderEPS(const nsRect& aRect, const unsigned char *aData, unsigned long aDatalen) +NS_IMETHODIMP nsXPrintContext::RenderEPS(Drawable aDrawable, + const nsRect& aRect, + const unsigned char *aData, unsigned long aDatalen) { PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::EPS(aData, aDatalen=%d)\n", aDatalen)); @@ -1646,7 +1767,7 @@ NS_IMETHODIMP nsXPrintContext::RenderEPS(const nsRect& aRect, const unsigned cha * supported options/option values) */ /* XpPutDocumentData() takes |const| input for all string arguments, only the X11 prototypes do not allow |const| yet */ - XpPutDocumentData(mPDisplay, mDrawable, (unsigned char *)embedData, embedDataLength, (char *)type, (char *)option); + XpPutDocumentData(mPDisplay, aDrawable, (unsigned char *)embedData, embedDataLength, (char *)type, (char *)option); XFree((void *)embedded_formats_supported); diff --git a/gfx/src/xprint/nsXPrintContext.h b/gfx/src/xprint/nsXPrintContext.h index a32941c718c3..1254e3ecbbd3 100644 --- a/gfx/src/xprint/nsXPrintContext.h +++ b/gfx/src/xprint/nsXPrintContext.h @@ -22,6 +22,7 @@ * Contributor(s): * Roland Mainz * Leon Sha + * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -65,15 +66,16 @@ public: void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes, PRUint32 aFlags) { return NS_OK; }; NS_IMETHOD Unlock(void) { return NS_OK; }; - NS_IMETHOD GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight) { return NS_OK; }; - NS_IMETHOD IsOffscreen(PRBool *aOffScreen) { return NS_OK; }; - NS_IMETHOD IsPixelAddressable(PRBool *aAddressable) { return NS_OK; }; - NS_IMETHOD GetPixelFormat(nsPixelFormat *aFormat) { return NS_OK; }; - + + NS_IMETHOD GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight); + NS_IMETHOD IsOffscreen(PRBool *aOffScreen); + NS_IMETHOD IsPixelAddressable(PRBool *aAddressable); + NS_IMETHOD GetPixelFormat(nsPixelFormat *aFormat); + NS_IMETHOD Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec); NS_IMETHOD BeginPage(); NS_IMETHOD EndPage(); - NS_IMETHOD RenderEPS(const nsRect& aRect, const unsigned char *aData, unsigned long aDatalen); + NS_IMETHOD RenderEPS(Drawable aDrawable, const nsRect& aRect, const unsigned char *aData, unsigned long aDatalen); NS_IMETHOD BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage); NS_IMETHOD EndDocument(); NS_IMETHOD AbortDocument(); @@ -88,22 +90,23 @@ public: void SetGC(xGC *aGC) { mGC = aGC; mGC->AddRef(); } - NS_IMETHOD GetPrintResolution(int &aPrintResolution); + NS_IMETHOD GetPrintResolution(int &aXres, int &aYres); - NS_IMETHOD DrawImage(xGC *gc, nsIImage *aImage, + NS_IMETHOD DrawImage(Drawable aDrawable, xGC *gc, nsIImage *aImage, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight); - NS_IMETHOD DrawImage(xGC *gc, nsIImage *aImage, + NS_IMETHOD DrawImage(Drawable aDrawable, xGC *gc, nsIImage *aImage, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); private: - nsresult DrawImageBitsScaled(xGC *gc, nsIImage *aImage, + nsresult DrawImageBitsScaled(Drawable aDrawable, + xGC *gc, nsIImage *aImage, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight); - nsresult DrawImageBits(xGC *gc, + nsresult DrawImageBits(Drawable aDrawable, xGC *gc, PRUint8 *alphaBits, PRInt32 alphaRowBytes, PRUint8 alphaDepth, PRUint8 *image_bits, PRInt32 row_bytes, PRInt32 aX, PRInt32 aY, @@ -113,7 +116,8 @@ private: Display *mPDisplay; Screen *mScreen; Visual *mVisual; - Drawable mDrawable; /* window */ + Drawable mDrawable; /* window/paper surface */ + nsPixelFormat mPixFormat; xGC *mGC; int mXpEventBase, /* XpExtension X event base */ mXpErrorBase; /* XpExtension X error base */ @@ -127,15 +131,19 @@ private: PRBool mIsAPrinter; /* destination: printer or file ? */ const char *mPrintFile; /* file to "print" to */ void *mXpuPrintToFileHandle; /* handle for XpuPrintToFile/XpuWaitForPrintFileChild when printing to file */ - long mPrintResolution; + long mPrintXResolution, + mPrintYResolution; nsDeviceContextXp *mContext; /* DeviceContext which created this object */ + static PRUint8 ConvertMaskToCount(unsigned long val); + static PRUint8 GetShiftForMask(unsigned long val); + nsresult SetupWindow(int x, int y, int width, int height); nsresult SetupPrintContext(nsIDeviceContextSpecXp *aSpec); nsresult SetMediumSize(const char *paper_name); nsresult SetOrientation(int landscape); nsresult SetPlexMode(const char *plexname); - nsresult SetResolution(void); + nsresult SetResolution(const char *resolution_name); }; diff --git a/gfx/src/xprintutil/xprintutil.c b/gfx/src/xprintutil/xprintutil.c index df2917ae642c..5693493290c3 100644 --- a/gfx/src/xprintutil/xprintutil.c +++ b/gfx/src/xprintutil/xprintutil.c @@ -49,7 +49,7 @@ #include "plstr.h" #undef strtok_r #define strtok_r(s1, s2, x) PL_strtok_r((s1), (s2), (x)) -#endif /* USE_MOZILLA_TYPES */ +#endif /* XPU_USE_NSPR */ /* List of tokens which can be used to separate entries in the * $XPSERVERLIST env var */ @@ -367,7 +367,13 @@ int XpuSetJobTitle( Display *pdpy, XPContext pcontext, const char *title ) { if( XpuGetSupportedJobAttributes(pdpy, pcontext) & XPUATTRIBUTESUPPORTED_JOB_NAME ) { - XpuSetOneAttribute(pdpy, pcontext, XPJobAttr, "*job-name", title, XPAttrMerge); + char *encoded_title; + + encoded_title = XpuResourceEncode(title); + if (!encoded_title) + return(0); + XpuSetOneAttribute(pdpy, pcontext, XPJobAttr, "*job-name", encoded_title, XPAttrMerge); + XpuResourceFreeString(encoded_title); return(1); } else @@ -1202,6 +1208,7 @@ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int * const char *s; long default_resolution = -1; int default_resolution_rec_index = -1; + char namebuf[64]; /* Get default document resolution */ if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", &default_resolution) != 1 ) @@ -1236,12 +1243,16 @@ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int * if( !list ) return(NULL); - list[rec_count-2].dpi = tmp; + sprintf(namebuf, "%lddpi", tmp); + list[rec_count-2].name = strdup(namebuf); + list[rec_count-2].x_dpi = tmp; + list[rec_count-2].y_dpi = tmp; if( default_resolution != -1 ) { /* Is this the default resolution ? */ - if( list[rec_count-2].dpi == default_resolution ) + if( (list[rec_count-2].x_dpi == default_resolution) && + (list[rec_count-2].y_dpi == default_resolution) ) { default_resolution_rec_index = rec_count-2; } @@ -1253,10 +1264,12 @@ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int * 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 + * (this is only to make current impl. of XpuGetResolutionList() easier) + * We may remove this implementation detail in a later revision of * the library! */ - list[rec_count-1].dpi = -1; + list[rec_count-1].name = NULL; + list[rec_count-1].x_dpi = -1; + list[rec_count-1].y_dpi = -1; rec_count--; } else @@ -1281,53 +1294,34 @@ void XpuFreeResolutionList( XpuResolutionList list ) { if( list ) { + XpuResolutionRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->name != NULL ) + { + free((void *)curr->name); + curr++; + } + free(list); } } /* Find resolution in resolution list. - * Lower resolutions are preferred over larger resolution if |dpi_a| <= |dpi_b|, - * otherwise larger resolutions are preferred over small resolutions */ -XpuResolutionRec *XpuFindResolution( XpuResolutionList list, int list_count, long dpi_a, long dpi_b ) +XpuResolutionRec *XpuFindResolutionByName( XpuResolutionList list, int list_count, const char *name) { - XpuResolutionRec *match = NULL; - int i; + int i; - if( dpi_a <= dpi_b ) + for( i = 0 ; i < list_count ; i++ ) { - /* Search list, lower resolutions are better... */ - for( i = 0 ; i < list_count ; i++ ) - { - XpuResolutionRec *curr = &list[i]; - - if( curr->dpi >= dpi_a && curr->dpi <= dpi_b ) - { - if( !match || (curr->dpi < match->dpi) ) - { - match = curr; - } - } - } - } - else - { - /* Search list, higher resolutions are better... */ - for( i = 0 ; i < list_count ; i++ ) - { - XpuResolutionRec *curr = &list[i]; - - if( curr->dpi >= dpi_b && curr->dpi <= dpi_a ) - { - if( !match || (curr->dpi > match->dpi) ) - { - match = curr; - } - } - } + XpuResolutionRec *curr = &list[i]; + if (!strcasecmp(curr->name, name)) + return curr; } - return(match); + return NULL; } /* Get default page (if defined) or document resolution @@ -1335,17 +1329,23 @@ XpuResolutionRec *XpuFindResolution( XpuResolutionList list, int list_count, lon * - No default resolution set yet * - X DPI != Y DPI (not yet implemented in Xprt) */ -Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi_ptr ) +Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *x_dpi_ptr, long *y_dpi_ptr ) { + long dpi; + /* 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 ) + if( XpuGetOneLongAttribute(pdpy, pcontext, XPPageAttr, "default-printer-resolution", &dpi) == 1 ) { + *x_dpi_ptr = dpi; + *y_dpi_ptr = dpi; return True; } /* Get document resolution */ - if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", dpi_ptr) == 1 ) + if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", &dpi) == 1 ) { + *x_dpi_ptr = dpi; + *y_dpi_ptr = dpi; return True; } @@ -1355,7 +1355,13 @@ Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi_ptr ) static int XpuSetResolution( Display *pdpy, XPContext pcontext, XPAttributes type, XpuResolutionRec *rec ) { - XpuSetOneLongAttribute(pdpy, pcontext, type, "*default-printer-resolution", rec->dpi, XPAttrMerge); + if( rec->x_dpi != rec->y_dpi ) + { + fprintf(stderr, "XpuSetResolution: internal error: x_dpi != y_dpi not supported yet.\n"); + return 0; + } + + XpuSetOneLongAttribute(pdpy, pcontext, type, "*default-printer-resolution", rec->x_dpi, XPAttrMerge); return( 1 ); } @@ -1655,6 +1661,205 @@ int XpuSetPagePlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ) } +XpuColorspaceList XpuGetColorspaceList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ) +{ + XpuColorspaceList list = NULL; + int rec_count = 1; /* Allocate one more |XpuColorspaceRec| structure + * as terminator */ + char namebuf[256]; /* Temporary name buffer for colorspace names */ + int i; /* Loop counter */ + int nvi; /* Number of visuals */ + Screen *pscreen; /* Print screen */ + XVisualInfo viproto; /* fill in for getting info */ + XVisualInfo *vip; /* retured info */ + + pscreen = XpGetScreenOfContext(pdpy, pcontext); + + nvi = 0; + viproto.screen = XScreenNumberOfScreen(pscreen); + vip = XGetVisualInfo(pdpy, VisualScreenMask, &viproto, &nvi); + if (!vip) + { + fprintf(stderr, "XpuGetColorspaceList: Internal error: vip == NULL\n"); + return NULL; + } + + for( i = 0 ; i < nvi ; i++ ) + { + XVisualInfo *vcurr = vip+i; + char cbuff[64]; + const char *class = NULL; + +#ifdef USE_MOZILLA_TYPES + /* Workaround for the current limitation of the gfx/src/xlibrgb code + * which cannot handle depths > 24bit yet */ + if( vcurr->depth > 24 ) + continue; +#endif /* USE_MOZILLA_TYPES */ + + rec_count++; + list = (XpuColorspaceRec *)realloc(list, sizeof(XpuColorspaceRec)*rec_count); + if( !list ) + return NULL; + + /* ToDO: This needs to be updated for the COLORSPACE X11 extension + * once it is ready and approved by the XOrg arch board. */ + switch (vcurr->class) { + case StaticGray: class = "StaticGray"; break; + case GrayScale: class = "GrayScale"; break; + case StaticColor: class = "StaticColor"; break; + case PseudoColor: class = "PseudoColor"; break; + case TrueColor: class = "TrueColor"; break; + case DirectColor: class = "DirectColor"; break; + default: /* Needed for forward compatibility to the COLORSPACE extension */ + sprintf (cbuff, "unknown_class_%x", vcurr->class); + class = cbuff; + break; + } + + if (vcurr->bits_per_rgb == 8) + { + sprintf(namebuf, "%s/%dbit", class, vcurr->depth); + } + else + { + sprintf(namebuf, "%s/%dbit/%dbpg", class, vcurr->depth, vcurr->bits_per_rgb); + } + list[rec_count-2].name = strdup(namebuf); + list[rec_count-2].visualinfo = *vcurr; + } + + XFree((char *)vip); + + if( list ) + { + /* users: DO NOT COUNT ON THIS DETAIL + * (this is only to make current impl. of XpuGetResolutionList() easier) + * We may remove this implementation detail in a later revision of + * the library! */ + list[rec_count-1].name = NULL; + rec_count--; + } + else + { + rec_count = 0; + } + + *numEntriesPtr = rec_count; + return(list); +} + +void XpuFreeColorspaceList( XpuColorspaceList list ) +{ + if( list ) + { + XpuColorspaceRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->name != NULL ) + { + free((void *)curr->name); + curr++; + } + + free(list); + } +} + +XpuColorspaceRec * +XpuFindColorspaceByName( XpuColorspaceList list, int list_count, const char *name ) +{ + int i; + + for( i = 0 ; i < list_count ; i++ ) + { + XpuColorspaceRec *curr = &list[i]; + if (!strcmp(curr->name, name)) + return curr; + } + + return(NULL); +} + +Bool XpuGetEnableFontDownload( Display *pdpy, XPContext pcontext ) +{ + Bool enableFontDownload; + char *value; + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "xp-listfonts-modes-supported"); + if( !value ) + { + fprintf(stderr, "XpuGetEnableFontDownload: xp-listfonts-modes-supported printer attribute not found.\n"); + return False; + } + + enableFontDownload = (strstr(value, "xp-list-glyph-fonts") != NULL); + XFree(value); + return enableFontDownload; +} + +int XpuSetEnableFontDownload( Display *pdpy, XPContext pcontext, Bool enableFontDownload ) +{ + char *value, + *newvalue; + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "xp-listfonts-modes-supported"); + if( !value ) + { + fprintf(stderr, "XpuSetEnableFontDownload: xp-listfonts-modes-supported printer attribute not found.\n"); + return 0; /* failure */ + } + + /* Set "xp-list-glyph-fonts" */ + if( enableFontDownload ) + { + /* Return success if "xp-list-glyph-fonts" is already set */ + if( strstr(value, "xp-list-glyph-fonts") != NULL ) + { + XFree(value); + return 1; /* success */ + } + + newvalue = malloc(strlen(value) + 33); + if( !newvalue ) + { + XFree(value); + return 0; /* failure */ + } + + sprintf(newvalue, "%s xp-list-glyph-fonts", value); + XpuSetOneAttribute(pdpy, pcontext, XPDocAttr, "*xp-listfonts-modes", newvalue, XPAttrMerge); + + free(newvalue); + XFree(value); + return 1; /* success */ + } + else + { + char *s, /* copy string "source" */ + *d; /* copy string "destination" */ + + /* Return success if "xp-list-glyph-fonts" not set */ + d = strstr(value, "xp-list-glyph-fonts"); + if( d == NULL ) + { + XFree(value); + return 1; /* success */ + } + + /* strip "xp-list-glyph-fonts" from |value| */ + s = d+19/*strlen("xp-list-glyph-fonts")*/; + while( (*d++ = *s++) != '\0' ) + ; + + XpuSetOneAttribute(pdpy, pcontext, XPDocAttr, "*xp-listfonts-modes", value, XPAttrMerge); + + XFree(value); + return 1; /* success */ + } +} + /* Return flags to indicate which attributes are supported and which not... */ static XpuSupportedFlags XpuGetSupportedAttributes( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name ) @@ -1687,6 +1892,7 @@ XpuSupportedFlags XpuGetSupportedAttributes( Display *pdpy, XPContext pcontext, else if( !strcmp(s, "default-input-tray") ) flags |= XPUATTRIBUTESUPPORTED_DEFAULT_INPUT_TRAY; else if( !strcmp(s, "default-medium") ) flags |= XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM; else if( !strcmp(s, "plex") ) flags |= XPUATTRIBUTESUPPORTED_PLEX; + else if( !strcmp(s, "xp-listfonts-modes") ) flags |= XPUATTRIBUTESUPPORTED_LISTFONTS_MODES; } XpuDisposeEnumerateXpAttributeValue(&tok_lasts); @@ -1711,4 +1917,193 @@ XpuSupportedFlags XpuGetSupportedPageAttributes(Display *pdpy, XPContext pcontex return XpuGetSupportedAttributes(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported"); } +/* Encode string for usage in a Xrm resource database as + * defined in X(7): [...] To allow a Value to begin + * with whitespace, the two-character sequence ``\space'' + * (backslash followed by space) is recognized and replaced by + * a space character, and the two-character sequence ``\tab'' + * (backslash followed by horizontal tab) is recognized and + * replaced by a horizontal tab character. To allow a Value to + * contain embedded newline characters, the two-character + * sequence ``\n'' is recognized and replaced by a newline + * character. To allow a Value to be broken across multiple + * lines in a text file, the two-character sequence ``\new- + * line'' (backslash followed by newline) is recognized and + * removed from the value. To allow a Value to contain arbi- + * trary character codes, the four-character sequence ``\nnn'', + * where each n is a digit character in the range of + * ``0''-``7'', is recognized and replaced with a single byte + * that contains the octal value specified by the sequence. + * Finally, the two-character sequence ``\\'' is recognized and + * replaced with a single backslash. + */ +char *XpuResourceEncode( const char *s ) +{ + size_t slen; + char *res; + char *d; + int i, + c; + + slen = strlen(s); + res = malloc(slen*4+1); + if (!res) + return NULL; + + d = res; + i = slen; + while (i--) { + c = *s++; + if (c == '\n') { + if (i) { + *d++ = '\\'; + *d++ = 'n'; + *d++ = '\\'; + *d++ = '\n'; + } + else { + *d++ = '\\'; + *d++ = 'n'; + } + } else if (c == '\\') { + *d++ = '\\'; + *d++ = '\\'; + } + else if ((c < ' ' && c != '\t') || + ((unsigned char)c >= 0x7F && (unsigned char)c < 0xA0)) { + sprintf(d, "\\%03o", (unsigned char)c); + d += 4; + } + else { + *d++ = c; + } + } + + *d = '\0'; + + return res; +} + +#ifdef XXXJULIEN_NOTNOW +char *XpuResourceDecode( const char *str ) +{ +} +#endif /* XXXJULIEN_NOTNOW */ + +void XpuResourceFreeString( char *s ) +{ + free(s); +} + +const char *XpuXmbToCompoundText(Display *dpy, const char *xmbtext) +{ + XTextProperty xtp; + int xcr; + char *xtl[2]; + char *ct; + + if (strlen(xmbtext) == 0) + return strdup(xmbtext); + + memset(&xtp, 0, sizeof(xtp)); + xtl[0] = (char *)xmbtext; + xtl[1] = NULL; + + xcr = XmbTextListToTextProperty(dpy, xtl, 1, XCompoundTextStyle, &xtp); + + if (xcr == XNoMemory || xcr == XLocaleNotSupported) + { + fprintf(stderr, "XpuXmbToCompoundText: XmbTextListToTextProperty failure.\n"); + return strdup(xmbtext); + } + + /* Did conversion succeed (some unconvertible characters + * are not a problem) ? */ + if ( !((xcr == Success) || (xcr > 0)) || + (xtp.value == NULL)) + { + fprintf(stderr, "XpuXmbToCompoundText: XmbTextListToTextProperty failure 2.\n"); + return strdup(xmbtext); + } + + ct = malloc(xtp.nitems+1); + if (!ct) + { + XFree(xtp.value); + return NULL; + } + memcpy(ct, xtp.value, xtp.nitems); + ct[xtp.nitems] = '\0'; + + XFree(xtp.value); + + return ct; +} + +void XpuFreeCompundTextString( const char *s ) +{ + free((void *)s); +} + +const char *XpuCompoundTextToXmb(Display *dpy, const char *ct) +{ + XTextProperty xtp; + int xcr; + char **xtl = NULL; + int xtl_count = 0; + char *xmb; + int xmb_len = 0; + int i; + + if (strlen(ct) == 0) + return strdup(ct); + + xtp.value = (unsigned char *)ct; + xtp.nitems = strlen(ct); + xtp.encoding = XInternAtom(dpy, "COMPOUND_TEXT", False); + xtp.format = 8; + + xcr = XmbTextPropertyToTextList(dpy, &xtp, &xtl, &xtl_count); + + if (xcr == XNoMemory || xcr == XLocaleNotSupported) + { + fprintf(stderr, "XpuCompoundTextToXmb: XmbTextPropertyToTextList failure 1.\n"); + return strdup(ct); + } + + /* Did conversion succeed (some unconvertible characters + * are not a problem) ? */ + if ( !((xcr == Success) || (xcr > 0)) || + (xtl == NULL)) + { + fprintf(stderr, "XpuCompoundTextToXmb: XmbTextPropertyToTextList failure 2.\n"); + return strdup(ct); + } + + for (i = 0; i < xtl_count; i++) + { + xmb_len += strlen(xtl[i]); + } + xmb = malloc (xmb_len + 1); + if (!xmb) + { + XFreeStringList(xtl); + return NULL; + } + xmb[0] = '\0'; /* Catch zero-length case */ + for (i = 0; i < xtl_count; i++) + { + strcat(xmb, xtl[i]); + } + + XFreeStringList(xtl); + + return xmb; +} + +void XpuFreeXmbString( const char *s ) +{ + free((void *)s); +} + /* EOF. */ diff --git a/gfx/src/xprintutil/xprintutil.h b/gfx/src/xprintutil/xprintutil.h index af3962ff219c..c962c9e471cd 100644 --- a/gfx/src/xprintutil/xprintutil.h +++ b/gfx/src/xprintutil/xprintutil.h @@ -93,11 +93,12 @@ typedef struct { /* * Struct for XpuGetResolutionList(), XpuFreeResolutionList(), * XpuGetResolution(), XpuSetPageResolution(), XpuSetDocResolution(), - * XpuFindResolution() + * XpuFindResolutionByName() */ typedef struct { - long dpi; - /* ToDo: Support for Xdpi != Ydpi */ + const char *name; + long x_dpi; + long y_dpi; } XpuResolutionRec, *XpuResolutionList; /* @@ -117,6 +118,14 @@ typedef struct { const char *plex; } XpuPlexRec, *XpuPlexList; +/* + * Struct for XpuGetColorspaceList(), XpuFreeColorspaceList() + */ +typedef struct +{ + const char *name; + XVisualInfo visualinfo; +} XpuColorspaceRec, *XpuColorspaceList; /* XPUATTRIBUTESUPPORTED_*: * Flags which indicate whether it is allowed to set/change a specific attribute @@ -134,6 +143,7 @@ typedef long XpuSupportedFlags; #define XPUATTRIBUTESUPPORTED_DEFAULT_INPUT_TRAY (1L<<7) #define XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM (1L<<8) #define XPUATTRIBUTESUPPORTED_PLEX (1L<<9) +#define XPUATTRIBUTESUPPORTED_LISTFONTS_MODES (1L<<10) /* prototypes */ _XFUNCPROTOBEGIN @@ -183,10 +193,10 @@ XpuFindMediumSourceSizeByName( XpuMediumSourceSizeList mlist, int mlist_count, /* Get/Set resolution */ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); void XpuFreeResolutionList( XpuResolutionList list ); -Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi ); +Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *x_dpi, long *y_dpi ); Bool XpuSetPageResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec * ); Bool XpuSetDocResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec * ); -XpuResolutionRec *XpuFindResolution( XpuResolutionList list, int list_count, long min_dpi, long max_dpi ); +XpuResolutionRec *XpuFindResolutionByName( XpuResolutionList list, int list_count, const char *resolution_name); /* Get/Set orientation */ XpuOrientationList XpuGetOrientationList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); @@ -203,6 +213,15 @@ XpuPlexRec *XpuFindPlexByName( XpuPlexList list, int list_count, const char *ple int XpuSetDocPlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ); int XpuSetPagePlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ); +/* Set/get usage of fonts */ +Bool XpuGetEnableFontDownload( Display *pdpy, XPContext pcontext ); +int XpuSetEnableFontDownload( Display *pdpy, XPContext pcontext, Bool enableFontDownload ); + +/* Get per-printer colorspace information */ +XpuColorspaceList XpuGetColorspaceList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); +void XpuFreeColorspaceList( XpuColorspaceList list ); +XpuColorspaceRec *XpuFindColorspaceByName( XpuColorspaceList list, int list_count, const char *colorspace ); + /* Start job to printer (spooler) or file */ void XpuStartJobToSpooler(Display *pdpy); void *XpuStartJobToFile( Display *pdpy, XPContext pcontext, const char *filename ); @@ -213,6 +232,18 @@ XpuSupportedFlags XpuGetSupportedJobAttributes(Display *pdpy, XPContext pcontext XpuSupportedFlags XpuGetSupportedDocAttributes(Display *pdpy, XPContext pcontext); XpuSupportedFlags XpuGetSupportedPageAttributes(Display *pdpy, XPContext pcontext); +/* Encode/decode resource strings */ +char *XpuResourceEncode( const char *str ); +char *XpuResourceDecode( const char *str ); +void XpuResourceFreeString( char *s ); + +/* COMPOUND_TEXT <----> local encoding string converters */ +const char *XpuXmbToCompoundText(Display *dpy, const char *xmbtext); +void XpuFreeCompundTextString( const char *s ); +const char *XpuCompoundTextToXmb(Display *dpy, const char *ct); +void XpuFreeXmbString( const char *s ); + + _XFUNCPROTOEND #define XpuGetJobAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPJobAttr ) diff --git a/layout/html/base/src/printing.properties b/layout/html/base/src/printing.properties index c24f9c068df4..2afcd2170350 100644 --- a/layout/html/base/src/printing.properties +++ b/layout/html/base/src/printing.properties @@ -106,6 +106,7 @@ NS_ERROR_GFX_PRINTER_PLEX_NOT_SUPPORTED=There was a problem printing because the NS_ERROR_GFX_PRINTER_DOC_IS_BUSY=The browser cannot print the document while it is being loaded. NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED=Printing is not implemented. NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE=The requested print module cannot be loaded. +NS_ERROR_GFX_PRINTER_RESOLUTION_NOT_SUPPORTED=There was a problem printing because the resolution/quality mode you specified is not supported by your printer. # No printers available noprinter=No printers available. diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index 63865e31ea59..f35d60444853 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -2257,6 +2257,7 @@ nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrinting) NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY) NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED) NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE) + NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_RESOLUTION_NOT_SUPPORTED) default: NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE) diff --git a/toolkit/components/printing/content/printdialog.js b/toolkit/components/printing/content/printdialog.js index 2b5d117e2563..547489639516 100644 --- a/toolkit/components/printing/content/printdialog.js +++ b/toolkit/components/printing/content/printdialog.js @@ -45,6 +45,7 @@ var printOptions = null; var gOriginalNumCopies = 1; var paramBlock; +var gPrefs = null; var gPrintSettings = null; var gWebBrowserPrint = null; var default_file = "mozilla.ps"; @@ -58,6 +59,7 @@ function initDialog() dialog = new Object; dialog.propertiesButton = document.getElementById("properties"); + dialog.descText = document.getElementById("descText"); dialog.destGroup = document.getElementById("destGroup"); dialog.fileRadio = document.getElementById("fileRadio"); @@ -132,6 +134,20 @@ function doEnablePrintToFile(value) } } +//--------------------------------------------------- +function getPrinterDescription(printerName) +{ + var s = ""; + + try { + /* This may not work with non-ASCII test (see bug 235763 comment #16) */ + s = gPrefs.getCharPref("print.printer_" + printerName + ".printer_description") + } catch(e) { + } + + return s; +} + //--------------------------------------------------- function listElement(aListElement) { @@ -144,13 +160,16 @@ listElement.prototype = function () { // remove the menupopup node child of the menulist. - this.listElement.removeChild(this.listElement.firstChild); + var popup = this.listElement.firstChild; + if (popup) { + this.listElement.removeChild(popup); + } }, appendPrinterNames: function (aDataObject) { - var popupNode = document.createElement("menupopup"); + var list = document.getElementById("printerList"); var strDefaultPrinterName = ""; var printerName; @@ -161,10 +180,8 @@ listElement.prototype = var printerNameStr = printerName.toString(); if (strDefaultPrinterName == "") strDefaultPrinterName = printerNameStr; - var itemNode = document.createElement("menuitem"); - itemNode.setAttribute("value", printerNameStr); - itemNode.setAttribute("label", printerNameStr); - popupNode.appendChild(itemNode); + + list.appendItem(printerNameStr, printerNameStr, getPrinterDescription(printerNameStr)); } if (strDefaultPrinterName != "") { this.listElement.removeAttribute("disabled"); @@ -184,7 +201,6 @@ listElement.prototype = doEnablePrintToFile(false); } - this.listElement.appendChild(popupNode); return strDefaultPrinterName; } }; @@ -211,6 +227,8 @@ function setPrinterDefaultsForSelectedPrinter() { gPrintSettings.printerName = dialog.printerList.value; + dialog.descText.value = getPrinterDescription(gPrintSettings.printerName); + // First get any defaults from the printer printService.initPrintSettingsFromPrinter(gPrintSettings.printerName, gPrintSettings); @@ -265,6 +283,8 @@ function loadDialog() var print_tofile = ""; try { + gPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); + printService = Components.classes["@mozilla.org/gfx/printsettings-service;1"]; if (printService) { printService = printService.getService(); @@ -385,7 +405,7 @@ function onLoad() function onAccept() { - if (gPrintSettings) { + if (gPrintSettings != null) { var print_howToEnableUI = gPrintSetInterface.kFrameEnableNone; var stringBundle = srGetStrBundle("chrome://global/locale/printing.properties"); var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] @@ -459,14 +479,23 @@ function onAccept() } } - if (printService) { + var saveToPrefs = false; + + saveToPrefs = gPrefs.getBoolPref("print.save_print_settings"); + + if (saveToPrefs && printService != null) { var flags = gPrintSetInterface.kInitSavePaperSizeType | gPrintSetInterface.kInitSavePaperSizeUnit | gPrintSetInterface.kInitSavePaperWidth | gPrintSetInterface.kInitSavePaperHeight | gPrintSetInterface.kInitSavePaperName | + gPrintSetInterface.kInitSaveColorSpace | gPrintSetInterface.kInitSaveInColor | - gPrintSetInterface.kInitSavePrintCommand; + gPrintSetInterface.kInitSaveResolutionName | + gPrintSetInterface.kInitSaveDownloadFonts | + gPrintSetInterface.kInitSavePrintCommand | + gPrintSetInterface.kInitSaveShrinkToFit | + gPrintSetInterface.kInitSaveScaling; printService.savePrintSettingsToPrefs(gPrintSettings, true, flags); } diff --git a/toolkit/components/printing/content/printdialog.xul b/toolkit/components/printing/content/printdialog.xul index c492ad542aca..4fc42a17258d 100644 --- a/toolkit/components/printing/content/printdialog.xul +++ b/toolkit/components/printing/content/printdialog.xul @@ -68,20 +68,15 @@ - - - - - + - - - +