diff --git a/ChangeLog b/ChangeLog index 5d6dba38e..7dee37a67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-06-26 Eric Wasylishen + + * Source/GSGhostscriptImageRep.m: + * Headers/Additions/GNUstepGUI/GSGhostscriptImageRep.h: + * Source/GNUmakefile: + * Source/NSImageRep.m: New image rep which attempts to + invoke Ghostscript to rasterize PS/EPS/PDF images. It needs + some polishing but basically works. + 2011-06-26 Wolfgang Lux * Source/NSTextView_actions.m (-deleteToEndOfParagraph:): diff --git a/Headers/Additions/GNUstepGUI/GSGhostscriptImageRep.h b/Headers/Additions/GNUstepGUI/GSGhostscriptImageRep.h new file mode 100644 index 000000000..90d4c0a71 --- /dev/null +++ b/Headers/Additions/GNUstepGUI/GSGhostscriptImageRep.h @@ -0,0 +1,46 @@ +/* + GSGhostscriptImageRep.h + + Ghostscript image representation. + + Copyright (C) 2011 Free Software Foundation, Inc. + + Written by: Eric Wasylishen + Date: June 2011 + + This file is part of the GNUstep GUI Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _GNUstep_H_GSGhostscriptImageRep +#define _GNUstep_H_GSGhostscriptImageRep + +#import + +@class NSData; + +@interface GSGhostscriptImageRep : NSImageRep +{ + NSBitmapImageRep *_bitmap; + NSData *_psData; +} + +@end + +#endif // _GNUstep_H_GSGhostscriptImageRep + diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 9cf76564a..94c82fead 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -212,6 +212,7 @@ GSTextFinder.m \ GSLayoutManager.m \ GSTypesetter.m \ GSHorizontalTypesetter.m \ +GSGhostscriptImageRep.m \ GSGormLoading.m \ GSIconManager.m \ GSNibLoading.m \ diff --git a/Source/GSGhostscriptImageRep.m b/Source/GSGhostscriptImageRep.m new file mode 100644 index 000000000..efc2f8767 --- /dev/null +++ b/Source/GSGhostscriptImageRep.m @@ -0,0 +1,202 @@ +/** GSGhostscriptImageRep + + Ghostscript image representation. + + Copyright (C) 2011 Free Software Foundation, Inc. + + Author: Eric Wasylishen + Date: June 2011 + + This file is part of the GNUstep Application Kit Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#import +#import +#import +#import +#import +#import "AppKit/NSImageRep.h" +#import "AppKit/NSPasteboard.h" +#import "AppKit/NSGraphicsContext.h" +#import "GNUstepGUI/GSGhostscriptImageRep.h" + +@implementation GSGhostscriptImageRep + ++ (BOOL) canInitWithData: (NSData *)data +{ + char buf[4]; + + if ([data length] < 4) + { + return NO; + } + + [data getBytes: buf length: 4]; + + // Simple check for PostScript or EPS, Windows EPS, PDF + + if ((buf[0] == '%' && buf[1] == '!' && buf[2] == 'P' && buf[3] == 'S') || + (buf[0] == '\xc5' && buf[1] == '\xd0' && buf[2] == '\xd3' && buf[3] == '\xc6') || + (buf[0] == '%' && buf[1] == 'P' && buf[2] == 'D' && buf[3] == 'F')) + { + return YES; + } + else + { + return NO; + } +} + ++ (NSArray *) imageUnfilteredFileTypes +{ + static NSArray *types = nil; + + if (types == nil) + { + types = [[NSArray alloc] initWithObjects: @"ps", @"eps", @"pdf", nil]; + } + + return types; +} + ++ (NSArray *) imageUnfilteredPasteboardTypes +{ + static NSArray *types = nil; + + if (types == nil) + { + types = [[NSArray alloc] initWithObjects: NSPostScriptPboardType, + NSPDFPboardType, + nil]; + } + + return types; +} + +- (NSData *) _pngWithGhostscriptData: (NSData *)psData atResolution: (CGFloat)res +{ + NSTask *task = [[[NSTask alloc] init] autorelease]; + NSPipe *inputPipe = [NSPipe pipe]; + NSPipe *outputPipe = [NSPipe pipe]; + NSFileHandle *inputHandle = [inputPipe fileHandleForWriting]; + NSFileHandle *outputHandle = [outputPipe fileHandleForReading]; + NSData *result; + + // FIXME: Parameterize + [task setLaunchPath: @"/usr/bin/gs"]; + [task setArguments: [NSArray arrayWithObjects: @"-dSAFER", + @"-q", + @"-o", + @"-", // Write output image to stdout + @"-sDEVICE=pngalpha", + [NSString stringWithFormat: @"-r%d", (int)res], + @"-dTextAlphaBits=4", + @"-dGraphicsAlphaBits=4", + @"-dDOINTERPOLATE", + @"-", // Read input from stdin + nil]]; + [task setStandardInput: inputPipe]; + [task setStandardOutput: outputPipe]; + [task launch]; + + [inputHandle writeData: psData]; + [inputHandle closeFile]; + + result = [outputHandle readDataToEndOfFile]; + [outputHandle closeFile]; + + return result; +} + + + +// Initializing a New Instance ++ (id) imageRepWithData: (NSData *)psData +{ + return AUTORELEASE([[self alloc] initWithData: psData]); +} + +- (id) initWithData: (NSData *)psData +{ + NSData *pngData; + + ASSIGN(_psData, psData); + + pngData = [self _pngWithGhostscriptData: _psData atResolution: 72.0]; + + if (pngData == nil) + { + [self release]; + return nil; + } + + _bitmap = [NSBitmapImageRep imageRepWithData: pngData]; + + [self setSize: [_bitmap size]]; + [self setAlpha: [_bitmap hasAlpha]]; + [self setBitsPerSample: NSImageRepMatchesDevice]; + [self setPixelsWide: NSImageRepMatchesDevice]; + [self setPixelsHigh: NSImageRepMatchesDevice]; + // FIXME: Other properties? + + return self; +} + +// Drawing the Image +- (BOOL) draw +{ + if (_bitmap != nil) + { + // FIXME: Re-cache at a higher resolution if needed + + return [_bitmap draw]; + } + return NO; +} + +// NSCopying protocol +- (id) copyWithZone: (NSZone *)zone +{ + GSGhostscriptImageRep *copy = [super copyWithZone: zone]; + + copy->_psData = [_psData copyWithZone: zone]; + copy->_bitmap = [_bitmap copyWithZone: zone]; + + return copy; +} + +// NSCoding protocol +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + // FIXME: + [super encodeWithCoder: aCoder]; + [_psData encodeWithCoder: aCoder]; +} + +- (id) initWithCoder: (NSCoder*)aDecoder +{ + // FIXME: + NSData *data; + + self = [super initWithCoder: aDecoder]; + data = [aDecoder decodeObject]; + return [self initWithData: data]; +} + +@end diff --git a/Source/NSImageRep.m b/Source/NSImageRep.m index d6bc530db..98a11953b 100644 --- a/Source/NSImageRep.m +++ b/Source/NSImageRep.m @@ -44,6 +44,7 @@ #import "AppKit/NSView.h" #import "AppKit/NSColor.h" #import "AppKit/DPSOperators.h" +#import "GNUstepGUI/GSGhostscriptImageRep.h" static NSMutableArray *imageReps = nil; static Class NSImageRep_class = NULL; @@ -59,7 +60,7 @@ static Class NSImageRep_class = NULL; NSImageRep_class = self; imageReps = [[NSMutableArray alloc] initWithCapacity: 2]; [imageReps addObject: [NSBitmapImageRep class]]; - //[imageReps addObject: [NSEPSImageRep class]]; + [imageReps addObject: [GSGhostscriptImageRep class]]; } }