tuxpaint-pencil-sharpener/src/macosx_print.m
2007-06-16 18:40:53 +00:00

292 lines
7.8 KiB
Objective-C

//
// macosx_print.m
// Tux Paint
//
// Created by Darrell Walisser on Sat Mar 15 2003.
// Copyright (c) 2003 Darrell Walisser.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
// $Id$
//
#import "macosx_print.h"
#import "wrapperdata.h"
#import <Cocoa/Cocoa.h>
extern WrapperData macosx;
// this object presents the image to the printing layer
@interface ImageView : NSView
{
NSImage* _image;
}
- (void) setImage:(NSImage*)image;
@end
@implementation ImageView
- (void) setImage:(NSImage*)image
{
_image = [ image retain ];
}
- (void) drawRect:(NSRect)rect
{
[ _image compositeToPoint: NSMakePoint( 0, 0 ) operation: NSCompositeCopy ];
}
- (BOOL) scalesWhenResized
{
return YES;
}
@end
// this object waits for the print dialog to go away
@interface ModalDelegate : NSObject
{
BOOL _complete;
BOOL _wasOK;
}
- (id) init;
- (BOOL) wait;
- (void) reset;
- (BOOL) wasOK;
@end
@implementation ModalDelegate
- (id) init
{
self = [ super init ];
_complete = NO;
_wasOK = NO;
return self;
}
- (BOOL) wait
{
while (!_complete) {
NSEvent *event;
event = [ NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[ NSDate distantFuture ]
inMode: NSDefaultRunLoopMode dequeue:YES ];
[ NSApp sendEvent:event ];
}
return [ self wasOK ];
}
- (void) reset
{
_complete = NO;
_wasOK = NO;
}
- (BOOL) wasOK
{
return _wasOK;
}
- (void)printDidRun:(NSPrintOperation *)printOperation
success:(BOOL)success contextInfo:(void *)contextInfo
{
_complete = YES;
_wasOK = success;
}
- (void)pageLayoutEnded:(NSPageLayout *)pageLayout
returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
_complete = YES;
_wasOK = returnCode == NSOKButton;
}
@end
static NSImage* CreateImage( SDL_Surface *surface )
{
NSBitmapImageRep* imageRep;
NSSize imageSize;
NSImage* image;
SDL_Surface* surface32RGBA;
// convert surface to 32bit RGBA
#ifdef BIG_ENDIAN_ARCH
surface32RGBA = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h,
32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0 );
#else
surface32RGBA = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h,
32, 0xff<<0, 0xff<<8, 0xff<<16, 0xff<<24 );
#endif
if( surface32RGBA == NULL ) {
NSLog (@"CreateImage: Cannot allocate conversion surface");
return nil;
}
SDL_BlitSurface( surface, NULL, surface32RGBA, NULL );
// convert surface to an NSBitmapImageRep
imageRep = [ [ NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&surface32RGBA->pixels
pixelsWide:surface->w
pixelsHigh:surface->h
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:surface->w * 4
bitsPerPixel:32 ];
if( imageRep == nil ) {
NSLog (@"CreateImage: Could not create image representation.");
return nil;
}
imageSize = NSMakeSize( surface->w, surface->h );
image = [ [ NSImage alloc ] initWithSize:imageSize ];
if( image == nil ) {
NSLog (@"CreateImage: Could not allocate image");
return nil;
}
[ image addRepresentation:imageRep ];
[ image setScalesWhenResized:YES ];
[ image setDataRetained:YES ];
[ image autorelease ];
[ imageRep release ];
free( surface32RGBA );
return image;
}
BOOL DisplayPageSetup()
{
NSPageLayout* pageLayout;
NSPrintInfo* printInfo;
ModalDelegate* delegate;
BOOL result;
macosx.cocoaKeystrokes = 1;
printInfo = [ NSPrintInfo sharedPrintInfo ];
delegate = [ [ [ ModalDelegate alloc ] init ] autorelease ];
pageLayout = [ NSPageLayout pageLayout ];
[ pageLayout beginSheetWithPrintInfo:printInfo
modalForWindow:[ NSApp mainWindow ]
delegate:delegate
didEndSelector:@selector(pageLayoutEnded:returnCode:contextInfo:)
contextInfo:nil ];
result = [ delegate wait ];
macosx.cocoaKeystrokes = 0;
return result;
}
void DefaultPrintSettings( SDL_Surface *surface )
{
NSPrintInfo* printInfo = [ NSPrintInfo sharedPrintInfo ];
if( surface->w > surface->h )
[ printInfo setOrientation:NSLandscapeOrientation ];
else
[ printInfo setOrientation:NSPortraitOrientation ];
[ printInfo setHorizontallyCentered:true ];
[ printInfo setVerticallyCentered:true ];
[ printInfo setVerticalPagination:NSFitPagination ];
[ printInfo setHorizontalPagination:NSFitPagination ];
}
const char* SurfacePrint( SDL_Surface *surface, int showDialog )
{
NSImage* image;
ImageView* printView;
NSWindow* printWindow;
NSPrintOperation* printOperation;
NSPrintInfo* printInfo;
ModalDelegate* delegate;
static BOOL firstTime = YES;
BOOL ok = YES;
const char* error = NULL;
// create image for surface
image = CreateImage( surface );
if( image == nil )
return "Could not create image";
if( firstTime == YES ) {
DefaultPrintSettings( surface );
firstTime = NO;
}
// create print control objects
printInfo = [ NSPrintInfo sharedPrintInfo ];
NSRect pageRect = [ printInfo imageablePageBounds ];
NSSize pageSize = pageRect.size;
NSPoint pageOrigin = pageRect.origin;
[ printInfo setTopMargin:pageOrigin.y ];
[ printInfo setLeftMargin:pageOrigin.x ];
[ printInfo setRightMargin:pageOrigin.x ];
[ printInfo setBottomMargin:pageOrigin.y ];
float surfaceRatio = (float)( surface->w ) / (float)( surface->h );
float pageRatio = pageSize.width / pageSize.height;
NSSize imageSize = pageSize;
if( pageRatio > surfaceRatio ) // wide page
{
imageSize.width = surface->w * pageSize.height / surface->h;
}
else // tall page
{
imageSize.height = surface->h * pageSize.width / surface->w;
}
// create print view
printView = [ [ [ ImageView alloc ] initWithFrame: NSMakeRect( 0, 0, imageSize.width, imageSize.height ) ] autorelease ];
if (printView == nil)
return "Could not create print view";
[ image setSize:imageSize ];
[ printView setImage:image ];
// run printing
printOperation = [ NSPrintOperation printOperationWithView:printView printInfo:printInfo ];
[ printOperation setShowPanels:showDialog ];
macosx.cocoaKeystrokes = 1;
delegate = [ [ [ ModalDelegate alloc ] init ] autorelease ];
[ printOperation runOperationModalForWindow:[ NSApp mainWindow ]
delegate:delegate didRunSelector:@selector(printDidRun:success:contextInfo:) contextInfo:nil ];
ok = [ delegate wait ];
if (!ok)
error = "Canceled or error when printing";
macosx.cocoaKeystrokes = 0;
[ image release ];
return error;
}