Changing mac printing to use print manager instead of cups. bug 367433. r=vlad/cbarrett

git-svn-id: svn://10.0.0.236/trunk@219035 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pavlov%pavlov.net
2007-01-27 04:06:59 +00:00
parent 45a91c751b
commit 4169248ca1
19 changed files with 282 additions and 178 deletions

View File

@@ -226,7 +226,7 @@ endif
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
ifdef BUILD_STATIC_LIBS
LIBS += -framework QuickTime -framework IOKit -lcups
LIBS += -framework QuickTime -framework IOKit
ifdef USE_PREBINDING
BIN_FLAGS += -Wl,-headerpad -Wl,5a0c
endif

View File

@@ -62,6 +62,8 @@
#include <pango/pango-fontmap.h>
#endif /* GTK2 */
#include "gfxImageSurface.h"
#ifdef MOZ_ENABLE_GTK2
#include "nsSystemFontsGTK2.h"
#include "gfxPDFSurface.h"
@@ -78,7 +80,7 @@ static nsSystemFontsWin *gSystemFonts = nsnull;
static nsSystemFontsBeOS *gSystemFonts = nsnull;
#elif XP_MACOSX
#include "nsSystemFontsMac.h"
#include "gfxQuartzPDFSurface.h"
#include "gfxQuartzSurface.h"
static nsSystemFontsMac *gSystemFonts = nsnull;
#else
#error Need to declare gSystemFonts!
@@ -229,15 +231,6 @@ nsThebesDeviceContext::Init(nsNativeWidget aWidget)
SetDPI(prefVal);
#ifdef XP_MACOSX
if (mPrinter) {
gfxSize size = ((gfxQuartzPDFSurface*)(mPrintingSurface.get()))->GetSize();
mWidth = NSFloatPointsToTwips(size.width);
mHeight = NSFloatPointsToTwips(size.height);
}
mDepth = 24;
#endif
#ifdef MOZ_ENABLE_GTK2
if (getenv ("MOZ_X_SYNC")) {
@@ -246,28 +239,10 @@ nsThebesDeviceContext::Init(nsNativeWidget aWidget)
XSetErrorHandler(x11_error_handler);
}
// XXX
if (mPrinter) {
// XXX this should use a gfxAPrintingSurface or somesuch cast.
// currently PDF and PS are identical here
gfxSize size = ((gfxPSSurface*)(mPrintingSurface.get()))->GetSize();
mWidth = NSFloatPointsToTwips(size.width);
mHeight = NSFloatPointsToTwips(size.height);
printf("%f %f\n", size.width, size.height);
printf("%d %d\n", (PRInt32)mWidth, (PRInt32)mHeight);
}
// XXX
mDepth = 24;
#endif
#ifdef XP_WIN
HDC dc = GetHDC() ? GetHDC() : GetDC((HWND)mWidget);
mWidth = ::GetDeviceCaps(dc, HORZRES);
mHeight = ::GetDeviceCaps(dc, VERTRES);
mDepth = (PRUint32)::GetDeviceCaps(dc, BITSPIXEL);
if (dc != (HDC)GetHDC())
ReleaseDC((HWND)mWidget, dc);
#endif
mDepth = 24;
mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
@@ -339,6 +314,9 @@ nsThebesDeviceContext::CreateRenderingContext(nsIRenderingContext *&aContext)
nsCOMPtr<nsIRenderingContext> pContext;
rv = CreateRenderingContextInstance(*getter_AddRefs(pContext));
if (NS_SUCCEEDED(rv)) {
#ifdef XP_MACOSX
mDeviceContextSpec->GetSurfaceForPrinter(getter_AddRefs(mPrintingSurface));
#endif
if (mPrintingSurface)
rv = pContext->Init(this, mPrintingSurface);
else
@@ -451,13 +429,8 @@ nsThebesDeviceContext::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHei
{
if (mPrinter) {
// we have a printer device
#if defined(MOZ_ENABLE_GTK2) || defined(XP_MACOSX)
aWidth = mWidth;
aHeight = mHeight;
#else
aWidth = NSToIntRound(mWidth * mDevUnitsToAppUnits);
aHeight = NSToIntRound(mHeight * mDevUnitsToAppUnits);
#endif
} else {
nsRect area;
ComputeFullAreaUsingScreen(&area);
@@ -475,13 +448,8 @@ nsThebesDeviceContext::GetRect(nsRect &aRect)
// we have a printer device
aRect.x = 0;
aRect.y = 0;
#if defined(MOZ_ENABLE_GTK2) || defined(XP_MACOSX)
aRect.width = NSToIntRound(mWidth);
aRect.height = NSToIntRound(mHeight);
#else
aRect.width = NSToIntRound(mWidth * mDevUnitsToAppUnits);
aRect.height = NSToIntRound(mHeight * mDevUnitsToAppUnits);
#endif
} else
ComputeFullAreaUsingScreen ( &aRect );
@@ -495,13 +463,8 @@ nsThebesDeviceContext::GetClientRect(nsRect &aRect)
// we have a printer device
aRect.x = 0;
aRect.y = 0;
#if defined(MOZ_ENABLE_GTK2) || defined(XP_MACOSX)
aRect.width = NSToIntRound(mWidth);
aRect.height = NSToIntRound(mHeight);
#else
aRect.width = NSToIntRound(mWidth * mDevUnitsToAppUnits);
aRect.height = NSToIntRound(mHeight * mDevUnitsToAppUnits);
#endif
}
else
ComputeClientRectUsingScreen(&aRect);
@@ -555,6 +518,8 @@ nsThebesDeviceContext::GetDeviceContextFor(nsIDeviceContextSpec *aDevice,
newDevCon->SetAppUnitsToDevUnits((a2d / t2d) * newDevCon->mTwipsToPixels);
newDevCon->SetDevUnitsToAppUnits(1.0f / newDevCon->mAppUnitsToDevUnits);
newDevCon->CalcPrintingSize();
return NS_OK;
}
@@ -577,6 +542,8 @@ nsThebesDeviceContext::BeginDocument(PRUnichar* aTitle,
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->BeginPrinting(nsDependentString(aTitle ? aTitle : kEmpty),
nsDependentString(aPrintToFileName ? aPrintToFileName : kEmpty));
if (mDeviceContextSpec)
mDeviceContextSpec->BeginDocument(aTitle, aPrintToFileName, aStartPage, aEndPage);
return NS_OK;
}
@@ -584,10 +551,12 @@ nsThebesDeviceContext::BeginDocument(PRUnichar* aTitle,
NS_IMETHODIMP
nsThebesDeviceContext::EndDocument(void)
{
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->EndPrinting();
mPrintingSurface->Finish();
if (mPrintingSurface) {
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->EndPrinting();
mPrintingSurface->Finish();
}
if (mDeviceContextSpec)
mDeviceContextSpec->EndDocument();
@@ -600,6 +569,9 @@ nsThebesDeviceContext::AbortDocument(void)
{
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->AbortPrinting();
if (mDeviceContextSpec)
mDeviceContextSpec->EndDocument();
return NS_OK;
}
@@ -607,8 +579,13 @@ nsThebesDeviceContext::AbortDocument(void)
NS_IMETHODIMP
nsThebesDeviceContext::BeginPage(void)
{
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->BeginPage();
if (mPrintingSurface) {
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->BeginPage();
}
if (mDeviceContextSpec)
mDeviceContextSpec->BeginPage();
return NS_OK;
}
@@ -617,6 +594,16 @@ nsThebesDeviceContext::EndPage(void)
{
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
thebes->EndPage();
/* uhh. yeah, don't ask.
* We need to release this before we call end page for mac.. */
#ifdef XP_MACOSX
mPrintingSurface = nsnull;
#endif
if (mDeviceContextSpec)
mDeviceContextSpec->EndPage();
return NS_OK;
}
@@ -702,8 +689,8 @@ nsThebesDeviceContext::ComputeFullAreaUsingScreen(nsRect* outRect)
outRect->width = NSToIntRound(width * mDevUnitsToAppUnits);
outRect->height = NSToIntRound(height * mDevUnitsToAppUnits);
mWidth = width;
mHeight = height;
mWidth = outRect->width;
mHeight = outRect->height;
}
}
@@ -722,3 +709,64 @@ nsThebesDeviceContext::FindScreen(nsIScreen** outScreen)
else
mScreenManager->GetPrimaryScreen(outScreen);
}
void
nsThebesDeviceContext::CalcPrintingSize()
{
if (!mPrinter)
return;
PRBool inPoints = PR_TRUE;
gfxSize size;
switch (mPrintingSurface->GetType()) {
case gfxASurface::SurfaceTypeImage:
inPoints = PR_FALSE;
size = reinterpret_cast<gfxImageSurface*>(mPrintingSurface.get())->GetSize();
break;
#ifdef MOZ_ENABLE_GTK2
case gfxASurface::SurfaceTypePDF:
inPoints = PR_TRUE;
size = reinterpret_cast<gfxPDFSurface*>(mPrintingSurface.get())->GetSize();
break;
case gfxASurface::SurfaceTypePS:
inPoints = PR_TRUE;
size = reinterpret_cast<gfxPSSurface*>(mPrintingSurface.get())->GetSize();
break;
#endif
#ifdef XP_MACOSX
case gfxASurface::SurfaceTypeQuartz2:
inPoints = PR_TRUE; // this is really only true when we're printing
size = reinterpret_cast<gfxQuartzSurface*>(mPrintingSurface.get())->GetSize();
break;
#endif
#ifdef XP_WIN
case gfxASurface::SurfaceTypeWin32:
{
inPoints = PR_FALSE;
HDC dc = GetHDC() ? GetHDC() : GetDC((HWND)mWidget);
size.width = NSToIntRound(::GetDeviceCaps(dc, HORZRES) * mDevUnitsToAppUnits);
size.height = NSToIntRound(::GetDeviceCaps(dc, VERTRES) * mDevUnitsToAppUnits);
mDepth = (PRUint32)::GetDeviceCaps(dc, BITSPIXEL);
if (dc != (HDC)GetHDC())
ReleaseDC((HWND)mWidget, dc);
break;
}
#endif
default:
NS_ASSERTION(0, "trying to print to unknown surface type");
}
if (inPoints) {
mWidth = NSFloatPointsToTwips(size.width);
mHeight = NSFloatPointsToTwips(size.height);
printf("%f %f\n", size.width, size.height);
printf("%d %d\n", (PRInt32)mWidth, (PRInt32)mHeight);
} else {
mWidth = NSToIntRound(size.width);
mHeight = NSToIntRound(size.height);
}
}

View File

@@ -120,8 +120,10 @@ public:
nsNativeWidget GetWidget() { return mWidget; }
#ifdef XP_WIN
HDC GetHDC() {
if (mPrintingSurface)
if (mPrintingSurface) {
NS_ASSERTION(mPrintingSurface->GetType() == gfxASurface::SurfaceTypeWin32, "invalid surface type");
return reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
}
return nsnull;
}
#endif
@@ -131,6 +133,7 @@ protected:
void ComputeClientRectUsingScreen(nsRect* outRect);
void ComputeFullAreaUsingScreen(nsRect* outRect);
void FindScreen(nsIScreen** outScreen);
void CalcPrintingSize();
PRUint32 mDepth;

View File

@@ -68,8 +68,9 @@ public:
// ImageSurface methods
gfxImageFormat Format() const { return mFormat; }
long Width() const { return mWidth; }
long Height() const { return mHeight; }
gfxSize GetSize() const { return gfxSize(mWidth, mHeight); }
/**
* Distance in bytes between the start of a line and the start of the
* next line.

View File

@@ -49,10 +49,9 @@ public:
void SetDPI(double x, double y);
void GetDPI(double *xDPI, double *yDPI);
gfxSize GetSize() {
gfxSize size = mSize;
return size;
}
// this is in points!
gfxSize GetSize() const { return mSize; }
private:
double mXDPI;
double mYDPI;

View File

@@ -52,10 +52,9 @@ public:
void SetDPI(double x, double y);
void GetDPI(double *xDPI, double *yDPI);
gfxSize GetSize() {
gfxSize size = mSize;
return size;
}
// this is in points!
gfxSize GetSize() const { return mSize; }
private:
double mXDPI;
double mYDPI;

View File

@@ -62,8 +62,6 @@ public:
protected:
CGContextRef mCGContext;
char *mFilename;
CGRect mRect;
PRBool mAborted;
};
#endif /* GFX_QUARTZPDFSURFACE_H */

View File

@@ -54,8 +54,7 @@ public:
virtual ~gfxQuartzSurface();
unsigned long Width() { return mWidth; }
unsigned long Height() { return mHeight; }
gfxSize GetSize() const { return gfxSize(mWidth, mHeight); }
CGContextRef GetCGContext() { return mCGContext; }

View File

@@ -69,8 +69,11 @@ public:
virtual ~gfxXlibSurface();
unsigned long Width() { if (mWidth == -1) DoSizeQuery(); return mWidth; }
unsigned long Height() { if (mHeight == -1) DoSizeQuery(); return mHeight; }
gfxSize GetSize() {
if (mWidth == -1 || mHeight == -1)
DoSizeQuery();
return gfxSize(mWidth, mHeight);
}
Display* XDisplay() { return mDisplay; }
Drawable XDrawable() { return mDrawable; }

View File

@@ -93,7 +93,7 @@ CPPSRCS += gfxQuartzSurface.cpp gfxQuartzPDFSurface.cpp gfxPlatformMac.cpp gfxA
CMMSRCS = gfxQuartzFontCache.mm
# Always link with OpenGL/AGL
EXTRA_DSO_LDOPTS += -framework OpenGL -framework AGL -framework Cocoa -framework QuickTime -lcups
EXTRA_DSO_LDOPTS += -framework OpenGL -framework AGL -framework Cocoa -framework QuickTime
endif
ifdef MOZ_ENABLE_GLITZ

View File

@@ -128,19 +128,20 @@ gfxPlatform::OptimizeImage(gfxImageSurface* aSurface)
nsRefPtr<gfxASurface> optSurface;
gfxASurface::gfxImageFormat realFormat = aSurface->Format();
gfxSize surfaceSize = aSurface->GetSize();
if (realFormat == gfxASurface::ImageFormatARGB32) {
// this might not really need alpha; figure that out
if (!DoesARGBImageDataHaveAlpha(aSurface->Data(),
aSurface->Width(),
aSurface->Height(),
surfaceSize.width,
surfaceSize.height,
aSurface->Stride()))
{
realFormat = gfxASurface::ImageFormatRGB24;
}
}
optSurface = CreateOffscreenSurface(aSurface->Width(),
aSurface->Height(),
optSurface = CreateOffscreenSurface(surfaceSize.width,
surfaceSize.height,
realFormat);
if (!optSurface)

View File

@@ -39,39 +39,7 @@
#include "cairo-nquartz.h"
#if defined(MAC_OS_X_VERSION_10_4) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
#include <cups/cups.h>
#else
/* stupid apple doesn't bother to include cups.h in anything lower than
* the 10.4 SDK yet they've shipped libcups since 10.2! wtf!
* Apple is as bad as Linux! come on!
*/
extern "C" {
typedef struct
{
char *name;
char *value;
} cups_option_t;
typedef struct
{
char *name,
*instance;
int is_default;
int num_options;
cups_option_t *options;
} cups_dest_t;
extern int cupsPrintFile(const char *printer, const char *filename,
const char *title, int num_options,
cups_option_t *options);
extern void cupsFreeDests(int num_dests, cups_dest_t *dests);
extern cups_dest_t *cupsGetDest(const char *name, const char *instance,
int num_dests, cups_dest_t *dests);
extern int cupsGetDests(cups_dest_t **dests);
}
#endif
gfxQuartzPDFSurface::gfxQuartzPDFSurface(const char *filename, gfxSize aSizeInPoints)
: mFilename(strdup(filename)), mAborted(PR_FALSE)
{
mRect = CGRectMake(0.0, 0.0, aSizeInPoints.width, aSizeInPoints.height);
@@ -88,37 +56,6 @@ gfxQuartzPDFSurface::gfxQuartzPDFSurface(const char *filename, gfxSize aSizeInPo
gfxQuartzPDFSurface::~gfxQuartzPDFSurface()
{
CGContextRelease(mCGContext);
/* don't spool if we're aborted */
if (mAborted) {
printf("aborted!!\n");
free(mFilename);
return;
}
/* quick dirty spooling code */
/* this doesn't do the right thing with the print options at all. */
int ndests;
cups_dest_t *dests;
ndests = cupsGetDests(&dests);
#ifdef DEBUG_pavlov
for (int i = 0; i < ndests; i++) {
printf("%s\n", dests[i].name);
}
#endif
/* get the default printer */
cups_dest_t *defaultDest = cupsGetDest(NULL, NULL, ndests, dests);
#ifdef DEBUG_pavlov
printf("printing to: %s\n", defaultDest->name);
printf("printing: %s\n", mFilename);
#endif
/* print with the default printer */
cupsPrintFile(defaultDest->name, mFilename, "Mozilla Print Job", defaultDest->num_options, defaultDest->options);
cupsFreeDests(ndests, dests);
free(mFilename);
}
@@ -137,7 +74,6 @@ gfxQuartzPDFSurface::EndPrinting()
nsresult
gfxQuartzPDFSurface::AbortPrinting()
{
mAborted = PR_TRUE;
return NS_OK;
}

View File

@@ -371,7 +371,7 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
gfxContext tmpContext(tmpSurface);
nsSVGRenderState tmpState(&tmpContext);
memset(tmpSurface->Data(), 0, tmpSurface->Height() * tmpSurface->Stride());
memset(tmpSurface->Data(), 0, tmpSurface->GetSize().height * tmpSurface->Stride());
aTarget->PaintSVG(&tmpState, nsnull);
mPrimitiveUnits->GetAnimVal(&type);

View File

@@ -295,7 +295,7 @@ nsSVGPatternFrame::PaintPattern(cairo_surface_t** surface,
if (!tmpSurface)
return NS_ERROR_FAILURE;
memset(tmpSurface->Data(), 0, tmpSurface->Height() * tmpSurface->Stride());
memset(tmpSurface->Data(), 0, tmpSurface->GetSize().height * tmpSurface->Stride());
gfxContext tmpContext(tmpSurface);
nsSVGRenderState tmpState(&tmpContext);

View File

@@ -71,12 +71,16 @@ public:
#ifdef MOZ_CAIRO_GFX
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **nativeSurface) = 0;
NS_IMETHOD BeginDocument(PRUnichar* aTitle,
NS_IMETHOD BeginDocument(PRUnichar* aTitle,
PRUnichar* aPrintToFileName,
PRInt32 aStartPage,
PRInt32 aEndPage) = 0;
NS_IMETHOD EndDocument() = 0;
NS_IMETHOD BeginPage() = 0;
NS_IMETHOD EndPage() = 0;
#endif
};

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -54,12 +54,16 @@ public:
nsDeviceContextSpecX();
NS_DECL_ISUPPORTS
#ifdef MOZ_CAIRO_GFX
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **surface);
NS_IMETHOD BeginDocument(PRUnichar* aTitle,
PRUnichar* aPrintToFileName,
PRInt32 aStartPage,
PRInt32 aEndPage) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD EndDocument() { return NS_ERROR_NOT_IMPLEMENTED; }
PRInt32 aEndPage);
NS_IMETHOD EndDocument();
NS_IMETHOD BeginPage();
NS_IMETHOD EndPage();
#endif
/**
* Initialize the nsDeviceContextSpecX for use. This will allocate a printrecord for use
@@ -105,8 +109,7 @@ protected:
PMPrintSession mPrintSession; // printing context.
PMPageFormat mPageFormat; // page format.
PMPrintSettings mPrintSettings; // print settings.
CGrafPtr mSavedPort; // saved graphics port.
PRBool mBeganPrinting;
};
#endif // nsDeviceContextSpecX_h_
#endif //nsDeviceContextSpecX_h_

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -49,8 +49,23 @@
#include "nsIPrintOptions.h"
#include "nsIPrintSettingsX.h"
#include "nsToolkit.h"
#include "gfxQuartzSurface.h"
#include "gfxQuartzPDFSurface.h"
#include "gfxImageSurface.h"
// These symbols don't exist on 10.3, but we use them on 10.4 and greater
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAX_OS_X_VERSION_10_4
extern PMSessionGetCGGraphicsContext(PMPrintSession, CGContextRef *);
extern PMSessionBeginCGDocumentNoDialog(PMPrintSession, PMPrintSettings, PMPageFormat);
#endif
// These functions don't exist on 10.3, which we build against. However, we want to be able to use them on
// 10.4, so we need to access them at runtime.
typedef OSStatus (*fpPMSessionBeginCGDocumentNoDialog_type)(PMPrintSession, PMPrintSettings, PMPageFormat);
typedef OSStatus (*fpPMSessionGetCGGraphicsContext_type)(PMPrintSession, CGContextRef*);
static fpPMSessionBeginCGDocumentNoDialog_type fpPMSessionBeginCGDocumentNoDialog = NULL;
static fpPMSessionGetCGGraphicsContext_type fpPMSessionGetCGGraphicsContext = NULL;
/** -------------------------------------------------------
* Construct the nsDeviceContextSpecX
@@ -60,9 +75,18 @@ nsDeviceContextSpecX::nsDeviceContextSpecX()
: mPrintSession(NULL)
, mPageFormat(kPMNoPageFormat)
, mPrintSettings(kPMNoPrintSettings)
, mSavedPort(0)
, mBeganPrinting(PR_FALSE)
{
//We have to load these at runtime to use them on 10.4, since we build against 10.3.
if (nsToolkit::OnTigerOrLater()) {
CFBundleRef bundle = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.ApplicationServices"));
if (bundle) {
fpPMSessionBeginCGDocumentNoDialog = (fpPMSessionBeginCGDocumentNoDialog_type)
::CFBundleGetFunctionPointerForName(bundle, CFSTR("PMSessionBeginCGDocumentNoDialog"));
fpPMSessionGetCGGraphicsContext = (fpPMSessionGetCGGraphicsContext_type)
::CFBundleGetFunctionPointerForName(bundle, CFSTR("PMSessionGetCGGraphicsContext"));
}
}
}
/** -------------------------------------------------------
@@ -76,8 +100,11 @@ nsDeviceContextSpecX::~nsDeviceContextSpecX()
ClosePrintManager();
}
#ifdef MOZ_CAIRO_GFX
NS_IMPL_ISUPPORTS1(nsDeviceContextSpecX, nsIDeviceContextSpec)
#else
NS_IMPL_ISUPPORTS2(nsDeviceContextSpecX, nsIDeviceContextSpec, nsIPrintingContext)
#endif
/** -------------------------------------------------------
* Initialize the nsDeviceContextSpecMac
* @update dc 12/02/98
@@ -89,27 +116,27 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget,
return Init(aPS, aIsPrintPreview);
}
NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, PRBool aIsPrintPreview)
NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, PRBool aIsPrintPreview)
{
nsresult rv;
nsresult rv;
nsCOMPtr<nsIPrintSettingsX> printSettingsX(do_QueryInterface(aPS));
if (!printSettingsX)
return NS_ERROR_NO_INTERFACE;
nsCOMPtr<nsIPrintSettingsX> printSettingsX(do_QueryInterface(aPS));
if (!printSettingsX)
return NS_ERROR_NO_INTERFACE;
rv = printSettingsX->GetNativePrintSession(&mPrintSession);
if (NS_FAILED(rv))
return rv;
::PMRetain(mPrintSession);
rv = printSettingsX->GetNativePrintSession(&mPrintSession);
if (NS_FAILED(rv))
return rv;
::PMRetain(mPrintSession);
rv = printSettingsX->GetPMPageFormat(&mPageFormat);
if (NS_FAILED(rv))
return rv;
rv = printSettingsX->GetPMPrintSettings(&mPrintSettings);
if (NS_FAILED(rv))
return rv;
rv = printSettingsX->GetPMPageFormat(&mPageFormat);
if (NS_FAILED(rv))
return rv;
rv = printSettingsX->GetPMPrintSettings(&mPrintSettings);
if (NS_FAILED(rv))
return rv;
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecX::PrintManagerOpen(PRBool* aIsOpen)
@@ -124,20 +151,91 @@ NS_IMETHODIMP nsDeviceContextSpecX::PrintManagerOpen(PRBool* aIsOpen)
*/
NS_IMETHODIMP nsDeviceContextSpecX::ClosePrintManager()
{
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(PRUnichar* aTitle,
PRUnichar* aPrintToFileName,
PRInt32 aStartPage,
PRInt32 aEndPage)
{
if (aTitle) {
CFStringRef cfString = ::CFStringCreateWithCharacters(NULL, aTitle, nsCRT::strlen(aTitle));
if (cfString) {
::PMSetJobNameCFString(mPrintSettings, cfString);
::CFRelease(cfString);
}
}
OSStatus status;
status = ::PMSetFirstPage(mPrintSettings, aStartPage, false);
NS_ASSERTION(status == noErr, "PMSetFirstPage failed");
status = ::PMSetLastPage(mPrintSettings, aEndPage, false);
NS_ASSERTION(status == noErr, "PMSetLastPage failed");
if (nsToolkit::OnTigerOrLater() && fpPMSessionBeginCGDocumentNoDialog) {
//On 10.4 and above, we can easily use CoreGraphics
status = fpPMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
} else {
//Not so on 10.3. The following (taken from Apple sample code) allows us to get a CGContextRef later on 10.3
CFStringRef strings[1];
CFArrayRef graphicsContextsArray;
strings[0] = kPMGraphicsContextCoreGraphics;
graphicsContextsArray = ::CFArrayCreate(kCFAllocatorDefault, (const void **)strings, 1, &kCFTypeArrayCallBacks);
if (graphicsContextsArray != NULL) {
::PMSessionSetDocumentFormatGeneration(mPrintSession, kPMDocumentFormatPDF, graphicsContextsArray, NULL);
::CFRelease(graphicsContextsArray);
}
//Actually create the document
status = ::PMSessionBeginDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
}
if (status != noErr) return NS_ERROR_ABORT;
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecX::EndDocument()
{
::PMSessionEndDocumentNoDialog(mPrintSession);
return NS_OK;
}
/*
NS_IMETHODIMP nsDeviceContextSpecX::AbortDocument()
{
return EndDocument();
}
*/
NS_IMETHODIMP nsDeviceContextSpecX::BeginPage()
{
PMSessionError(mPrintSession);
OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL);
if (status != noErr) return NS_ERROR_ABORT;
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecX::EndPage()
{
OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
if (status != noErr) return NS_ERROR_ABORT;
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecX::GetPrinterResolution(double* aResolution)
{
PMPrinter printer;
OSStatus status = ::PMSessionGetCurrentPrinter(mPrintSession, &printer);
if (status != noErr)
return NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
PMResolution defaultResolution;
status = ::PMPrinterGetPrinterResolution(printer, kPMDefaultResolution, &defaultResolution);
if (status != noErr)
return NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
*aResolution = defaultResolution.hRes;
return NS_OK;
@@ -154,21 +252,29 @@ NS_IMETHODIMP nsDeviceContextSpecX::GetPageRect(double* aTop, double* aLeft, dou
NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface)
{
// PDF surface -- prints to file and then uses cups to spool
char *filename;
char tmpfilename[] = "/tmp/printing.XXXXXX";
filename = mktemp(tmpfilename);
double top, left, bottom, right;
GetPageRect(&top, &left, &bottom, &right);
const double width = right - left;
const double height = bottom - top;
nsRefPtr<gfxASurface> newSurface = new gfxQuartzPDFSurface(filename, gfxSize(width, height));
//On 10.4 or later, just use CG natively. On 10.3, though, we have to request CG specifically.
CGContextRef context;
if (nsToolkit::OnTigerOrLater() && fpPMSessionGetCGGraphicsContext) {
fpPMSessionGetCGGraphicsContext(mPrintSession, &context);
} else {
::PMSessionGetGraphicsContext(mPrintSession, kPMGraphicsContextCoreGraphics, (void **)&context);
}
nsRefPtr<gfxASurface> newSurface;
if (context)
newSurface = new gfxQuartzSurface(context, (int)width, (int)height, PR_FALSE);
else
newSurface = new gfxImageSurface(gfxASurface::ImageFormatARGB32, width, height);
if (!newSurface)
return NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
*surface = newSurface;
NS_ADDREF(*surface);

View File

@@ -91,6 +91,8 @@ public:
NS_IMETHOD ClosePrintManager();
NS_IMETHOD BeginDocument(PRUnichar * aTitle, PRUnichar * aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage);
NS_IMETHOD EndDocument();
NS_IMETHOD BeginPage() { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD EndPage() { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD GetToPrinter(PRBool &aToPrinter);
NS_IMETHOD GetIsPrintPreview(PRBool &aIsPPreview);

View File

@@ -63,6 +63,8 @@ public:
PRInt32 aStartPage,
PRInt32 aEndPage) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD EndDocument() { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD BeginPage() { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD EndPage() { return NS_ERROR_NOT_IMPLEMENTED; }
#else
// kill these when we move to CAIRO_GFX
NS_IMETHOD GetType(PRUint16 *aType) { *aType = nsISupportsPrimitive::TYPE_VOID; return NS_OK; }