Re-add print dialog access to macOS.

Ability to bring up the print dialog from the macOS build was removed in
Tux Paint 0.9.23 to support the new build mechanism.  It has been re-added.
To access it, option-click the print icon, or configure Tux Paint to always
bring up the dialog upon print.
This commit is contained in:
Mark Kim 2018-09-28 23:24:56 -04:00
parent 33de9841c0
commit be99eb3844
5 changed files with 411 additions and 9 deletions

View file

@ -90,7 +90,7 @@ linux_BUNDLE:=
BUNDLE:=$($(OS)_BUNDLE)
windows_ARCH_LIBS:=obj/win32_print.o obj/resource.o
osx_ARCH_LIBS:=obj/postscript_print.o obj/macos.o
osx_ARCH_LIBS:=src/macos_print.m obj/macos.o
beos_ARCH_LIBS:=obj/BeOS_print.o
linux_ARCH_LIBS:=obj/postscript_print.o
ARCH_LIBS:=$($(OS)_ARCH_LIBS)
@ -116,7 +116,7 @@ FRIBIDI_LIB:=$(shell $(PKG_CONFIG) --libs fribidi)
FRIBIDI_CFLAGS:=$(shell $(PKG_CONFIG) --cflags fribidi)
windows_ARCH_LINKS:=-lintl $(PNG) -lzdll -lwinspool -lshlwapi $(FRIBIDI_LIB) -liconv
osx_ARCH_LINKS:=$(PAPER_LIB) $(FRIBIDI_LIB)
osx_ARCH_LINKS:=$(FRIBIDI_LIB)
beos_ARCH_LINKS:=-lintl $(PNG) -lz -lbe -lnetwork -liconv $(FRIBIDI_LIB) $(PAPER_LIB) $(STDC_LIB)
linux_ARCH_LINKS:=$(PAPER_LIB) $(FRIBIDI_LIB)
ARCH_LINKS:=$($(OS)_ARCH_LINKS)

View file

@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>tuxpaint</string>
<key>CFBundleGetInfoString</key>
<string>0.9.23a, Copyright 2009-2018, Tux Paint Development Team</string>
<string>0.9.23b, Copyright 2009-2018, Tux Paint Development Team</string>
<key>CFBundleIconFile</key>
<string>tuxpaint.icns</string>
<key>CFBundleIdentifier</key>
@ -19,10 +19,10 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.9.23a</string>
<string>0.9.23b</string>
<key>CFBundleSignature</key>
<string>TXPT</string>
<key>CFBundleVersion</key>
<string>2018-09-24</string>
<string>2018-09-28</string>
</dict>
</plist>

40
src/macos_print.h Normal file
View file

@ -0,0 +1,40 @@
//
// macosx_print.h
// Tux Paint
//
// Created by Darrell Walisser on Sat Mar 15 2003.
// Modified by Martin Fuhrer 2007.
// Copyright (c) 2007 Darrell Walisser, Martin Fuhrer. All rights reserved.
// $Id$
//
// 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)
//
#include "SDL.h"
const char *SurfacePrint(SDL_Surface * surface, int showDialog);
int DisplayPageSetup(const SDL_Surface * surface);
#ifdef OBJECTIVEC
@interface PrintSheetController:NSObject
{
bool displayPrintSetupSheet;
bool displayPrintSheet;
}
-@end
#endif /* OBJECTIVEC */

330
src/macos_print.m Normal file
View file

@ -0,0 +1,330 @@
//
// macos_print.m
// Tux Paint
//
// Created by Darrell Walisser on Sat Mar 15 2003.
// Modified by Martin Fuhrer 2007.
// Modified by Mark Kim 2018.
// Copyright (c) 2018 Darrell Walisser, Martin Fuhrer, Mark Kim.
//
// 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 "macos_print.h"
#import <Cocoa/Cocoa.h>
struct {
int cocoaKeystrokes; // should keystrokes be intercepted by Cocoa wrapper?
} macos;
NSData* printData = nil;
// 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;
}
void DefaultPrintSettings( const SDL_Surface *surface, NSPrintInfo *printInfo )
{
if( surface->w > surface->h )
[ printInfo setOrientation:NSLandscapeOrientation ];
else
[ printInfo setOrientation:NSPortraitOrientation ];
[ printInfo setHorizontallyCentered:true ];
[ printInfo setVerticallyCentered:true ];
[ printInfo setVerticalPagination:NSFitPagination ];
[ printInfo setHorizontalPagination:NSFitPagination ];
}
NSPrintInfo* LoadPrintInfo( const SDL_Surface *surface )
{
NSUserDefaults* standardUserDefaults;
NSPrintInfo* printInfo;
NSData* printData = nil;
static BOOL firstTime = YES;
standardUserDefaults = [ NSUserDefaults standardUserDefaults ];
if( standardUserDefaults )
printData = [ standardUserDefaults dataForKey:@"PrintInfo" ];
if( printData )
printInfo = (NSPrintInfo*)[ NSUnarchiver unarchiveObjectWithData:printData ];
else
{
printInfo = [ NSPrintInfo sharedPrintInfo ];
if( firstTime == YES )
{
DefaultPrintSettings( surface, printInfo );
firstTime = NO;
}
}
return printInfo;
}
void SavePrintInfo( NSPrintInfo* printInfo )
{
NSUserDefaults* standardUserDefaults;
NSData* printData = nil;
printData = [ NSArchiver archivedDataWithRootObject:printInfo ];
standardUserDefaults = [ NSUserDefaults standardUserDefaults ];
if( standardUserDefaults )
[ standardUserDefaults setObject:printData forKey:@"PrintInfo" ];
}
int DisplayPageSetup( const SDL_Surface * surface )
{
NSPageLayout* pageLayout;
NSPrintInfo* printInfo;
ModalDelegate* delegate;
BOOL result;
macos.cocoaKeystrokes = 1;
printInfo = LoadPrintInfo( surface );
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 ];
SavePrintInfo( printInfo );
macos.cocoaKeystrokes = 0;
return (int)( result );
}
const char* SurfacePrint( SDL_Surface *surface, int showDialog )
{
NSImage* image;
ImageView* printView;
NSWindow* printWindow;
NSPrintOperation* printOperation;
NSPrintInfo* printInfo;
ModalDelegate* delegate;
BOOL ok = YES;
// check if printers are available
NSArray* printerNames = [NSPrinter printerNames];
if( [printerNames count] == 0 && !showDialog)
return "No printer is available. Run Tux Paint in window mode (not fullscreen), and select File > Print... to choose a printer.";
// create image for surface
image = CreateImage( surface );
if( image == nil )
return "Could not create a print image.";
// create print control objects
printInfo = LoadPrintInfo( surface );
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 a print view.";
[ image setSize:imageSize ];
[ printView setImage:image ];
// run printing
printOperation = [ NSPrintOperation printOperationWithView:printView printInfo:printInfo ];
[ printOperation setShowsPrintPanel:showDialog ]; //EP replaced setShowPanels by setShowsPrintPanel
macos.cocoaKeystrokes = 1;
delegate = [ [ [ ModalDelegate alloc ] init ] autorelease ];
[ printOperation runOperationModalForWindow:[ NSApp mainWindow ]
delegate:delegate didRunSelector:@selector(printDidRun:success:contextInfo:) contextInfo:nil ];
ok = [ delegate wait ];
macos.cocoaKeystrokes = 0;
SavePrintInfo( printInfo );
[ image release ];
return NULL;
}

View file

@ -298,10 +298,22 @@ typedef struct safer_dirent
#else /* __BEOS__ */
/* Not Windows, not BeOS */
/* Not BeOS */
#ifdef __APPLE__
/* Apple */
#include "macos_print.h"
#else /* __APPLE__ */
/* Not Windows, not BeOS, not Apple */
#include "postscript_print.h"
#endif /* __APPLE__ */
#endif /* __BEOS__ */
#else /* WIN32 */
@ -1356,7 +1368,7 @@ enum
static magic_api *magic_api_struct; /* Pointer to our internal functions; passed to shared object's functions when we call them */
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__HAIKU__)
#if !defined(WIN32) && !defined(__APPLE__) && !defined(__BEOS__) && !defined(__HAIKU__)
#include <paper.h>
#if !defined(PAPER_H)
#error "---------------------------------------------------"
@ -2555,6 +2567,14 @@ static void mainloop(void)
magic_switchin(canvas);
}
#ifdef __APPLE__
else if (key == SDLK_p && (mod & KMOD_CTRL) && (mod & KMOD_SHIFT) && !noshortcuts)
{
/* Ctrl-Shft-P - Page Setup */
if (!disable_print)
DisplayPageSetup(canvas);
}
#endif
else if (key == SDLK_p && (mod & KMOD_CTRL) && !noshortcuts)
{
/* Ctrl-P - Print */
@ -16293,7 +16313,7 @@ void do_print(void)
SDL_BlitSurface(canvas, NULL, save_canvas, NULL);
SDL_BlitSurface(label, NULL, save_canvas, NULL);
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__HAIKU__)
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__APPLE__) && !defined(__HAIKU__)
const char *pcmd;
FILE *pi;
@ -16345,6 +16365,18 @@ void do_print(void)
/* BeOS */
SurfacePrint(save_canvas);
#elif defined(__APPLE__)
/* Mac OS X */
int show = (want_alt_printcommand && !fullscreen);
const char *error = SurfacePrint(save_canvas, show);
if (error)
{
fprintf(stderr, "Cannot print: %s\n", error);
do_prompt_snd(error, PROMPT_PRINT_YES, "", SND_TUXOK, 0, 0);
}
#endif
#endif
@ -22100,7 +22132,7 @@ void load_embedded_data(char *fname, SDL_Surface * org_surf)
/* ================================================================================== */
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__HAIKU__)
#if !defined(WIN32) && !defined(__APPLE__) && !defined(__BEOS__) && !defined(__HAIKU__)
/**
* FIXME
*/