cocoa-cairo printing. bug 359124. r=vlad

This commit is contained in:
pavlov%pavlov.net 2006-11-28 21:10:05 +00:00
parent 7650b7bf1b
commit 21165fdebb
8 changed files with 281 additions and 20 deletions

View File

@ -547,6 +547,29 @@ SurfacePatternDrawFunc (void *info, CGContextRef context)
cairo_surface_destroy ((cairo_surface_t*) quartz_surf);
}
/* Borrowed from cairo-meta-surface */
static cairo_status_t
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
_cairo_pattern_init_copy (pattern, other);
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern =
(cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
surface_pattern->surface = _cairo_surface_snapshot (surface);
cairo_surface_destroy (surface);
if (surface_pattern->surface->status)
return surface_pattern->surface->status;
}
return CAIRO_STATUS_SUCCESS;
}
static CGPatternRef
_cairo_nquartz_cairo_repeating_surface_pattern_to_quartz (cairo_nquartz_surface_t *dest,
cairo_pattern_t *abspat)
@ -563,6 +586,9 @@ _cairo_nquartz_cairo_repeating_surface_pattern_to_quartz (cairo_nquartz_surface_
CGPatternRef cgpat;
float rw, rh;
cairo_pattern_union_t *snap_pattern = NULL;
cairo_pattern_t *target_pattern = abspat;
/* SURFACE is the only type we'll handle here */
if (abspat->type != CAIRO_PATTERN_TYPE_SURFACE)
return NULL;
@ -627,8 +653,18 @@ _cairo_nquartz_cairo_repeating_surface_pattern_to_quartz (cairo_nquartz_surface_
rh = extents.height;
#endif
cairo_pattern_reference (abspat);
cgpat = CGPatternCreate (abspat,
/* XXX fixme: only do snapshots if the context is for printing, or get rid of the
other block if it doesn't fafect performance */
if (1 /* context is for printing */) {
snap_pattern = (cairo_pattern_union_t*) malloc(sizeof(cairo_pattern_union_t));
target_pattern = (cairo_pattern_t*) snap_pattern;
_init_pattern_with_snapshot (snap_pattern, abspat);
} else {
cairo_pattern_reference (abspat);
target_pattern = abspat;
}
cgpat = CGPatternCreate (target_pattern,
pbounds,
ptransform,
rw, rh,

View File

@ -78,6 +78,7 @@ static nsSystemFontsWin *gSystemFonts = nsnull;
static nsSystemFontsBeOS *gSystemFonts = nsnull;
#elif XP_MACOSX
#include "nsSystemFontsMac.h"
#include "gfxQuartzPDFSurface.h"
static nsSystemFontsMac *gSystemFonts = nsnull;
#else
#error Need to declare gSystemFonts!
@ -178,6 +179,14 @@ nsThebesDeviceContext::SetDPI(PRInt32 aPrefDPI)
if (OSVal != 0)
dpi = OSVal;
#elif defined(XP_MACOSX)
if (mPrinter) {
dpi = 72;
do_round = PR_FALSE;
}
#endif
int in2pt = 72;
@ -219,6 +228,16 @@ 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")) {
PR_LOG (gThebesGFXLog, PR_LOG_DEBUG, ("+++ Enabling XSynchronize\n"));
@ -453,7 +472,7 @@ nsThebesDeviceContext::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHei
{
if (mPrinter) {
// we have a printer device
#ifdef MOZ_ENABLE_GTK2
#if defined(MOZ_ENABLE_GTK2) || defined(XP_MACOSX)
aWidth = mWidth;
aHeight = mHeight;
#else
@ -477,7 +496,7 @@ nsThebesDeviceContext::GetRect(nsRect &aRect)
// we have a printer device
aRect.x = 0;
aRect.y = 0;
#ifdef MOZ_ENABLE_GTK2
#if defined(MOZ_ENABLE_GTK2) || defined(XP_MACOSX)
aRect.width = NSToIntRound(mWidth);
aRect.height = NSToIntRound(mHeight);
#else
@ -497,7 +516,7 @@ nsThebesDeviceContext::GetClientRect(nsRect &aRect)
// we have a printer device
aRect.x = 0;
aRect.y = 0;
#ifdef MOZ_ENABLE_GTK2
#if defined(MOZ_ENABLE_GTK2) || defined(XP_MACOSX)
aRect.width = NSToIntRound(mWidth);
aRect.height = NSToIntRound(mHeight);
#else

View File

@ -60,6 +60,7 @@ endif
ifneq (,$(filter $(MOZ_GFX_TOOLKIT),mac cocoa))
EXPORTS += gfxPlatformMac.h \
gfxQuartzSurface.h \
gfxQuartzPDFSurface.h \
gfxAtsuiFonts.h \
$(NULL)

View File

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_QUARTZPDFSURFACE_H
#define GFX_QUARTZPDFSURFACE_H
#include "gfxASurface.h"
#include <Carbon/Carbon.h>
class THEBES_API gfxQuartzPDFSurface : public gfxASurface {
public:
gfxQuartzPDFSurface(const char *filename, gfxSize aSizeInPoints);
virtual ~gfxQuartzPDFSurface();
nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName);
nsresult EndPrinting();
nsresult AbortPrinting();
nsresult BeginPage();
nsresult EndPage();
gfxSize GetSize() {
gfxSize size(mRect.size.width, mRect.size.height);
return size;
}
CGContextRef GetCGContext() { return mCGContext; }
protected:
CGContextRef mCGContext;
char *mFilename;
CGRect mRect;
PRBool mAborted;
};
#endif /* GFX_QUARTZPDFSURFACE_H */

View File

@ -58,6 +58,7 @@ public:
unsigned long Height() { return mHeight; }
CGContextRef GetCGContext() { return mCGContext; }
protected:
CGContextRef mCGContext;
unsigned long mWidth, mHeight;

View File

@ -81,13 +81,13 @@ endif
ifneq (,$(filter $(MOZ_GFX_TOOLKIT),mac cocoa))
CPPSRCS += gfxQuartzSurface.cpp gfxPlatformMac.cpp gfxAtsuiFonts.cpp
CPPSRCS += gfxQuartzSurface.cpp gfxQuartzPDFSurface.cpp gfxPlatformMac.cpp gfxAtsuiFonts.cpp
#CPPSRCS += gfxPDFSurface.cpp
CMMSRCS = gfxQuartzFontCache.mm
# Always link with OpenGL/AGL
EXTRA_DSO_LDOPTS += -framework OpenGL -framework AGL -framework Cocoa -framework QuickTime
EXTRA_DSO_LDOPTS += -framework OpenGL -framework AGL -framework Cocoa -framework QuickTime -lcups
endif
ifdef MOZ_ENABLE_GLITZ

View File

@ -0,0 +1,129 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "gfxQuartzPDFSurface.h"
#include "cairo-nquartz.h"
#include <cups/cups.h>
gfxQuartzPDFSurface::gfxQuartzPDFSurface(const char *filename, gfxSize aSizeInPoints)
: mFilename(strdup(filename)), mAborted(PR_FALSE)
{
mRect = CGRectMake(0.0, 0.0, aSizeInPoints.width, aSizeInPoints.height);
CFStringRef file = CFStringCreateWithCString(kCFAllocatorDefault, filename, kCFStringEncodingUTF8);
CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, file, kCFURLPOSIXPathStyle, false);
mCGContext = CGPDFContextCreateWithURL(fileURL, &mRect, NULL);
CFRelease(file);
CFRelease(fileURL);
Init(cairo_nquartz_surface_create_for_cg_context(mCGContext, aSizeInPoints.width, aSizeInPoints.height, PR_FALSE));
}
gfxQuartzPDFSurface::~gfxQuartzPDFSurface()
{
Destroy();
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);
}
nsresult
gfxQuartzPDFSurface::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName)
{
return NS_OK;
}
nsresult
gfxQuartzPDFSurface::EndPrinting()
{
return NS_OK;
}
nsresult
gfxQuartzPDFSurface::AbortPrinting()
{
mAborted = PR_TRUE;
return NS_OK;
}
nsresult
gfxQuartzPDFSurface::BeginPage()
{
CGContextBeginPage(mCGContext, &mRect);
return NS_OK;
}
nsresult
gfxQuartzPDFSurface::EndPage()
{
CGContextEndPage(mCGContext);
return NS_OK;
}

View File

@ -43,6 +43,7 @@
#include "prmem.h"
#include "plstr.h"
#include "nsCRT.h"
#include <unistd.h>
#include "nsIServiceManager.h"
#include "nsIPrintOptions.h"
@ -50,6 +51,7 @@
#ifdef MOZ_CAIRO_GFX
#include "gfxQuartzSurface.h"
#include "gfxQuartzPDFSurface.h"
#endif
/** -------------------------------------------------------
@ -161,12 +163,14 @@ NS_IMETHODIMP nsDeviceContextSpecX::BeginPage()
OSStatus status = ::PMSessionBeginPage(mPrintSession, mPageFormat, NULL);
if (status != noErr) return NS_ERROR_ABORT;
#ifndef MOZ_CAIRO_GFX
::GetPort(&mSavedPort);
void *graphicsContext;
status = ::PMSessionGetGraphicsContext(mPrintSession, kPMGraphicsContextQuickdraw, &graphicsContext);
if (status != noErr)
return NS_ERROR_ABORT;
::SetPort((CGrafPtr)graphicsContext);
#endif
return NS_OK;
}
@ -211,23 +215,25 @@ NS_IMETHODIMP nsDeviceContextSpecX::GetPageRect(double* aTop, double* aLeft, dou
#ifdef MOZ_CAIRO_GFX
NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface)
{
#if 0
// open this when cairo-mac / cairo-cocoa printing is ready
// 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);
nsRefPtr<gfxASurface> newSurface = new gfxQuartzSurface(gfxASurface::ImageFormatRGB24, right - left, bottom - top, PR_TRUE);
if (newSurface) {
*surface = newSurface;
NS_ADDREF(*surface);
const double width = right - left;
const double height = bottom - top;
return NS_OK;
}
NS_WARNING("GetSurfaceForPrinter failed to create gfxQuartzSurface.");
#endif
*surface = nsnull;
nsRefPtr<gfxASurface> newSurface = new gfxQuartzPDFSurface(filename, gfxSize(width, height));
return NS_ERROR_FAILURE;
if (!newSurface)
return NS_ERROR_FAILURE;
*surface = newSurface;
NS_ADDREF(*surface);
return NS_OK;
}
#endif