Bug 198515 - patch by Roland.Mainz r=peterl/leon.sha sr=bz

This commit is contained in:
bsmedberg%covad.net 2003-07-23 14:10:12 +00:00
parent 3dede7b5c9
commit d26f4f42ba
14 changed files with 329 additions and 37 deletions

View File

@ -20,7 +20,9 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Leon Sha <leon.sha@sun.com>
* Boris Zbarsky <bzbarsky@mit.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -823,6 +825,57 @@ public:
nscoord aXImageStart, nscoord aYImageStart,
const nsRect * aTargetRect) = 0;
/**
* Render the provided postscript fragment to the current rendering
* surface.
*
* This is usually implemented via including a PostScript data fragment
* into the output of a print device which supports embedding
* of PostScript code fragments (this may be a PostScript printer, a PCL
* printer which supports embedded PostScript fragments in the PCL stream
* etc. etc.) on the drawing surface this nsIRenderingContext is currently
* rendering on (e.g. the embedded PostScript code "draws" on this surface
* as if the matching nsIRenderingContext methods would have been called).
*
* The PostScript code fragment MUST NOT contain any code which begins a
* new page.
*
* The PostScript code fragment can only contain PostScript Level 1 and
* Level 2 code, PostScript Level 3 is not allowed yet.
*
* This must be called after nsIDeviceContext::BeginPage() and
* before nsIDeviceContext::EndPage().
*
* There is no gurantee that the PostScript data are included into the
* output and it may happen that the PostScript code fragment passed via
* RenderPostScriptDataFragment() may be included multiple times into the
* output (for example if PS data come from a plugin which is split over
* multiple pages the data may be embedded for each page and the matching
* visible area is clipped).
*
* The PostScript code will operate in its own context and can use the
* whole drawable area which is defined by the caller of this method via
* establishing a clipping area to set the X,Y and width/height of the
* output area (e.g. the output created by the passed PostScript code
* fragment is positioned (X, Y pos) and limited (width, height) via
* defining a clipping area before calling this method).
*
* The initial PostScript coordinate system is aligned with the top and
* left edges of the clip rect, with the positive X axis along the top
* edge and the positive Y axis along the left edge.
*
* Note that nsIRenderingContext and PostScript have the vertical axis
* NOT flipped - "0,0" means "left, top" edge for both
* nsIRenderingContext and the PostScript fragment code (this is different
* from the PostScript "default" where "0,0" means "left, bottom" edge -
* the nsIRenderingContext implementation ensures that both X and Y axis
* for PostScript are the same as used in the nsIRenderingContext).
*
* @param aData - PostScript fragment data
* @param aLength - Length of PostScript fragment data
* @return error status
*/
NS_IMETHOD RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen) = 0;
};
//modifiers for text rendering

View File

@ -42,9 +42,11 @@
#define SET_PRINTER_FEATURES_VIA_PREFS 1
#define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
#define FORCE_PR_LOG /* Allow logging in the release build */
#define PR_LOGGING 1
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "prlog.h"
#include "plstr.h"
#include "nsDeviceContextSpecG.h"

View File

@ -136,6 +136,7 @@ public:
NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);
NS_IMETHOD DrawTile(imgIContainer *aImage, nscoord aXOffset, nscoord aYOffset, const nsRect * aTargetRect);
NS_IMETHOD RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen);
protected:
virtual ~nsRenderingContextImpl();

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Leon Sha <leon.sha@sun.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
@ -1419,7 +1420,16 @@ const nsFont *font;
}
}
NS_IMETHODIMP nsRenderingContextPS::RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen)
{
nsPostScriptObj *postscriptobj = GetPostScriptObj();
fprintf(postscriptobj->mPrintSetup->tmpBody, "1 -1 scale\n");
fprintf(postscriptobj->mPrintSetup->tmpBody, "0 %d translate\n", -(postscriptobj->mPrintSetup->height));
fwrite(aData, aDatalen, 1, postscriptobj->mPrintSetup->tmpBody);
return NS_OK;
}
#ifdef NOTNOW
HPEN nsRenderingContextPS :: SetupSolidPen(void)

View File

@ -267,6 +267,8 @@ public:
PRInt32* aFontID = nsnull);
#endif /* MOZ_MATHML */
NS_IMETHOD RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen);
private:
nsresult CommonInit(void);
void PushClipState(void);

View File

@ -925,3 +925,11 @@ nsRenderingContextImpl::FlushRect(nscoord aX, nscoord aY, nscoord aWidth, nscoor
{
return NS_OK;
}
NS_IMETHODIMP
nsRenderingContextImpl::RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -42,8 +42,9 @@
#define SET_PRINTER_FEATURES_VIA_PREFS 1
#define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
#define FORCE_PR_LOG /* Allow logging in the release build */
#define PR_LOGGING 1
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "prlog.h"
#include "nsDeviceContextSpecXlib.h"

View File

@ -38,8 +38,9 @@
*
* ***** END LICENSE BLOCK ***** */
#define FORCE_PR_LOG /* Allow logging in the release build */
#define PR_LOGGING 1
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "prlog.h"
#include "nsDeviceContextXP.h"

View File

@ -228,3 +228,13 @@ nsRenderingContextXp::CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSrcX
NS_NOTREACHED("nsRenderingContextXp::CopyOffScreenBits() not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsRenderingContextXp::RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen)
{
PR_LOG(RenderingContextXpLM, PR_LOG_DEBUG, ("nsRenderingContextXp::RenderPostScriptDataFragment()\n"));
return mPrintContext->RenderPostScriptDataFragment(aData, aDatalen);
}

View File

@ -74,6 +74,8 @@ class nsRenderingContextXp : public nsRenderingContextXlib
NS_IMETHOD CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds, PRUint32 aCopyFlags);
NS_IMETHOD RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen);
protected:
nsXPrintContext *mPrintContext; /* identical to |mRenderingSurface|

View File

@ -21,7 +21,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
*
* Leon Sha <leon.sha@sun.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -47,8 +47,9 @@
#include <errno.h>
#include <string.h> /* for strerror & memset */
#define FORCE_PR_LOG /* Allow logging in the release build */
#define PR_LOGGING 1
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "prlog.h"
#include "imgScaler.h"
@ -1298,3 +1299,53 @@ NS_IMETHODIMP nsXPrintContext::GetPrintResolution(int &aPrintResolution)
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsXPrintContext::RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen)
{
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG,
("nsXPrintContext::RenderPostScriptDataFragment(aData, aDatalen=%d)\n", aDatalen));
const char *embedded_formats_supported = XpGetOneAttribute(mPDisplay, mPContext,XPPrinterAttr, "xp-embedded-formats-supported");
/* Check whether "PostScript Level 2" is supported as embedding format
* (The content of the "xp-embedded-formats-supported" attribute needs
* to be searched in a case-insensitive way since the model-configs
* may use the same word with multiple variants of case
* (e.g. "PostScript" vs. "Postscript" or "PCL" vs. "Pcl" etc.")
* To avoid problems we simply use |PL_strcasestr()| (case-insensitive
* strstr()) instead of |strstr()| here...)
*/
if( embedded_formats_supported == NULL )
{
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::RenderPostScriptDataFragment(): Embedding data not supported for this DDX/Printer\n"));
return NS_ERROR_FAILURE;
}
if( PL_strcasestr(embedded_formats_supported, "PostScript 2") == NULL )
{
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG,
("nsXPrintContext::RenderPostScriptDataFragment(): Embedding data not supported for this DDX/Printer "
"(supported embedding formats are '%s')\n", embedded_formats_supported));
XFree((void *)embedded_formats_supported);
return NS_ERROR_FAILURE;
}
/* Note that the embedded PostScript code uses the same resolution and
* coordinate space as currently be used by the DDX (if you do not
* want that simply reset it yourself :) */
const char *type = "PostScript 2"; /* Format of embedded data
* (older PS DDX may be picky, fixed via
* http://xprint.mozdev.org/bugs/show_bug.cgi?id=4023)
*/
const char *option = ""; /* PostScript DDX does not support any options yet
* (in general |BadValue| will be returned for not
* 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 *)aData, aDatalen, (char *)type, (char *)option);
XFree((void *)embedded_formats_supported);
return NS_OK;
}

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Leon Sha <leon.sha@sun.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
@ -73,10 +74,10 @@ public:
NS_IMETHOD Init(nsDeviceContextXp *dc, nsIDeviceContextSpecXp *aSpec);
NS_IMETHOD BeginPage();
NS_IMETHOD EndPage();
NS_IMETHOD RenderPostScriptDataFragment(const unsigned char *aData, unsigned long aDatalen);
NS_IMETHOD BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage);
NS_IMETHOD EndDocument();
NS_IMETHOD AbortDocument();
int GetHeight() { return mHeight; }
int GetWidth() { return mWidth; }

View File

@ -22,6 +22,8 @@
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Jacek Piskozub <piskozub@iopan.gda.pl>
* Leon Sha <leon.sha@sun.com>
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -142,6 +144,13 @@
#include "nsIAccessibilityService.h"
#endif
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "prlog.h"
#include <errno.h>
#include "nsContentCID.h"
static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
@ -155,6 +164,10 @@ static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
#include <winuser.h>
#endif
#ifdef PR_LOGGING
static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
#endif /* PR_LOGGING */
// special class for handeling DOM context menu events
// because for some reason it starves other mouse events if implemented on the same class
class nsPluginDOMContextMenuListener : public nsIDOMContextMenuListener,
@ -1665,22 +1678,85 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
window.window = &port;
npprint.print.embedPrint.platformPrint = (void*)window.window;
npprint.print.embedPrint.window = window;
// send off print info to plugin
rv = pi->Print(&npprint);
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
// UNIX does things completely differently
PRUnichar *printfile = nsnull;
if (printSettings) {
printSettings->GetToFileName(&printfile);
}
if (!printfile)
return NS_OK; // XXX what to do on UNIX when we don't have a PS file????
/* UNIX does things completely differently:
* We call the plugin and it sends generated PostScript data into a
* file handle we provide. If the plugin returns with success we embed
* this PostScript code fragment into the PostScript job we send to the
* printer.
*/
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("nsObjectFrame::Paint() start for X11 platforms\n"));
FILE *plugintmpfile = tmpfile();
if( !plugintmpfile ) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: could not open tmp. file, errno=%d\n", errno));
return NS_ERROR_FAILURE;
}
/* Send off print info to plugin */
NPPrintCallbackStruct npPrintInfo;
npPrintInfo.type = NP_PRINT;
npPrintInfo.fp = (FILE*)printfile;
npprint.print.embedPrint.platformPrint = (void*) &npPrintInfo;
npPrintInfo.fp = plugintmpfile;
npprint.print.embedPrint.platformPrint = (void *)&npPrintInfo;
npprint.print.embedPrint.window = window;
rv = pi->Print(&npprint);
if (NS_FAILED(rv)) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: plugin returned failure %lx\n", (long)rv));
fclose(plugintmpfile);
return rv;
}
unsigned char *pluginbuffer;
long fileLength;
/* Get file size */
fseek(plugintmpfile, 0, SEEK_END);
fileLength = ftell(plugintmpfile);
/* Safeguard against bogus values
* (make sure we clamp the size to a reasonable value (say... 128 MB)) */
if( fileLength <= 0 || fileLength > (128 * 1024 * 1024) ) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: file size %ld too large\n", fileLength));
fclose(plugintmpfile);
return NS_ERROR_FAILURE;
}
pluginbuffer = new unsigned char[fileLength+1];
if (!pluginbuffer) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: no buffer memory for %ld bytes\n", fileLength+1));
fclose(plugintmpfile);
return NS_ERROR_OUT_OF_MEMORY;
}
/* Read data into temp. buffer */
long numBytesRead = 0;
fseek(plugintmpfile, 0, SEEK_SET);
numBytesRead = fread(pluginbuffer, 1, fileLength, plugintmpfile);
if( numBytesRead == fileLength ) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("sending %ld bytes of PostScript data to printer\n", numBytesRead));
/* Send data to printer */
aRenderingContext.RenderPostScriptDataFragment(pluginbuffer, numBytesRead);
}
else
{
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
("error: bytes read in buffer (%ld) does not match file length (%ld)\n",
numBytesRead, fileLength));
}
fclose(plugintmpfile);
delete [] pluginbuffer;
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("plugin printing done, return code is %lx\n", (long)rv));
#else // Windows and non-UNIX, non-Mac(Classic) cases
// we need the native printer device context to pass to plugin
// On Windows, this will be the HDC
PRUint32 pDC = 0;
@ -1690,13 +1766,12 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
return NS_OK; // no dc implemented so quit
npprint.print.embedPrint.platformPrint = (void*)pDC;
#endif
npprint.print.embedPrint.window = window;
// send off print info to plugin
rv = pi->Print(&npprint);
#endif
#if defined(XP_MAC) && !TARGET_CARBON
// Clean-up on Mac
::SetOrigin(0,0);

View File

@ -22,6 +22,8 @@
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Jacek Piskozub <piskozub@iopan.gda.pl>
* Leon Sha <leon.sha@sun.com>
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -142,6 +144,13 @@
#include "nsIAccessibilityService.h"
#endif
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "prlog.h"
#include <errno.h>
#include "nsContentCID.h"
static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
@ -155,6 +164,10 @@ static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
#include <winuser.h>
#endif
#ifdef PR_LOGGING
static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
#endif /* PR_LOGGING */
// special class for handeling DOM context menu events
// because for some reason it starves other mouse events if implemented on the same class
class nsPluginDOMContextMenuListener : public nsIDOMContextMenuListener,
@ -1665,22 +1678,85 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
window.window = &port;
npprint.print.embedPrint.platformPrint = (void*)window.window;
npprint.print.embedPrint.window = window;
// send off print info to plugin
rv = pi->Print(&npprint);
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
// UNIX does things completely differently
PRUnichar *printfile = nsnull;
if (printSettings) {
printSettings->GetToFileName(&printfile);
}
if (!printfile)
return NS_OK; // XXX what to do on UNIX when we don't have a PS file????
/* UNIX does things completely differently:
* We call the plugin and it sends generated PostScript data into a
* file handle we provide. If the plugin returns with success we embed
* this PostScript code fragment into the PostScript job we send to the
* printer.
*/
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("nsObjectFrame::Paint() start for X11 platforms\n"));
FILE *plugintmpfile = tmpfile();
if( !plugintmpfile ) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: could not open tmp. file, errno=%d\n", errno));
return NS_ERROR_FAILURE;
}
/* Send off print info to plugin */
NPPrintCallbackStruct npPrintInfo;
npPrintInfo.type = NP_PRINT;
npPrintInfo.fp = (FILE*)printfile;
npprint.print.embedPrint.platformPrint = (void*) &npPrintInfo;
npPrintInfo.fp = plugintmpfile;
npprint.print.embedPrint.platformPrint = (void *)&npPrintInfo;
npprint.print.embedPrint.window = window;
rv = pi->Print(&npprint);
if (NS_FAILED(rv)) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: plugin returned failure %lx\n", (long)rv));
fclose(plugintmpfile);
return rv;
}
unsigned char *pluginbuffer;
long fileLength;
/* Get file size */
fseek(plugintmpfile, 0, SEEK_END);
fileLength = ftell(plugintmpfile);
/* Safeguard against bogus values
* (make sure we clamp the size to a reasonable value (say... 128 MB)) */
if( fileLength <= 0 || fileLength > (128 * 1024 * 1024) ) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: file size %ld too large\n", fileLength));
fclose(plugintmpfile);
return NS_ERROR_FAILURE;
}
pluginbuffer = new unsigned char[fileLength+1];
if (!pluginbuffer) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("error: no buffer memory for %ld bytes\n", fileLength+1));
fclose(plugintmpfile);
return NS_ERROR_OUT_OF_MEMORY;
}
/* Read data into temp. buffer */
long numBytesRead = 0;
fseek(plugintmpfile, 0, SEEK_SET);
numBytesRead = fread(pluginbuffer, 1, fileLength, plugintmpfile);
if( numBytesRead == fileLength ) {
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("sending %ld bytes of PostScript data to printer\n", numBytesRead));
/* Send data to printer */
aRenderingContext.RenderPostScriptDataFragment(pluginbuffer, numBytesRead);
}
else
{
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
("error: bytes read in buffer (%ld) does not match file length (%ld)\n",
numBytesRead, fileLength));
}
fclose(plugintmpfile);
delete [] pluginbuffer;
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("plugin printing done, return code is %lx\n", (long)rv));
#else // Windows and non-UNIX, non-Mac(Classic) cases
// we need the native printer device context to pass to plugin
// On Windows, this will be the HDC
PRUint32 pDC = 0;
@ -1690,13 +1766,12 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
return NS_OK; // no dc implemented so quit
npprint.print.embedPrint.platformPrint = (void*)pDC;
#endif
npprint.print.embedPrint.window = window;
// send off print info to plugin
rv = pi->Print(&npprint);
#endif
#if defined(XP_MAC) && !TARGET_CARBON
// Clean-up on Mac
::SetOrigin(0,0);