diff options
-rw-r--r-- | library/print.tcl | 31 | ||||
-rw-r--r-- | macosx/tkMacOSXImage.c | 60 | ||||
-rw-r--r-- | macosx/tkMacOSXImage.h | 25 | ||||
-rw-r--r-- | macosx/tkMacOSXPrint.c | 65 | ||||
-rw-r--r-- | unix/Makefile.in | 2 | ||||
-rwxr-xr-x | unix/configure | 2 | ||||
-rw-r--r-- | unix/configure.ac | 2 |
7 files changed, 161 insertions, 26 deletions
diff --git a/library/print.tcl b/library/print.tcl index 85383c5..0879d72 100644 --- a/library/print.tcl +++ b/library/print.tcl @@ -24,15 +24,24 @@ namespace eval ::tk::print { # Full filename for created file # proc makeTempFile {filename {contents ""}} { - set f [file tempfile filename $filename] + set dumpfile [file join /tmp rawprint.txt] + set tmpfile [file join /tmp $filename] + set f [open $dumpfile w] try { puts -nonewline $f $contents - return $filename } finally { close $f + if {[file extension $filename] == ".ps"} { + #don't apply formatting to PostScript + file rename -force $dumpfile $tmpfile + } else { + #Make text fixed width for improved printed output + exec fmt -w 75 $dumpfile > $tmpfile + } + return $tmpfile } } - + if {[tk windowingsystem] eq "win32"} { variable printer_name variable copies @@ -957,16 +966,10 @@ proc ::tk::print {w} { tailcall ::tk::print::_print $w } "Canvas,aqua" { - set psfile [::tk::print::makeTempFile tk_canvas.ps] - try { - $w postscript -file $psfile - set printfile [::tk::print::makePDF $psfile tk_canvas.pdf] - ::tk::print::_print $printfile - } finally { - file delete $psfile - } - } - + ::tk::print::_printcanvas $w + set printfile /tmp/tk_canvas.pdf + ::tk::print::_print $printfile + } "Text,win32" { tailcall ::tk::print::_print_data [$w get 1.0 end] 1 {Arial 12} } @@ -976,7 +979,7 @@ proc ::tk::print {w} { "Text,aqua" { set txtfile [::tk::print::makeTempFile tk_text.txt [$w get 1.0 end]] try { - set printfile [::tk::print::makePDF $txtfile tk_text.pdf] + set printfile [::tk::print::makePDF $txtfile [file join /tmp tk_text.pdf]] ::tk::print::_print $printfile } finally { file delete $txtfile diff --git a/macosx/tkMacOSXImage.c b/macosx/tkMacOSXImage.c index 34538b6..8d352b2 100644 --- a/macosx/tkMacOSXImage.c +++ b/macosx/tkMacOSXImage.c @@ -15,13 +15,10 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXConstants.h" +#include "tkMacOSXImage.h" #include "tkColor.h" #include "xbytes.h" -static CGImageRef CreateCGImageFromPixmap(Drawable pixmap); -static CGImageRef CreateCGImageFromDrawableRect( Drawable drawable, - int x, int y, unsigned int width, unsigned int height); - /* Pixel formats * * Tk uses the XImage structure defined in Xlib.h for storing images. The @@ -628,7 +625,7 @@ int TkpPutRGBAImage( *---------------------------------------------------------------------- */ -static CGImageRef +CGImageRef CreateCGImageFromDrawableRect( Drawable drawable, int x, @@ -673,6 +670,57 @@ CreateCGImageFromDrawableRect( } return result; } + +/* + *---------------------------------------------------------------------- + * + * CreatePDFFromDrawableRect + * + * Extract PDF data from a MacOSX drawable. + * + * Results: + * Returns a CFDataRef that can be written to a file. + * + * NOTE: The x,y coordinates should be relative to a coordinate system + * with origin at the bottom left as used by NSView, not top left + * as used by XImage and CGImage. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +CFDataRef +CreatePDFFromDrawableRect( + Drawable drawable, + int x, + int y, + unsigned int width, + unsigned int height) +{ + MacDrawable *mac_drawable = (MacDrawable *)drawable; + NSView *view = TkMacOSXGetNSViewForDrawable(mac_drawable); + if (view == nil) { + TkMacOSXDbgMsg("Invalid source drawable"); + return NULL; + } + NSRect bounds, viewSrcRect; + + /* + * Get the child window area in NSView coordinates + * (origin at bottom left). + */ + + bounds = [view bounds]; + viewSrcRect = NSMakeRect(mac_drawable->xOff + x, + bounds.size.height - height - (mac_drawable->yOff + y), + width, height); + NSData *viewData = [view dataWithPDFInsideRect:viewSrcRect]; + CFDataRef result = (CFDataRef)viewData; + return result; +} + /* *---------------------------------------------------------------------- @@ -690,7 +738,7 @@ CreateCGImageFromDrawableRect( *---------------------------------------------------------------------- */ -static CGImageRef +CGImageRef CreateCGImageFromPixmap( Drawable pixmap) { diff --git a/macosx/tkMacOSXImage.h b/macosx/tkMacOSXImage.h new file mode 100644 index 0000000..7dcb50e --- /dev/null +++ b/macosx/tkMacOSXImage.h @@ -0,0 +1,25 @@ +/* + * tkMacOSXImage.h -- + * + * + * The code in this file provides an interface for XImages, and + * implements the nsimage image type. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 2001-2009, Apple Inc. + * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2017-2021 Marc Culler. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +/* + * Function prototypes + */ + +CGImageRef CreateCGImageFromPixmap(Drawable pixmap); +CGImageRef CreateCGImageFromDrawableRect( Drawable drawable, + int x, int y, unsigned int width, unsigned int height); +CFDataRef CreatePDFFromDrawableRect( Drawable drawable, + int x, int y, unsigned int width, unsigned int height); diff --git a/macosx/tkMacOSXPrint.c b/macosx/tkMacOSXPrint.c index 3ebfa29..727d617 100644 --- a/macosx/tkMacOSXPrint.c +++ b/macosx/tkMacOSXPrint.c @@ -22,13 +22,18 @@ #include <unistd.h> #include <stdio.h> #include <fcntl.h> +#include <tkMacOSXImage.h> +#include "tkMacOSXPrivate.h" -/* Forward declarations of functions and variables. */ NSString * fileName = nil; CFStringRef urlFile = NULL; + +/*Forward declaration of functions.*/ int StartPrint(void *clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const objv[]); -OSStatus FinishPrint(NSString *file, int buttonValue); +OSStatus FinishPrint(NSString *file, int buttonValue); +int MakePDF(void *clientData, Tcl_Interp *ip, + int objc, Tcl_Obj *const objv[]); int MacPrint_Init(Tcl_Interp * interp); /* Delegate class for print dialogs. */ @@ -237,7 +242,7 @@ FinishPrint( NSFileManager * fileManager = [NSFileManager defaultManager]; NSError * error = nil; - /* + /* * Is the target file a PDF? If so, copy print file * to output location. */ @@ -326,6 +331,59 @@ FinishPrint( return status; } + +/* + *---------------------------------------------------------------------- + * + * MakePDF-- + * + * Converts a Tk canvas to PDF data. + * + * Results: + * Outputs PDF file. + * + *---------------------------------------------------------------------- + */ + +int MakePDF +(void *clientData, + Tcl_Interp *ip, + int objc, + Tcl_Obj *const objv[]) +{ + Tk_Window path; + Drawable d = NULL; + int x, y; + unsigned int width, height; + CFDataRef pdfData; + + if (objc != 2) { + Tcl_WrongNumArgs(ip, 1, objv, "path?"); + return TCL_ERROR; + } + + /*Get window and render to PDF.*/ + + path = Tk_NameToWindow(ip, Tcl_GetString(objv[1]), Tk_MainWindow(ip)); + if (path == NULL) { + return TCL_ERROR; + } + + Tk_MakeWindowExist(path); + Tk_MapWindow(path); + d = Tk_WindowId(path); + width = Tk_Width(path); + height = Tk_Height(path); + MacDrawable *mac_drawable = (MacDrawable *)d; + + pdfData = CreatePDFFromDrawableRect(mac_drawable, 0, 0, width, height); + + NSData *viewData = (NSData*)pdfData; + [viewData writeToFile:@"/tmp/tk_canvas.pdf" atomically:YES]; + return TCL_OK; + +} + /* *---------------------------------------------------------------------- * @@ -342,6 +400,7 @@ FinishPrint( int MacPrint_Init(Tcl_Interp * interp) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Tcl_CreateObjCommand(interp, "::tk::print::_print", StartPrint, NULL, NULL); + Tcl_CreateObjCommand(interp, "::tk::print::_printcanvas", MakePDF, NULL, NULL); [pool release]; return TCL_OK; } diff --git a/unix/Makefile.in b/unix/Makefile.in index a9651ac..9fce557 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1402,7 +1402,7 @@ tkMacOSXFont.o: $(MAC_OSX_DIR)/tkMacOSXFont.c tkMacOSXHLEvents.o: $(MAC_OSX_DIR)/tkMacOSXHLEvents.c $(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXHLEvents.c -tkMacOSXImage.o: $(MAC_OSX_DIR)/tkMacOSXImage.c +tkMacOSXImage.o: $(MAC_OSX_DIR)/tkMacOSXImage.c $(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXImage.c tkMacOSXInit.o: $(MAC_OSX_DIR)/tkMacOSXInit.c tkConfig.sh diff --git a/unix/configure b/unix/configure index dd73d5c..065c0bf 100755 --- a/unix/configure +++ b/unix/configure @@ -7652,7 +7652,7 @@ if test $tk_aqua = yes; then printf "%s\n" "#define MAC_OSX_TK 1" >>confdefs.h - LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore -framework Security" + LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore -framework Security -framework CoreGraphics" if test -d /System/Library/Frameworks/UserNotifications.framework; then LIBS="$LIBS -framework UserNotifications" fi diff --git a/unix/configure.ac b/unix/configure.ac index a81c527..38eda9d 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -284,7 +284,7 @@ fi if test $tk_aqua = yes; then AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?]) - LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore -framework Security" + LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore -framework Security -framework CoreGraphics" if test -d /System/Library/Frameworks/UserNotifications.framework; then LIBS="$LIBS -framework UserNotifications" fi |