From 4169248ca101d4c84845f8bf1f4eab24ee7d15f7 Mon Sep 17 00:00:00 2001 From: "pavlov%pavlov.net" Date: Sat, 27 Jan 2007 04:06:59 +0000 Subject: [PATCH] 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 --- mozilla/browser/app/Makefile.in | 2 +- .../gfx/src/thebes/nsThebesDeviceContext.cpp | 154 ++++++++++------ .../gfx/src/thebes/nsThebesDeviceContext.h | 5 +- mozilla/gfx/thebes/public/gfxImageSurface.h | 5 +- mozilla/gfx/thebes/public/gfxPDFSurface.h | 7 +- mozilla/gfx/thebes/public/gfxPSSurface.h | 7 +- .../gfx/thebes/public/gfxQuartzPDFSurface.h | 2 - mozilla/gfx/thebes/public/gfxQuartzSurface.h | 3 +- mozilla/gfx/thebes/public/gfxXlibSurface.h | 7 +- mozilla/gfx/thebes/src/Makefile.in | 2 +- mozilla/gfx/thebes/src/gfxPlatform.cpp | 9 +- .../gfx/thebes/src/gfxQuartzPDFSurface.cpp | 64 ------- .../layout/svg/base/src/nsSVGFilterFrame.cpp | 2 +- .../layout/svg/base/src/nsSVGPatternFrame.cpp | 2 +- mozilla/widget/public/nsIDeviceContextSpec.h | 6 +- .../widget/src/cocoa/nsDeviceContextSpecX.h | 13 +- .../widget/src/cocoa/nsDeviceContextSpecX.mm | 166 ++++++++++++++---- .../widget/src/gtk2/nsDeviceContextSpecG.h | 2 + .../src/windows/nsDeviceContextSpecWin.h | 2 + 19 files changed, 282 insertions(+), 178 deletions(-) diff --git a/mozilla/browser/app/Makefile.in b/mozilla/browser/app/Makefile.in index 4e7abcf4c1a..8179c37130c 100644 --- a/mozilla/browser/app/Makefile.in +++ b/mozilla/browser/app/Makefile.in @@ -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 diff --git a/mozilla/gfx/src/thebes/nsThebesDeviceContext.cpp b/mozilla/gfx/src/thebes/nsThebesDeviceContext.cpp index 0ad7fbe1f7c..22825e16c73 100644 --- a/mozilla/gfx/src/thebes/nsThebesDeviceContext.cpp +++ b/mozilla/gfx/src/thebes/nsThebesDeviceContext.cpp @@ -62,6 +62,8 @@ #include #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 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 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 thebes = new gfxContext(mPrintingSurface); - thebes->EndPrinting(); - - mPrintingSurface->Finish(); + if (mPrintingSurface) { + nsRefPtr thebes = new gfxContext(mPrintingSurface); + thebes->EndPrinting(); + + mPrintingSurface->Finish(); + } if (mDeviceContextSpec) mDeviceContextSpec->EndDocument(); @@ -600,6 +569,9 @@ nsThebesDeviceContext::AbortDocument(void) { nsRefPtr 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 thebes = new gfxContext(mPrintingSurface); - thebes->BeginPage(); + if (mPrintingSurface) { + nsRefPtr thebes = new gfxContext(mPrintingSurface); + thebes->BeginPage(); + } + + if (mDeviceContextSpec) + mDeviceContextSpec->BeginPage(); return NS_OK; } @@ -617,6 +594,16 @@ nsThebesDeviceContext::EndPage(void) { nsRefPtr 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(mPrintingSurface.get())->GetSize(); + break; + +#ifdef MOZ_ENABLE_GTK2 + case gfxASurface::SurfaceTypePDF: + inPoints = PR_TRUE; + size = reinterpret_cast(mPrintingSurface.get())->GetSize(); + break; + case gfxASurface::SurfaceTypePS: + inPoints = PR_TRUE; + size = reinterpret_cast(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(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); + } +} diff --git a/mozilla/gfx/src/thebes/nsThebesDeviceContext.h b/mozilla/gfx/src/thebes/nsThebesDeviceContext.h index 87715b69ee3..6eaddd831bc 100644 --- a/mozilla/gfx/src/thebes/nsThebesDeviceContext.h +++ b/mozilla/gfx/src/thebes/nsThebesDeviceContext.h @@ -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(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; diff --git a/mozilla/gfx/thebes/public/gfxImageSurface.h b/mozilla/gfx/thebes/public/gfxImageSurface.h index 5de4e04c304..0c4843510a9 100644 --- a/mozilla/gfx/thebes/public/gfxImageSurface.h +++ b/mozilla/gfx/thebes/public/gfxImageSurface.h @@ -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. diff --git a/mozilla/gfx/thebes/public/gfxPDFSurface.h b/mozilla/gfx/thebes/public/gfxPDFSurface.h index 0506155457d..1ad6feb005c 100644 --- a/mozilla/gfx/thebes/public/gfxPDFSurface.h +++ b/mozilla/gfx/thebes/public/gfxPDFSurface.h @@ -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; diff --git a/mozilla/gfx/thebes/public/gfxPSSurface.h b/mozilla/gfx/thebes/public/gfxPSSurface.h index eec22f707e9..63cbb0faa71 100644 --- a/mozilla/gfx/thebes/public/gfxPSSurface.h +++ b/mozilla/gfx/thebes/public/gfxPSSurface.h @@ -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; diff --git a/mozilla/gfx/thebes/public/gfxQuartzPDFSurface.h b/mozilla/gfx/thebes/public/gfxQuartzPDFSurface.h index d499e2b1b57..7c95cccf4fe 100644 --- a/mozilla/gfx/thebes/public/gfxQuartzPDFSurface.h +++ b/mozilla/gfx/thebes/public/gfxQuartzPDFSurface.h @@ -62,8 +62,6 @@ public: protected: CGContextRef mCGContext; - char *mFilename; CGRect mRect; - PRBool mAborted; }; #endif /* GFX_QUARTZPDFSURFACE_H */ diff --git a/mozilla/gfx/thebes/public/gfxQuartzSurface.h b/mozilla/gfx/thebes/public/gfxQuartzSurface.h index cbe535dd625..104f0bcf31d 100644 --- a/mozilla/gfx/thebes/public/gfxQuartzSurface.h +++ b/mozilla/gfx/thebes/public/gfxQuartzSurface.h @@ -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; } diff --git a/mozilla/gfx/thebes/public/gfxXlibSurface.h b/mozilla/gfx/thebes/public/gfxXlibSurface.h index 17cc5f1bde1..f217ae75c95 100644 --- a/mozilla/gfx/thebes/public/gfxXlibSurface.h +++ b/mozilla/gfx/thebes/public/gfxXlibSurface.h @@ -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; } diff --git a/mozilla/gfx/thebes/src/Makefile.in b/mozilla/gfx/thebes/src/Makefile.in index 12cb0f53036..bfec53fd45c 100644 --- a/mozilla/gfx/thebes/src/Makefile.in +++ b/mozilla/gfx/thebes/src/Makefile.in @@ -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 diff --git a/mozilla/gfx/thebes/src/gfxPlatform.cpp b/mozilla/gfx/thebes/src/gfxPlatform.cpp index 1ec8576e3a7..b417ae9d82f 100644 --- a/mozilla/gfx/thebes/src/gfxPlatform.cpp +++ b/mozilla/gfx/thebes/src/gfxPlatform.cpp @@ -128,19 +128,20 @@ gfxPlatform::OptimizeImage(gfxImageSurface* aSurface) nsRefPtr 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) diff --git a/mozilla/gfx/thebes/src/gfxQuartzPDFSurface.cpp b/mozilla/gfx/thebes/src/gfxQuartzPDFSurface.cpp index 5e62f470d00..8fe5c0d2c7a 100644 --- a/mozilla/gfx/thebes/src/gfxQuartzPDFSurface.cpp +++ b/mozilla/gfx/thebes/src/gfxQuartzPDFSurface.cpp @@ -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 -#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; } diff --git a/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp b/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp index 5729dc2e842..53d0e14443f 100644 --- a/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp @@ -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); diff --git a/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp b/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp index 1749dfcb4d4..e1efddc9d45 100644 --- a/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp @@ -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); diff --git a/mozilla/widget/public/nsIDeviceContextSpec.h b/mozilla/widget/public/nsIDeviceContextSpec.h index 99f97f976d9..e76f9ff811d 100644 --- a/mozilla/widget/public/nsIDeviceContextSpec.h +++ b/mozilla/widget/public/nsIDeviceContextSpec.h @@ -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 }; diff --git a/mozilla/widget/src/cocoa/nsDeviceContextSpecX.h b/mozilla/widget/src/cocoa/nsDeviceContextSpecX.h index 013bf131f1b..1ee9bbaa112 100644 --- a/mozilla/widget/src/cocoa/nsDeviceContextSpecX.h +++ b/mozilla/widget/src/cocoa/nsDeviceContextSpecX.h @@ -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_ diff --git a/mozilla/widget/src/cocoa/nsDeviceContextSpecX.mm b/mozilla/widget/src/cocoa/nsDeviceContextSpecX.mm index 5f579499325..7b23545604d 100644 --- a/mozilla/widget/src/cocoa/nsDeviceContextSpecX.mm +++ b/mozilla/widget/src/cocoa/nsDeviceContextSpecX.mm @@ -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 printSettingsX(do_QueryInterface(aPS)); - if (!printSettingsX) - return NS_ERROR_NO_INTERFACE; + nsCOMPtr 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 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 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); diff --git a/mozilla/widget/src/gtk2/nsDeviceContextSpecG.h b/mozilla/widget/src/gtk2/nsDeviceContextSpecG.h index d9551e1a7f4..4b33d2d1a40 100644 --- a/mozilla/widget/src/gtk2/nsDeviceContextSpecG.h +++ b/mozilla/widget/src/gtk2/nsDeviceContextSpecG.h @@ -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); diff --git a/mozilla/widget/src/windows/nsDeviceContextSpecWin.h b/mozilla/widget/src/windows/nsDeviceContextSpecWin.h index e311c7d7814..9423e4d82a0 100644 --- a/mozilla/widget/src/windows/nsDeviceContextSpecWin.h +++ b/mozilla/widget/src/windows/nsDeviceContextSpecWin.h @@ -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; }