From 89c1ce993a42ecbd183c964df58016cd40c54f37 Mon Sep 17 00:00:00 2001 From: Fred Kiefer Date: Fri, 27 Apr 2007 12:23:28 +0000 Subject: [PATCH] Use cairo specific code for PS file creation git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@25088 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 27 ++++++++++- Headers/cairo/CairoGState.h | 4 +- Headers/cairo/CairoPSSurface.h | 38 +++++++++++++++ Headers/cairo/CairoSurface.h | 2 - Headers/cairo/XGCairoSurface.h | 3 -- Headers/cairo/XGCairoXImageSurface.h | 7 ++- Source/cairo/CairoContext.m | 58 +++++++++++++---------- Source/cairo/CairoGState.m | 42 +++++++++-------- Source/cairo/CairoPSSurface.m | 69 ++++++++++++++++++++++++++++ Source/cairo/CairoSurface.m | 12 ----- Source/cairo/GNUmakefile | 1 + Source/cairo/XGCairoSurface.m | 2 + Source/cairo/XGCairoXImageSurface.m | 24 +++++----- 13 files changed, 209 insertions(+), 80 deletions(-) create mode 100644 Headers/cairo/CairoPSSurface.h create mode 100644 Source/cairo/CairoPSSurface.m diff --git a/ChangeLog b/ChangeLog index 6559f55..2664837 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2007-04-27 Fred Kiefer + + * Headers/cairo/CairoSurface.h, + * Source/cairo/CairoSurface.m: Remove default surface type setting. + * Headers/cairo/XGCairoSurface.h: Remove includes. + * Source/cairo/XGCairoSurface.m: Add includes. + * Headers/cairo/XGCairoXImageSurface.h: Remove includes. + * Source/cairo/XGCairoXImageSurface.m: Add includes, add missing + dealloc method. + * Headers/cairo/CairoPSSurface.h, + * Source/cairo/CairoPSSurface.m: New files. + * Source/cairo/GNUmakefile: Add CairoPSSurface. + * Headers/cairo/CairoGState.h, + * Source/cairo/CairoGState.m: Replace method -GSSetDevice::: with + -GSSetDevice::: and GSCurrentDevice::: with GSCurrentSurface:::. + * Source/cairo/CairoGState.m (-DPSshowpage): Implement this method. + * Source/cairo/CairoContext.m (-DPSgrestore, -DPSgsave): Remove + these newly added methods. + * Source/cairo/CairoContext.m (-initializeBackend): No longer set + default surface type. + * Source/cairo/CairoContext.m (-GSSetDevice:::): Create the + surface here. + * Source/cairo/CairoContext.m (-initWithContextInfo:): For PS + output set the surface here. + 2007-04-24 Fred Kiefer * Source/x11/XGDragView.m (-sendExternalEvent:... toWindow:) Tell @@ -50,7 +75,7 @@ * Source/art/ARTConext.m: Removed ARTContext bits. * Source/art/blit-main.m: New file split out from blit.m. * Source/art/blit.m: Removed self include stuff. - * Source/GNUmakefile: Add new source files. + * Source/art/GNUmakefile: Add new source files. * Source/art/composite.m: Adopt to GNUstep coding style. 2007-03-22 Fred Kiefer diff --git a/Headers/cairo/CairoGState.h b/Headers/cairo/CairoGState.h index 093e4d0..061e69f 100644 --- a/Headers/cairo/CairoGState.h +++ b/Headers/cairo/CairoGState.h @@ -36,8 +36,8 @@ CairoSurface *_surface; } -- (void) GSCurrentDevice: (void **)device: (int *)x : (int *)y; -- (void) GSSetDevice: (void *)device : (int)x : (int)y; +- (void) GSCurrentSurface: (CairoSurface **)surface: (int *)x : (int *)y; +- (void) GSSetSurface: (CairoSurface *)surface : (int)x : (int)y; - (void) DPSgsave; - (void) DPSgrestore; diff --git a/Headers/cairo/CairoPSSurface.h b/Headers/cairo/CairoPSSurface.h new file mode 100644 index 0000000..2c331da --- /dev/null +++ b/Headers/cairo/CairoPSSurface.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2007 Free Software Foundation, Inc. + + Author: Fred Kiefer + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef XGCairoPSSurface_h +#define XGCairoPSSurface_h + +#include "cairo/CairoSurface.h" + +@interface CairoPSSurface : CairoSurface +{ + NSSize size; +} + +- (void)setSize: (NSSize)newSize; +- (void)writeComment: (NSString *)comment; + +@end + +#endif diff --git a/Headers/cairo/CairoSurface.h b/Headers/cairo/CairoSurface.h index f082ed1..57b06f8 100644 --- a/Headers/cairo/CairoSurface.h +++ b/Headers/cairo/CairoSurface.h @@ -33,8 +33,6 @@ cairo_surface_t *_surface; } -+ (void) setDefaultSurfaceClass: (Class)aClass; - - (id) initWithDevice: (void *)device; - (NSSize) size; diff --git a/Headers/cairo/XGCairoSurface.h b/Headers/cairo/XGCairoSurface.h index 854c548..7624b9e 100644 --- a/Headers/cairo/XGCairoSurface.h +++ b/Headers/cairo/XGCairoSurface.h @@ -23,9 +23,6 @@ #ifndef XGCairoSurface_h #define XGCairoSurface_h -#include "x11/XGServer.h" -#include "x11/XGServerWindow.h" - #include "cairo/CairoSurface.h" @interface XGCairoSurface : CairoSurface diff --git a/Headers/cairo/XGCairoXImageSurface.h b/Headers/cairo/XGCairoXImageSurface.h index edcd07b..deb3609 100644 --- a/Headers/cairo/XGCairoXImageSurface.h +++ b/Headers/cairo/XGCairoXImageSurface.h @@ -23,14 +23,13 @@ #ifndef XGCairoXImageSurface_h #define XGCairoXImageSurface_h -#include "x11/XGServer.h" -#include "x11/XGServerWindow.h" -#include "x11/XWindowBuffer.h" #include "cairo/CairoSurface.h" +@class XWindowBuffer; + @interface XGCairoXImageSurface : CairoSurface { - @public + @private XWindowBuffer *wi; } @end diff --git a/Source/cairo/CairoContext.m b/Source/cairo/CairoContext.m index 1297d19..265883d 100644 --- a/Source/cairo/CairoContext.m +++ b/Source/cairo/CairoContext.m @@ -22,6 +22,7 @@ #include "cairo/CairoContext.h" #include "cairo/CairoGState.h" #include "cairo/CairoSurface.h" +#include "cairo/CairoPSSurface.h" #include "cairo/CairoFontInfo.h" #include "cairo/CairoFontEnumerator.h" #include "x11/XGServer.h" @@ -32,6 +33,8 @@ #else #include "cairo/XGCairoSurface.h" #include "cairo/XGCairoXImageSurface.h" +#include "x11/XGServerWindow.h" +#include "x11/XWindowBuffer.h" #endif #define CGSTATE ((CairoGState *)gstate) @@ -42,15 +45,8 @@ + (void) initializeBackend { - //NSLog (@"CairoContext : Initializing cairo backend"); [NSGraphicsContext setDefaultContextClass: self]; -#ifdef USE_GLITZ - [CairoSurface setDefaultSurfaceClass: [XGCairoGlitzSurface class]]; -#else -// [CairoSurface setDefaultSurfaceClass: [XGCairoSurface class]]; - [CairoSurface setDefaultSurfaceClass: [XGCairoXImageSurface class]]; -#endif [GSFontEnumerator setDefaultClass: [CairoFontEnumerator class]]; [GSFontInfo setDefaultClass: [CairoFontInfo class]]; } @@ -61,16 +57,25 @@ contextType = [info objectForKey: NSGraphicsContextRepresentationFormatAttributeName]; - self = [super initWithContextInfo: info]; - if (contextType) - { - /* Most likely this is a PS or PDF context, so just return what - super gave us */ - return self; - } + // Don't allow super to handle PS case. + self = [super initWithContextInfo: nil]; + if (!self) + return self; gstate = [[CairoGState allocWithZone: [self zone]] initWithDrawContext: self]; + if (contextType) + { + CairoSurface *surface; + NSSize size; + + surface = [[CairoPSSurface alloc] initWithDevice: info]; + // This strange setting is needed because of the way GUI handles offset. + size = [surface size]; + [CGSTATE GSSetSurface: surface : 0.0 : size.height]; + RELEASE(surface); + } + return self; } @@ -105,22 +110,27 @@ - (void) GSCurrentDevice: (void **)device : (int *)x : (int *)y { - [CGSTATE GSCurrentDevice: device : x : y]; + CairoSurface *surface; + + [CGSTATE GSCurrentSurface: &surface : x : y]; + if (device) + { + *device = surface->gsDevice; + } } - (void) GSSetDevice: (void *)device : (int)x : (int)y { - [CGSTATE GSSetDevice: device : x : y]; -} + CairoSurface *surface; -- (void) DPSgrestore -{ - [CGSTATE DPSgrestore]; -} +#ifdef USE_GLITZ + surface = [[XGCairoGlitzSurface alloc] initWithDevice: device]; +#else + //surface = [[XGCairoSurface alloc] initWithDevice: device]; + surface = [[XGCairoXImageSurface alloc] initWithDevice: device]; +#endif -- (void) DPSgsave -{ - [CGSTATE DPSgsave]; + [CGSTATE GSSetSurface: surface : x : y]; } @end diff --git a/Source/cairo/CairoGState.m b/Source/cairo/CairoGState.m index f68abb0..60f63e6 100644 --- a/Source/cairo/CairoGState.m +++ b/Source/cairo/CairoGState.m @@ -129,44 +129,35 @@ return copy; } -- (void) GSCurrentDevice: (void **)device: (int *)x : (int *)y +- (void) GSCurrentSurface: (CairoSurface **)surface: (int *)x : (int *)y { if (x) *x = offset.x; if (y) *y = offset.y; - if (device) + if (surface) { - if (_surface) - { - *device = _surface->gsDevice; - } - else - { - *device = NULL; - } + *surface = _surface; } } -- (void) GSSetDevice: (void *)device : (int)x : (int)y +- (void) GSSetSurface: (CairoSurface *)surface : (int)x : (int)y { - DESTROY(_surface); - _surface = [[CairoSurface alloc] initWithDevice: device]; + ASSIGN(_surface, surface); [self setOffset: NSMakePoint(x, y)]; [self DPSinitgraphics]; } - (void) setOffset: (NSPoint)theOffset { - NSSize size = {0, 0}; - if (_surface != nil) { - size = [_surface size]; + NSSize size = [_surface size]; + + cairo_surface_set_device_offset([_surface surface], -theOffset.x, + theOffset.y - size.height); } [super setOffset: theOffset]; - cairo_surface_set_device_offset([_surface surface], -theOffset.x, - theOffset.y - size.height); } - (void) DPSgrestore @@ -174,6 +165,10 @@ if (_ct) { cairo_restore(_ct); + if (cairo_status(_ct) == CAIRO_STATUS_INVALID_RESTORE) + { + // Restore failed because there was no more state on the stack + } } } @@ -185,6 +180,14 @@ } } +- (void) DPSshowpage +{ + if (_ct) + { + cairo_show_page(_ct); + } +} + /* * Color operations */ @@ -931,11 +934,10 @@ _set_op(cairo_t *ct, NSCompositingOperation op) path = [NSBezierPath bezierPathWithRect: aRect]; [path transformUsingAffineTransform: ctm]; [self _setPath]; - path = oldPath; cairo_clip(_ct); - cairo_paint(_ct); cairo_restore(_ct); + path = oldPath; } } diff --git a/Source/cairo/CairoPSSurface.m b/Source/cairo/CairoPSSurface.m new file mode 100644 index 0000000..cae69ca --- /dev/null +++ b/Source/cairo/CairoPSSurface.m @@ -0,0 +1,69 @@ +/* + Copyright (C) 2007 Free Software Foundation, Inc. + + Author: Fred Kiefer + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "cairo/CairoPSSurface.h" +#include + +@implementation CairoPSSurface + +- (id) initWithDevice: (void *)device +{ + NSDictionary *info; + NSString *path; + + info = (NSDictionary*)device; + path = [info objectForKey: @"NSOutputFile"]; + //NSLog(@"Write to file %@", path); + // This gets only set later on: + // @"NSPrintSheetBounds" + + + // FIXME: Hard coded size in points + size = NSMakeSize(400, 400); + _surface = cairo_ps_surface_create([path fileSystemRepresentation], size.width, size.height); + if (cairo_surface_status(_surface)) + { + NSLog(@"Could not create surface"); + DESTROY(self); + } + + return self; +} + +- (NSSize) size +{ + return size; +} + +- (void) setSize: (NSSize)newSize +{ + size = newSize; + cairo_ps_surface_set_size(_surface, size.width, size.height); +} + + +- (void) writeComment: (NSString *)comment +{ + cairo_ps_surface_dsc_comment(_surface, [comment UTF8String]); +} + +@end diff --git a/Source/cairo/CairoSurface.m b/Source/cairo/CairoSurface.m index 338c21b..862c21b 100644 --- a/Source/cairo/CairoSurface.m +++ b/Source/cairo/CairoSurface.m @@ -22,20 +22,8 @@ #include "cairo/CairoSurface.h" -static Class __defaultSurfaceClass; - @implementation CairoSurface -+ (void) setDefaultSurfaceClass: (Class)aClass -{ - __defaultSurfaceClass = aClass; -} - -+ (id) allocWithZone: (NSZone*)zone -{ - return NSAllocateObject(__defaultSurfaceClass, 0, zone); -} - - (id) initWithDevice: (void *) device { /* TODO FIXME make a more abstract struct for the device */ diff --git a/Source/cairo/GNUmakefile b/Source/cairo/GNUmakefile index c516aeb..332d40b 100644 --- a/Source/cairo/GNUmakefile +++ b/Source/cairo/GNUmakefile @@ -35,6 +35,7 @@ cairo_OBJC_FILES = CairoSurface.m \ CairoContext.m \ CairoFontEnumerator.m \ CairoFaceInfo.m \ + CairoPSSurface.m \ XGCairoSurface.m \ XGCairoXImageSurface.m diff --git a/Source/cairo/XGCairoSurface.m b/Source/cairo/XGCairoSurface.m index 5e87608..7f0a47a 100644 --- a/Source/cairo/XGCairoSurface.m +++ b/Source/cairo/XGCairoSurface.m @@ -20,6 +20,8 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "x11/XGServer.h" +#include "x11/XGServerWindow.h" #include "cairo/XGCairoSurface.h" #include diff --git a/Source/cairo/XGCairoXImageSurface.m b/Source/cairo/XGCairoXImageSurface.m index d74f8f9..10934bc 100644 --- a/Source/cairo/XGCairoXImageSurface.m +++ b/Source/cairo/XGCairoXImageSurface.m @@ -20,6 +20,9 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "x11/XGServer.h" +#include "x11/XGServerWindow.h" +#include "x11/XWindowBuffer.h" #include "cairo/XGCairoXImageSurface.h" #define GSWINDEVICE ((gswindow_device_t *)gsDevice) @@ -29,7 +32,6 @@ - (id) initWithDevice: (void *)device { struct XWindowBuffer_depth_info_s di; - XWindowBuffer *new_wi; gsDevice = device; @@ -37,25 +39,23 @@ di.bytes_per_pixel = 4; di.inline_alpha = YES; di.inline_alpha_ofs = 0; - new_wi = [XWindowBuffer windowBufferForWindow: GSWINDEVICE depthInfo: &di]; - if (new_wi != wi) - { - DESTROY(wi); - wi = new_wi; - } - else - { - DESTROY(new_wi); - } + // This method is somewhat special as it does not return an autoreleased object + wi = [XWindowBuffer windowBufferForWindow: GSWINDEVICE depthInfo: &di]; _surface = cairo_image_surface_create_for_data((unsigned char*)wi->data, CAIRO_FORMAT_ARGB32, - wi->sx, wi->sy, + wi->sx, wi->sy, wi->bytes_per_line); return self; } +- (void) dealloc +{ + DESTROY(wi); + [super dealloc]; +} + - (NSSize) size { return GSWINDEVICE->xframe.size;