diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2017-10-17 19:50:58 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2017-10-17 19:50:58 (GMT) |
commit | 9b7a6c3507ea3383c60aaecb29f873c9b590ccca (patch) | |
tree | 82ce31ebd8f46803d969034f5aa3db8d7974493c /tk8.6/macosx/tkMacOSXDraw.c | |
parent | 87fca7325b97005eb44dcf3e198277640af66115 (diff) | |
download | blt-9b7a6c3507ea3383c60aaecb29f873c9b590ccca.zip blt-9b7a6c3507ea3383c60aaecb29f873c9b590ccca.tar.gz blt-9b7a6c3507ea3383c60aaecb29f873c9b590ccca.tar.bz2 |
rm tcl/tk 8.6.7
Diffstat (limited to 'tk8.6/macosx/tkMacOSXDraw.c')
-rw-r--r-- | tk8.6/macosx/tkMacOSXDraw.c | 2103 |
1 files changed, 0 insertions, 2103 deletions
diff --git a/tk8.6/macosx/tkMacOSXDraw.c b/tk8.6/macosx/tkMacOSXDraw.c deleted file mode 100644 index 5ca8bfe..0000000 --- a/tk8.6/macosx/tkMacOSXDraw.c +++ /dev/null @@ -1,2103 +0,0 @@ -/* - * tkMacOSXDraw.c -- - * - * This file contains functions that perform drawing to - * Xlib windows. Most of the functions simple emulate - * Xlib functions. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright 2001-2009, Apple Inc. - * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net> - * Copyright 2014 Marc Culler. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkMacOSXPrivate.h" -#include "tkMacOSXDebug.h" -#include "xbytes.h" -#include "tkButton.h" - -/* -#ifdef TK_MAC_DEBUG -#define TK_MAC_DEBUG_DRAWING -#define TK_MAC_DEBUG_IMAGE_DRAWING -#endif -*/ - -#define radians(d) ((d) * (M_PI/180.0)) - -/* - * Non-antialiased CG drawing looks better and more like X11 drawing when using - * very fine lines, so decrease all linewidths by the following constant. - */ -#define NON_AA_CG_OFFSET .999 - -static int cgAntiAliasLimit = 0; -#define notAA(w) ((w) < cgAntiAliasLimit) - -static int useThemedToplevel = 0; -static int useThemedFrame = 0; - -/* - * Prototypes for functions used only in this file. - */ - -static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr); -static CGImageRef CreateCGImageWithXImage(XImage *ximage); -static CGContextRef GetCGContextForDrawable(Drawable d); -static void DrawCGImage(Drawable d, GC gc, CGContextRef context, CGImageRef image, - unsigned long imageForeground, unsigned long imageBackground, - CGRect imageBounds, CGRect srcBounds, CGRect dstBounds); - - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXInitCGDrawing -- - * - * Initializes link vars that control CG drawing. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -MODULE_SCOPE int -TkMacOSXInitCGDrawing( - Tcl_Interp *interp, - int enable, - int limit) -{ - static Boolean initialized = FALSE; - - if (!initialized) { - initialized = TRUE; - - if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) { - Tcl_ResetResult(interp); - } - - if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit", - (char *) &cgAntiAliasLimit, TCL_LINK_INT) != TCL_OK) { - Tcl_ResetResult(interp); - } - cgAntiAliasLimit = limit; - - /* - * Piggy-back the themed drawing var init here. - */ - - if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel", - (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } - if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame", - (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * BitmapRepFromDrawableRect - * - * Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep. - * - * Results: - * Returns an autoreleased NSBitmapRep representing the image of the given - * rectangle of the given drawable. - * - * NOTE: The x,y coordinates should be relative to a coordinate system with - * origin at the top left, as used by XImage and CGImage, not bottom - * left as used by NSView. - * - * Side effects: - * None - * - *---------------------------------------------------------------------- - */ -NSBitmapImageRep* -BitmapRepFromDrawableRect( - Drawable drawable, - int x, - int y, - unsigned int width, - unsigned int height) -{ - MacDrawable *mac_drawable = (MacDrawable *) drawable; - CGContextRef cg_context=NULL; - CGImageRef cg_image=NULL, sub_cg_image=NULL; - NSBitmapImageRep *bitmap_rep=NULL; - NSView *view=NULL; - if ( mac_drawable->flags & TK_IS_PIXMAP ) { - /* - This means that the MacDrawable is functioning as a Tk Pixmap, so its view - field is NULL. - */ - cg_context = GetCGContextForDrawable(drawable); - CGRect image_rect = CGRectMake(x, y, width, height); - cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context); - sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect); - if ( sub_cg_image ) { - /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/ - bitmap_rep = [NSBitmapImageRep alloc]; - [bitmap_rep initWithCGImage:sub_cg_image]; - } - if ( cg_image ) { - CGImageRelease(cg_image); - } - } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) { - /* convert top-left coordinates to NSView coordinates */ - int view_height = [view bounds].size.height; - NSRect view_rect = NSMakeRect(x + mac_drawable->xOff, - view_height - height - y - mac_drawable->yOff, - width,height); - - if ( [view lockFocusIfCanDraw] ) { - /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/ - bitmap_rep = [NSBitmapImageRep alloc]; - bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect]; - [view unlockFocus]; - } else { - TkMacOSXDbgMsg("Could not lock focus on view."); - } - - } else { - TkMacOSXDbgMsg("Invalid source drawable"); - } - return bitmap_rep; -} - -/* - *---------------------------------------------------------------------- - * - * XCopyArea -- - * - * Copies data from one drawable to another. - * - * Results: - * None. - * - * Side effects: - * Data is moved from a window or bitmap to a second window or - * bitmap. - * - *---------------------------------------------------------------------- - */ - -void -XCopyArea( - Display *display, /* Display. */ - Drawable src, /* Source drawable. */ - Drawable dst, /* Destination drawable. */ - GC gc, /* GC to use. */ - int src_x, /* X & Y, width & height */ - int src_y, /* define the source rectangle */ - unsigned int width, /* that will be copied. */ - unsigned int height, - int dest_x, /* Dest X & Y on dest rect. */ - int dest_y) -{ - TkMacOSXDrawingContext dc; - MacDrawable *srcDraw = (MacDrawable *) src; - NSBitmapImageRep *bitmap_rep = NULL; - CGImageRef img = NULL; - - display->request++; - - if (!width || !height) { - /* This happens all the time. - TkMacOSXDbgMsg("Drawing of empty area requested"); - */ - return; - } - - if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { - return; - /*TkMacOSXDbgMsg("Failed to setup drawing context.");*/ - } - - if ( dc.context ) { - if (srcDraw->flags & TK_IS_PIXMAP) { - img = TkMacOSXCreateCGImageWithDrawable(src); - }else if (TkMacOSXDrawableWindow(src)) { - bitmap_rep = BitmapRepFromDrawableRect(src, src_x, src_y, width, height); - if ( bitmap_rep ) { - img = [bitmap_rep CGImage]; - } - } else { - TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap."); - } - - if (img) { - DrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background, - CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), - CGRectMake(src_x, src_y, width, height), - CGRectMake(dest_x, dest_y, width, height)); - CFRelease(img); - - - } else { - TkMacOSXDbgMsg("Failed to construct CGImage."); - } - - } else { - TkMacOSXDbgMsg("Invalid destination drawable - no context."); - return; - } - - TkMacOSXRestoreDrawingContext(&dc); -} - -/* - *---------------------------------------------------------------------- - * - * XCopyPlane -- - * - * Copies a bitmap from a source drawable to a destination - * drawable. The plane argument specifies which bit plane of - * the source contains the bitmap. Note that this implementation - * ignores the gc->function. - * - * Results: - * None. - * - * Side effects: - * Changes the destination drawable. - * - *---------------------------------------------------------------------- - */ - -void -XCopyPlane( - Display *display, /* Display. */ - Drawable src, /* Source drawable. */ - Drawable dst, /* Destination drawable. */ - GC gc, /* GC to use. */ - int src_x, /* X & Y, width & height */ - int src_y, /* define the source rectangle */ - unsigned int width, /* that will be copied. */ - unsigned int height, - int dest_x, /* Dest X & Y on dest rect. */ - int dest_y, - unsigned long plane) /* Which plane to copy. */ -{ - TkMacOSXDrawingContext dc; - MacDrawable *srcDraw = (MacDrawable *) src; - MacDrawable *dstDraw = (MacDrawable *) dst; - - display->request++; - if (!width || !height) { - /* TkMacOSXDbgMsg("Drawing of empty area requested"); */ - return; - } - if (plane != 1) { - Tcl_Panic("Unexpected plane specified for XCopyPlane"); - } - if (srcDraw->flags & TK_IS_PIXMAP) { - if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { - return; - } - CGContextRef context = dc.context; - if (context) { - CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src); - if (img) { - TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; - unsigned long imageBackground = gc->background; - if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){ - CGRect srcRect = CGRectMake(src_x, src_y, width, height); - CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap); - CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect); - CGRect rect = CGRectMake(dest_x, dest_y, width, height); - rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff); - CGContextSaveGState(context); - /* Move the origin of the destination to top left. */ - CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect)); - CGContextScaleCTM(context, 1, -1); - /* Fill with the background color, clipping to the mask. */ - CGContextClipToMask(context, rect, submask); - TkMacOSXSetColorInContext(gc, gc->background, dc.context); - CGContextFillRect(context, rect); - /* Fill with the foreground color, clipping to the - intersection of img and mask. */ - CGImageRef subimage = CGImageCreateWithImageInRect(img, srcRect); - CGContextClipToMask(context, rect, subimage); - TkMacOSXSetColorInContext(gc, gc->foreground, context); - CGContextFillRect(context, rect); - CGContextRestoreGState(context); - CGImageRelease(img); - CGImageRelease(mask); - CGImageRelease(submask); - CGImageRelease(subimage); - } else { - DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground, - CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), - CGRectMake(src_x, src_y, width, height), - CGRectMake(dest_x, dest_y, width, height)); - CGImageRelease(img); - } - } else { /* no image */ - TkMacOSXDbgMsg("Invalid source drawable"); - } - } else { - TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context."); - } - TkMacOSXRestoreDrawingContext(&dc); - } else { /* source drawable is a window, not a Pixmap */ - XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkPutImage -- - * - * Copies a subimage from an in-memory image to a rectangle of - * of the specified drawable. - * - * Results: - * None. - * - * Side effects: - * Draws the image on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -TkPutImage( - unsigned long *colors, /* Unused on Macintosh. */ - int ncolors, /* Unused on Macintosh. */ - Display* display, /* Display. */ - Drawable d, /* Drawable to place image on. */ - GC gc, /* GC to use. */ - XImage* image, /* Image to place. */ - int src_x, /* Source X & Y. */ - int src_y, - int dest_x, /* Destination X & Y. */ - int dest_y, - unsigned int width, /* Same width & height for both */ - unsigned int height) /* distination and source. */ -{ - TkMacOSXDrawingContext dc; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return BadDrawable; - } - if (dc.context) { - CGImageRef img = CreateCGImageWithXImage(image); - - if (img) { - /* If the XImage has big pixels, rescale the source dimensions.*/ - int pp = image->pixelpower; - DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background, - CGRectMake(0, 0, image->width<<pp, image->height<<pp), - CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp), - CGRectMake(dest_x, dest_y, width, height)); - CFRelease(img); - } else { - TkMacOSXDbgMsg("Invalid source drawable"); - } - } else { - TkMacOSXDbgMsg("Invalid destination drawable"); - } - TkMacOSXRestoreDrawingContext(&dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * CreateCGImageWithXImage -- - * - * Create CGImage from XImage, copying the image data. - * - * Results: - * CGImage, release after use. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void ReleaseData(void *info, const void *data, size_t size) { - ckfree(info); -} - -CGImageRef -CreateCGImageWithXImage( - XImage *image) -{ - CGImageRef img = NULL; - size_t bitsPerComponent, bitsPerPixel; - size_t len = image->bytes_per_line * image->height; - const CGFloat *decode = NULL; - CGBitmapInfo bitmapInfo; - CGDataProviderRef provider = NULL; - char *data = NULL; - CGDataProviderReleaseDataCallback releaseData = ReleaseData; - - if (image->bits_per_pixel == 1) { - /* - * BW image - */ - - /* Reverses the sense of the bits */ - static const CGFloat decodeWB[2] = {1, 0}; - decode = decodeWB; - - bitsPerComponent = 1; - bitsPerPixel = 1; - if (image->bitmap_bit_order != MSBFirst) { - char *srcPtr = image->data + image->xoffset; - char *endPtr = srcPtr + len; - char *destPtr = (data = ckalloc(len)); - - while (srcPtr < endPtr) { - *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))]; - } - } else { - data = memcpy(ckalloc(len), image->data + image->xoffset, len); - } - if (data) { - provider = CGDataProviderCreateWithData(data, data, len, releaseData); - } - if (provider) { - img = CGImageMaskCreate(image->width, image->height, bitsPerComponent, - bitsPerPixel, image->bytes_per_line, provider, decode, 0); - } - } else if (image->format == ZPixmap && image->bits_per_pixel == 32) { - /* - * Color image - */ - - CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - - bitsPerComponent = 8; - bitsPerPixel = 32; - bitmapInfo = (image->byte_order == MSBFirst ? - kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little) | - kCGImageAlphaNoneSkipFirst; - data = memcpy(ckalloc(len), image->data + image->xoffset, len); - if (data) { - provider = CGDataProviderCreateWithData(data, data, len, releaseData); - } - if (provider) { - img = CGImageCreate(image->width, image->height, bitsPerComponent, - bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo, - provider, decode, 0, kCGRenderingIntentDefault); - CFRelease(provider); - } - if (colorspace) { - CFRelease(colorspace); - } - } else { - TkMacOSXDbgMsg("Unsupported image type"); - } - return img; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXCreateCGImageWithDrawable -- - * - * Create a CGImage from the given Drawable. - * - * Results: - * CGImage, release after use. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -CGImageRef -TkMacOSXCreateCGImageWithDrawable( - Drawable drawable) -{ - CGImageRef img = NULL; - CGContextRef context = GetCGContextForDrawable(drawable); - - if (context) { - img = CGBitmapContextCreateImage(context); - } - return img; -} - -/* - *---------------------------------------------------------------------- - * - * CreateNSImageWithPixmap -- - * - * Create NSImage for Pixmap. - * - * Results: - * NSImage. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static NSImage* -CreateNSImageWithPixmap( - Pixmap pixmap, - int width, - int height) -{ - CGImageRef cgImage; - NSImage *nsImage; - NSBitmapImageRep *bitmapImageRep; - - cgImage = TkMacOSXCreateCGImageWithDrawable(pixmap); - nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)]; - bitmapImageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; - [nsImage addRepresentation:bitmapImageRep]; - [bitmapImageRep release]; - CFRelease(cgImage); - - return nsImage; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXGetNSImageWithTkImage -- - * - * Get autoreleased NSImage for Tk_Image. - * - * Results: - * NSImage. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -NSImage* -TkMacOSXGetNSImageWithTkImage( - Display *display, - Tk_Image image, - int width, - int height) -{ - Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0); - NSImage *nsImage; - - Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0); - nsImage = CreateNSImageWithPixmap(pixmap, width, height); - Tk_FreePixmap(display, pixmap); - - return [nsImage autorelease]; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXGetNSImageWithBitmap -- - * - * Get autoreleased NSImage for Bitmap. - * - * Results: - * NSImage. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -NSImage* -TkMacOSXGetNSImageWithBitmap( - Display *display, - Pixmap bitmap, - GC gc, - int width, - int height) -{ - Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0); - NSImage *nsImage; - - unsigned long origBackground = gc->background; - - gc->background = TRANSPARENT_PIXEL << 24; - XSetClipOrigin(display, gc, 0, 0); - XCopyPlane(display, bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1); - gc->background = origBackground; - nsImage = CreateNSImageWithPixmap(pixmap, width, height); - Tk_FreePixmap(display, pixmap); - - return [nsImage autorelease]; -} - -/* - *---------------------------------------------------------------------- - * - * GetCGContextForDrawable -- - * - * Get CGContext for given Drawable, creating one if necessary. - * - * Results: - * CGContext. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -CGContextRef -GetCGContextForDrawable( - Drawable d) -{ - MacDrawable *macDraw = (MacDrawable *) d; - - if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) { - const size_t bitsPerComponent = 8; - size_t bitsPerPixel, bytesPerRow, len; - CGColorSpaceRef colorspace = NULL; - CGBitmapInfo bitmapInfo = -#ifdef __LITTLE_ENDIAN__ - kCGBitmapByteOrder32Host; -#else - kCGBitmapByteOrderDefault; -#endif - char *data; - CGRect bounds = CGRectMake(0, 0, macDraw->size.width, macDraw->size.height); - - if (macDraw->flags & TK_IS_BW_PIXMAP) { - bitsPerPixel = 8; - bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly; - } else { - colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - bitsPerPixel = 32; - bitmapInfo |= kCGImageAlphaPremultipliedFirst; - } - bytesPerRow = ((size_t) macDraw->size.width * bitsPerPixel + 127) >> 3 - & ~15; - len = macDraw->size.height * bytesPerRow; - data = ckalloc(len); - bzero(data, len); - macDraw->context = CGBitmapContextCreate(data, macDraw->size.width, - macDraw->size.height, bitsPerComponent, bytesPerRow, - colorspace, bitmapInfo); - if (macDraw->context) { - CGContextClearRect(macDraw->context, bounds); - } - if (colorspace) { - CFRelease(colorspace); - } - } - - return (macDraw ? macDraw->context : NULL); -} - -/* - *---------------------------------------------------------------------- - * - * DrawCGImage -- - * - * Draw CG image into drawable. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -DrawCGImage( - Drawable d, - GC gc, - CGContextRef context, - CGImageRef image, - unsigned long imageForeground, - unsigned long imageBackground, - CGRect imageBounds, - CGRect srcBounds, - CGRect dstBounds) -{ - MacDrawable *macDraw = (MacDrawable *) d; - - if (macDraw && context && image) { - CGImageRef subImage = NULL; - - if (!CGRectEqualToRect(imageBounds, srcBounds)) { - if (!CGRectContainsRect(imageBounds, srcBounds)) { - TkMacOSXDbgMsg("Mismatch of sub CGImage bounds"); - } - subImage = CGImageCreateWithImageInRect(image, CGRectOffset( - srcBounds, -imageBounds.origin.x, -imageBounds.origin.y)); - if (subImage) { - image = subImage; - } - } - dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff); - - if (CGImageIsMask(image)) { - /*CGContextSaveGState(context);*/ - if (macDraw->flags & TK_IS_BW_PIXMAP) { - /* Set fill color to black, background comes from the context, or is transparent. */ - if (imageBackground != TRANSPARENT_PIXEL << 24) { - CGContextClearRect(context, dstBounds); - } - CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); - } else { - if (imageBackground != TRANSPARENT_PIXEL << 24) { - TkMacOSXSetColorInContext(gc, imageBackground, context); - CGContextFillRect(context, dstBounds); - } - TkMacOSXSetColorInContext(gc, imageForeground, context); - } - } - -#ifdef TK_MAC_DEBUG_IMAGE_DRAWING - CGContextSaveGState(context); - CGContextSetLineWidth(context, 1.0); - CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.1); - CGContextSetRGBFillColor(context, 0, 1, 0, 0.1); - CGContextFillRect(context, dstBounds); - CGContextStrokeRect(context, dstBounds); - CGPoint p[4] = {dstBounds.origin, - CGPointMake(CGRectGetMaxX(dstBounds), CGRectGetMaxY(dstBounds)), - CGPointMake(CGRectGetMinX(dstBounds), CGRectGetMaxY(dstBounds)), - CGPointMake(CGRectGetMaxX(dstBounds), CGRectGetMinY(dstBounds)) - }; - CGContextStrokeLineSegments(context, p, 4); - CGContextRestoreGState(context); - TkMacOSXDbgMsg("Drawing CGImage at (x=%f, y=%f), (w=%f, h=%f)", - dstBounds.origin.x, dstBounds.origin.y, - dstBounds.size.width, dstBounds.size.height); -#else /* TK_MAC_DEBUG_IMAGE_DRAWING */ - CGContextSaveGState(context); - CGContextTranslateCTM(context, 0, dstBounds.origin.y + CGRectGetMaxY(dstBounds)); - CGContextScaleCTM(context, 1, -1); - CGContextDrawImage(context, dstBounds, image); - CGContextRestoreGState(context); -#endif /* TK_MAC_DEBUG_IMAGE_DRAWING */ - if (subImage) { - CFRelease(subImage); - } - } else { - TkMacOSXDbgMsg("Drawing of empty CGImage requested"); - } -} - -/* - *---------------------------------------------------------------------- - * - * XDrawLines -- - * - * Draw connected lines. - * - * Results: - * None. - * - * Side effects: - * Renders a series of connected lines. - * - *---------------------------------------------------------------------- - */ - -int -XDrawLines( - Display *display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - XPoint *points, /* Array of points. */ - int npoints, /* Number of points. */ - int mode) /* Line drawing mode. */ -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - int i, lw = gc->line_width; - - if (npoints < 2) { - return BadValue; - } - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return BadDrawable; - } - if (dc.context) { - double prevx, prevy; - double o = (lw % 2) ? .5 : 0; - - CGContextBeginPath(dc.context); - prevx = macWin->xOff + points[0].x + o; - prevy = macWin->yOff + points[0].y + o; - CGContextMoveToPoint(dc.context, prevx, prevy); - for (i = 1; i < npoints; i++) { - if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(dc.context, - macWin->xOff + points[i].x + o, - macWin->yOff + points[i].y + o); - } else { - prevx += points[i].x; - prevy += points[i].y; - CGContextAddLineToPoint(dc.context, prevx, prevy); - } - } - CGContextStrokePath(dc.context); - } - TkMacOSXRestoreDrawingContext(&dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XDrawSegments -- - * - * Draw unconnected lines. - * - * Results: - * None. - * - * Side effects: - * Renders a series of unconnected lines. - * - *---------------------------------------------------------------------- - */ - -int -XDrawSegments( - Display *display, - Drawable d, - GC gc, - XSegment *segments, - int nsegments) -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - int i, lw = gc->line_width; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return BadDrawable; - } - if (dc.context) { - double o = (lw % 2) ? .5 : 0; - - for (i = 0; i < nsegments; i++) { - CGContextBeginPath(dc.context); - CGContextMoveToPoint(dc.context, - macWin->xOff + segments[i].x1 + o, - macWin->yOff + segments[i].y1 + o); - CGContextAddLineToPoint(dc.context, - macWin->xOff + segments[i].x2 + o, - macWin->yOff + segments[i].y2 + o); - CGContextStrokePath(dc.context); - } - } - TkMacOSXRestoreDrawingContext(&dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XFillPolygon -- - * - * Draws a filled polygon. - * - * Results: - * None. - * - * Side effects: - * Draws a filled polygon on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XFillPolygon( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - XPoint* points, /* Array of points. */ - int npoints, /* Number of points. */ - int shape, /* Shape to draw. */ - int mode) /* Drawing mode. */ -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - int i; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - double prevx, prevy; - double o = (gc->line_width % 2) ? .5 : 0; - - CGContextBeginPath(dc.context); - prevx = macWin->xOff + points[0].x + o; - prevy = macWin->yOff + points[0].y + o; - CGContextMoveToPoint(dc.context, prevx, prevy); - for (i = 1; i < npoints; i++) { - if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(dc.context, - macWin->xOff + points[i].x + o, - macWin->yOff + points[i].y + o); - } else { - prevx += points[i].x; - prevy += points[i].y; - CGContextAddLineToPoint(dc.context, prevx, prevy); - } - } - CGContextEOFillPath(dc.context); - } - TkMacOSXRestoreDrawingContext(&dc); -} - -/* - *---------------------------------------------------------------------- - * - * XDrawRectangle -- - * - * Draws a rectangle. - * - * Results: - * None. - * - * Side effects: - * Draws a rectangle on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XDrawRectangle( - Display *display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, int y, /* Upper left corner. */ - unsigned int width, /* Width & height of rect. */ - unsigned int height) -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - int lw = gc->line_width; - - if (width == 0 || height == 0) { - return; - } - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - CGRect rect; - double o = (lw % 2) ? .5 : 0; - - rect = CGRectMake( - macWin->xOff + x + o, - macWin->yOff + y + o, - width, height); - CGContextStrokeRect(dc.context, rect); - } - TkMacOSXRestoreDrawingContext(&dc); -} - -#ifdef TK_MACOSXDRAW_UNUSED -/* - *---------------------------------------------------------------------- - * - * XDrawRectangles -- - * - * Draws the outlines of the specified rectangles as if a - * five-point PolyLine protocol request were specified for each - * rectangle: - * - * [x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y] - * - * For the specified rectangles, these functions do not draw a - * pixel more than once. XDrawRectangles draws the rectangles in - * the order listed in the array. If rectangles intersect, the - * intersecting pixels are drawn multiple times. Draws a - * rectangle. - * - * Results: - * None. - * - * Side effects: - * Draws rectangles on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XDrawRectangles( - Display *display, - Drawable drawable, - GC gc, - XRectangle *rectArr, - int nRects) -{ - MacDrawable *macWin = (MacDrawable *) drawable; - TkMacOSXDrawingContext dc; - XRectangle * rectPtr; - int i, lw = gc->line_width; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - CGRect rect; - double o = (lw % 2) ? .5 : 0; - - for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) { - if (rectPtr->width == 0 || rectPtr->height == 0) { - continue; - } - rect = CGRectMake( - macWin->xOff + rectPtr->x + o, - macWin->yOff + rectPtr->y + o, - rectPtr->width, rectPtr->height); - CGContextStrokeRect(dc.context, rect); - } - } - TkMacOSXRestoreDrawingContext(&dc); -} -#endif - -/* - *---------------------------------------------------------------------- - * - * XFillRectangles -- - * - * Fill multiple rectangular areas in the given drawable. - * - * Results: - * None. - * - * Side effects: - * Draws onto the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -XFillRectangles( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - XRectangle *rectangles, /* Rectangle array. */ - int n_rectangles) /* Number of rectangles. */ -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - XRectangle * rectPtr; - int i; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return BadDrawable; - } - if (dc.context) { - CGRect rect; - - for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) { - if (rectPtr->width == 0 || rectPtr->height == 0) { - continue; - } - rect = CGRectMake( - macWin->xOff + rectPtr->x, - macWin->yOff + rectPtr->y, - rectPtr->width, rectPtr->height); - CGContextFillRect(dc.context, rect); - } - } - TkMacOSXRestoreDrawingContext(&dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XDrawArc -- - * - * Draw an arc. - * - * Results: - * None. - * - * Side effects: - * Draws an arc on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XDrawArc( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, int y, /* Upper left of bounding rect. */ - unsigned int width, /* Width & height. */ - unsigned int height, - int angle1, /* Staring angle of arc. */ - int angle2) /* Extent of arc. */ -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - int lw = gc->line_width; - - if (width == 0 || height == 0 || angle2 == 0) { - return; - } - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - CGRect rect; - double o = (lw % 2) ? .5 : 0; - - rect = CGRectMake( - macWin->xOff + x + o, - macWin->yOff + y + o, - width, height); - if (angle1 == 0 && angle2 == 23040) { - CGContextStrokeEllipseInRect(dc.context, rect); - } else { - CGMutablePathRef p = CGPathCreateMutable(); - CGAffineTransform t = CGAffineTransformIdentity; - CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - double w = CGRectGetWidth(rect); - - if (width != height) { - t = CGAffineTransformMakeScale(1.0, CGRectGetHeight(rect)/w); - c = CGPointApplyAffineTransform(c, CGAffineTransformInvert(t)); - } - CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0), - radians(-(angle1 + angle2)/64.0), angle2 > 0); - CGContextAddPath(dc.context, p); - CGPathRelease(p); - CGContextStrokePath(dc.context); - } - } - TkMacOSXRestoreDrawingContext(&dc); -} - -#ifdef TK_MACOSXDRAW_UNUSED -/* - *---------------------------------------------------------------------- - * - * XDrawArcs -- - * - * Draws multiple circular or elliptical arcs. Each arc is - * specified by a rectangle and two angles. The center of the - * circle or ellipse is the center of the rect- angle, and the - * major and minor axes are specified by the width and height. - * Positive angles indicate counterclock- wise motion, and - * negative angles indicate clockwise motion. If the magnitude - * of angle2 is greater than 360 degrees, XDrawArcs truncates it - * to 360 degrees. - * - * Results: - * None. - * - * Side effects: - * Draws an arc for each array element on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XDrawArcs( - Display *display, - Drawable d, - GC gc, - XArc *arcArr, - int nArcs) -{ - - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - XArc *arcPtr; - int i, lw = gc->line_width; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - CGRect rect; - double o = (lw % 2) ? .5 : 0; - - for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { - if (arcPtr->width == 0 || arcPtr->height == 0 - || arcPtr->angle2 == 0) { - continue; - } - rect = CGRectMake( - macWin->xOff + arcPtr->x + o, - macWin->yOff + arcPtr->y + o, - arcPtr->width, arcPtr->height); - - if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040) { - CGContextStrokeEllipseInRect(dc.context, rect); - } else { - CGMutablePathRef p = CGPathCreateMutable(); - CGAffineTransform t = CGAffineTransformIdentity; - CGPoint c = CGPointMake(CGRectGetMidX(rect), - CGRectGetMidY(rect)); - double w = CGRectGetWidth(rect); - - if (arcPtr->width != arcPtr->height) { - t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); - c = CGPointApplyAffineTransform(c, - CGAffineTransformInvert(t)); - } - CGPathAddArc(p, &t, c.x, c.y, w/2, - radians(-arcPtr->angle1/64.0), - radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0), - arcPtr->angle2 > 0); - CGContextAddPath(dc.context, p); - CGPathRelease(p); - CGContextStrokePath(dc.context); - } - } - } - TkMacOSXRestoreDrawingContext(&dc); -} -#endif - -/* - *---------------------------------------------------------------------- - * - * XFillArc -- - * - * Draw a filled arc. - * - * Results: - * None. - * - * Side effects: - * Draws a filled arc on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XFillArc( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, int y, /* Upper left of bounding rect. */ - unsigned int width, /* Width & height. */ - unsigned int height, - int angle1, /* Staring angle of arc. */ - int angle2) /* Extent of arc. */ -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - int lw = gc->line_width; - - if (width == 0 || height == 0 || angle2 == 0) { - return; - } - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - CGRect rect; - double o = (lw % 2) ? .5 : 0, u = 0; - - if (notAA(lw)) { - o += NON_AA_CG_OFFSET/2; - u += NON_AA_CG_OFFSET; - } - rect = CGRectMake( - macWin->xOff + x + o, - macWin->yOff + y + o, - width - u, height - u); - - if (angle1 == 0 && angle2 == 23040) { - CGContextFillEllipseInRect(dc.context, rect); - } else { - CGMutablePathRef p = CGPathCreateMutable(); - CGAffineTransform t = CGAffineTransformIdentity; - CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - double w = CGRectGetWidth(rect); - - if (width != height) { - t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); - c = CGPointApplyAffineTransform(c, CGAffineTransformInvert(t)); - } - if (gc->arc_mode == ArcPieSlice) { - CGPathMoveToPoint(p, &t, c.x, c.y); - } - CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0), - radians(-(angle1 + angle2)/64.0), angle2 > 0); - CGPathCloseSubpath(p); - CGContextAddPath(dc.context, p); - CGPathRelease(p); - CGContextFillPath(dc.context); - } - } - TkMacOSXRestoreDrawingContext(&dc); -} - -#ifdef TK_MACOSXDRAW_UNUSED -/* - *---------------------------------------------------------------------- - * - * XFillArcs -- - * - * Draw a filled arc. - * - * Results: - * None. - * - * Side effects: - * Draws a filled arc for each array element on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -void -XFillArcs( - Display *display, - Drawable d, - GC gc, - XArc *arcArr, - int nArcs) -{ - MacDrawable *macWin = (MacDrawable *) d; - TkMacOSXDrawingContext dc; - XArc * arcPtr; - int i, lw = gc->line_width; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; - } - if (dc.context) { - CGRect rect; - double o = (lw % 2) ? .5 : 0, u = 0; - - if (notAA(lw)) { - o += NON_AA_CG_OFFSET/2; - u += NON_AA_CG_OFFSET; - } - for (i = 0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { - if (arcPtr->width == 0 || arcPtr->height == 0 - || arcPtr->angle2 == 0) { - continue; - } - rect = CGRectMake( - macWin->xOff + arcPtr->x + o, - macWin->yOff + arcPtr->y + o, - arcPtr->width - u, arcPtr->height - u); - if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040) { - CGContextFillEllipseInRect(dc.context, rect); - } else { - CGMutablePathRef p = CGPathCreateMutable(); - CGAffineTransform t = CGAffineTransformIdentity; - CGPoint c = CGPointMake(CGRectGetMidX(rect), - CGRectGetMidY(rect)); - double w = CGRectGetWidth(rect); - - if (arcPtr->width != arcPtr->height) { - t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); - c = CGPointApplyAffineTransform(c, - CGAffineTransformInvert(t)); - } - if (gc->arc_mode == ArcPieSlice) { - CGPathMoveToPoint(p, &t, c.x, c.y); - } - CGPathAddArc(p, &t, c.x, c.y, w/2, - radians(-arcPtr->angle1/64.0), - radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0), - arcPtr->angle2 > 0); - CGPathCloseSubpath(p); - CGContextAddPath(dc.context, p); - CGPathRelease(p); - CGContextFillPath(dc.context); - } - } - } - TkMacOSXRestoreDrawingContext(&dc); -} -#endif - -#ifdef TK_MACOSXDRAW_UNUSED -/* - *---------------------------------------------------------------------- - * - * XMaxRequestSize -- - * - *---------------------------------------------------------------------- - */ - -long -XMaxRequestSize( - Display *display) -{ - return (SHRT_MAX / 4); -} -#endif - -/* - *---------------------------------------------------------------------- - * - * TkScrollWindow -- - * - * Scroll a rectangle of the specified window and accumulate - * a damage region. - * - * Results: - * Returns 0 if the scroll genereated no additional damage. - * Otherwise, sets the region that needs to be repainted after - * scrolling and returns 1. - * - * Side effects: - * Scrolls the bits in the window. - * - *---------------------------------------------------------------------- - */ - -int -TkScrollWindow( - Tk_Window tkwin, /* The window to be scrolled. */ - GC gc, /* GC for window to be scrolled. */ - int x, int y, /* Position rectangle to be scrolled. */ - int width, int height, - int dx, int dy, /* Distance rectangle should be moved. */ - TkRegion damageRgn) /* Region to accumulate damage in. */ -{ - Drawable drawable = Tk_WindowId(tkwin); - MacDrawable *macDraw = (MacDrawable *) drawable; - TKContentView *view = (TKContentView *)TkMacOSXDrawableView(macDraw); - CGRect srcRect, dstRect; - HIShapeRef dmgRgn = NULL, extraRgn = NULL; - NSRect bounds, visRect, scrollSrc, scrollDst; - int result = 0; - - if ( view ) { - /* Get the scroll area in NSView coordinates (origin at bottom left). */ - bounds = [view bounds]; - scrollSrc = NSMakeRect( - macDraw->xOff + x, - bounds.size.height - height - (macDraw->yOff + y), - width, height); - scrollDst = NSOffsetRect(scrollSrc, dx, -dy); - - /* Limit scrolling to the window content area. */ - visRect = [view visibleRect]; - scrollSrc = NSIntersectionRect(scrollSrc, visRect); - scrollDst = NSIntersectionRect(scrollDst, visRect); - if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) { - - /* - * Mark the difference between source and destination as damaged. - * This region is described in NSView coordinates (y=0 at the bottom) - * and converted to Tk coordinates later. - */ - - srcRect = CGRectMake(x, y, width, height); - dstRect = CGRectOffset(srcRect, dx, dy); - - /* Compute the damage. */ - dmgRgn = HIShapeCreateMutableWithRect(&srcRect); - extraRgn = HIShapeCreateWithRect(&dstRect); - ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn); - result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; - - /* Convert to Tk coordinates. */ - TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); - if (extraRgn) { - CFRelease(extraRgn); - } - - /* Scroll the rectangle. */ - [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)]; - - /* Shift the Tk children which meet the source rectangle. */ - TkWindow *winPtr = (TkWindow *)tkwin; - TkWindow *childPtr; - CGRect childBounds; - for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) { - if (Tk_IsMapped(childPtr) && !Tk_IsTopLevel(childPtr)) { - TkMacOSXWinCGBounds(childPtr, &childBounds); - if (CGRectIntersectsRect(srcRect, childBounds)) { - MacDrawable *macChild = childPtr->privatePtr; - if (macChild) { - macChild->yOff += dy; - macChild->xOff += dx; - childPtr->changes.y = macChild->yOff; - childPtr->changes.x = macChild->xOff; - } - } - } - } - - /* Queue up Expose events for the damage region. */ - int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); - [view generateExposeEvents:dmgRgn childrenOnly:1]; - Tcl_SetServiceMode(oldMode); - } - } else { - dmgRgn = HIShapeCreateEmpty(); - TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); - } - - if (dmgRgn) { - CFRelease(dmgRgn); - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXSetUpGraphicsPort -- - * - * Set up the graphics port from the given GC. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXSetUpGraphicsPort( - GC gc, /* GC to apply to current port. */ - void *destPort) -{ - Tcl_Panic("TkMacOSXSetUpGraphicsPort: Obsolete, no more QD!"); -} - - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXSetUpDrawingContext -- - * - * Set up a drawing context for the given drawable and GC. - * - * Results: - * Boolean indicating whether it is ok to draw; if false, drawing - * context was not setup, so do not attempt to draw and do not call - * TkMacOSXRestoreDrawingContext(). - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXSetupDrawingContext( - Drawable d, - GC gc, - int useCG, /* advisory only ! */ - TkMacOSXDrawingContext *dcPtr) -{ - MacDrawable *macDraw = ((MacDrawable*)d); - int dontDraw = 0, isWin = 0; - TkMacOSXDrawingContext dc = {}; - CGRect clipBounds; - - dc.clipRgn = TkMacOSXGetClipRgn(d); - if (!dontDraw) { - ClipToGC(d, gc, &dc.clipRgn); - dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0; - } - if (dontDraw) { - goto end; - } - if (useCG) { - dc.context = GetCGContextForDrawable(d); - } - if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) { - isWin = (TkMacOSXDrawableWindow(d) != nil); - } - if (dc.context) { - dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context); - } else if (isWin) { - NSView *view = TkMacOSXDrawableView(macDraw); - if (view) { - if (view != [NSView focusView]) { - dc.focusLocked = [view lockFocusIfCanDraw]; - dontDraw = !dc.focusLocked; - } else { - dontDraw = ![view canDraw]; - } - if (dontDraw) { - goto end; - } - [[view window] disableFlushWindow]; - dc.view = view; - dc.context = [[NSGraphicsContext currentContext] graphicsPort]; - dc.portBounds = NSRectToCGRect([view bounds]); - if (dc.clipRgn) { - clipBounds = CGContextGetClipBoundingBox(dc.context); - } - } else { - Tcl_Panic("TkMacOSXSetupDrawingContext(): " - "no NSView to draw into !"); - } - } else { - Tcl_Panic("TkMacOSXSetupDrawingContext(): " - "no context to draw into !"); - } - if (dc.context) { - CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0, - .ty = dc.portBounds.size.height}; - dc.portBounds.origin.x += macDraw->xOff; - dc.portBounds.origin.y += macDraw->yOff; - if (!dc.focusLocked) { - CGContextSaveGState(dc.context); - } - CGContextSetTextDrawingMode(dc.context, kCGTextFill); - CGContextConcatCTM(dc.context, t); - if (dc.clipRgn) { -#ifdef TK_MAC_DEBUG_DRAWING - CGContextSaveGState(dc.context); - ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); - CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1); - CGContextEOFillPath(dc.context); - CGContextRestoreGState(dc.context); -#endif /* TK_MAC_DEBUG_DRAWING */ - CGRect r; - if (!HIShapeIsRectangular(dc.clipRgn) || !CGRectContainsRect( - *HIShapeGetBounds(dc.clipRgn, &r), - CGRectApplyAffineTransform(clipBounds, t))) { - ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); - CGContextEOClip(dc.context); - } - } - if (gc) { - static const CGLineCap cgCap[] = { - [CapNotLast] = kCGLineCapButt, - [CapButt] = kCGLineCapButt, - [CapRound] = kCGLineCapRound, - [CapProjecting] = kCGLineCapSquare, - }; - static const CGLineJoin cgJoin[] = { - [JoinMiter] = kCGLineJoinMiter, - [JoinRound] = kCGLineJoinRound, - [JoinBevel] = kCGLineJoinBevel, - }; - bool shouldAntialias; - double w = gc->line_width; - - TkMacOSXSetColorInContext(gc, gc->foreground, dc.context); - if (isWin) { - CGContextSetPatternPhase(dc.context, CGSizeMake( - dc.portBounds.size.width, dc.portBounds.size.height)); - } - if(gc->function != GXcopy) { - TkMacOSXDbgMsg("Logical functions other than GXcopy are " - "not supported for CG drawing!"); - } - /* When should we antialias? */ - shouldAntialias = !notAA(gc->line_width); - if (!shouldAntialias) { - /* Make non-antialiased CG drawing look more like X11 */ - w -= (gc->line_width ? NON_AA_CG_OFFSET : 0); - } - CGContextSetShouldAntialias(dc.context, shouldAntialias); - CGContextSetLineWidth(dc.context, w); - if (gc->line_style != LineSolid) { - int num = 0; - char *p = &(gc->dashes); - CGFloat dashOffset = gc->dash_offset; - CGFloat lengths[10]; - - while (p[num] != '\0' && num < 10) { - lengths[num] = p[num]; - num++; - } - CGContextSetLineDash(dc.context, dashOffset, lengths, num); - } - if ((unsigned)gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) { - CGContextSetLineCap(dc.context, - cgCap[(unsigned)gc->cap_style]); - } - if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) { - CGContextSetLineJoin(dc.context, - cgJoin[(unsigned)gc->join_style]); - } - } - } -end: - if (dontDraw && dc.clipRgn) { - CFRelease(dc.clipRgn); - dc.clipRgn = NULL; - } - *dcPtr = dc; - return !dontDraw; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXRestoreDrawingContext -- - * - * Restore drawing context. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXRestoreDrawingContext( - TkMacOSXDrawingContext *dcPtr) -{ - if (dcPtr->context) { - CGContextSynchronize(dcPtr->context); - [[dcPtr->view window] setViewsNeedDisplay:YES]; - [[dcPtr->view window] enableFlushWindow]; - if (dcPtr->focusLocked) { - [dcPtr->view unlockFocus]; - } else { - CGContextRestoreGState(dcPtr->context); - } - } - if (dcPtr->clipRgn) { - CFRelease(dcPtr->clipRgn); - } -#ifdef TK_MAC_DEBUG - bzero(dcPtr, sizeof(TkMacOSXDrawingContext)); -#endif /* TK_MAC_DEBUG */ -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXGetClipRgn -- - * - * Get the clipping region needed to restrict drawing to the given - * drawable. - * - * Results: - * Clipping region. If non-NULL, CFRelease it when done. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HIShapeRef -TkMacOSXGetClipRgn( - Drawable drawable) /* Drawable. */ -{ - MacDrawable *macDraw = (MacDrawable *) drawable; - HIShapeRef clipRgn = NULL; - - if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) { - TkMacOSXUpdateClipRgn(macDraw->winPtr); -#ifdef TK_MAC_DEBUG_DRAWING - TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName); - NSView *view = TkMacOSXDrawableView(macDraw); - if ([view lockFocusIfCanDraw]) { - CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState(context); - CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, - -1.0, 0.0, [view bounds].size.height)); - ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context); - CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1); - CGContextEOFillPath(context); - CGContextRestoreGState(context); - [view unlockFocus]; - } -#endif /* TK_MAC_DEBUG_DRAWING */ - } - - if (macDraw->drawRgn) { - clipRgn = HIShapeCreateCopy(macDraw->drawRgn); - } else if (macDraw->visRgn) { - clipRgn = HIShapeCreateCopy(macDraw->visRgn); - } - return clipRgn; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXSetUpClippingRgn -- - * - * Set up the clipping region so that drawing only occurs on the - * specified X subwindow. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXSetUpClippingRgn( - Drawable drawable) /* Drawable to update. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * TkpClipDrawableToRect -- - * - * Clip all drawing into the drawable d to the given rectangle. - * If width or height are negative, reset to no clipping. - * - * Results: - * None. - * - * Side effects: - * Subsequent drawing into d is offset and clipped as specified. - * - *---------------------------------------------------------------------- - */ - -void -TkpClipDrawableToRect( - Display *display, - Drawable d, - int x, int y, - int width, int height) -{ - MacDrawable *macDraw = (MacDrawable *) d; - NSView *view = TkMacOSXDrawableView(macDraw); - - if (macDraw->drawRgn) { - CFRelease(macDraw->drawRgn); - macDraw->drawRgn = NULL; - } - - if (width >= 0 && height >= 0) { - CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff, - width, height); - HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect); - - if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) { - TkMacOSXUpdateClipRgn(macDraw->winPtr); - } - if (macDraw->visRgn) { - macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn, - drawRgn); - CFRelease(drawRgn); - } else { - macDraw->drawRgn = drawRgn; - } - if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) { - clipRect.origin.y = [view bounds].size.height - - (clipRect.origin.y + clipRect.size.height); - NSRectClip(NSRectFromCGRect(clipRect)); - macDraw->flags |= TK_FOCUSED_VIEW; - } - } else { - if (view && (macDraw->flags & TK_FOCUSED_VIEW)) { - [view unlockFocus]; - macDraw->flags &= ~TK_FOCUSED_VIEW; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * ClipToGC -- - * - * Helper function to intersect given region with gc clip region. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -ClipToGC( - Drawable d, - GC gc, - HIShapeRef *clipRgnPtr) /* must point to initialized variable */ -{ - if (gc && gc->clip_mask && - ((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) { - TkRegion gcClip = ((TkpClipMask*)gc->clip_mask)->value.region; - int xOffset = ((MacDrawable *) d)->xOff + gc->clip_x_origin; - int yOffset = ((MacDrawable *) d)->yOff + gc->clip_y_origin; - HIShapeRef clipRgn = *clipRgnPtr, gcClipRgn; - - TkMacOSXOffsetRegion(gcClip, xOffset, yOffset); - gcClipRgn = TkMacOSXGetNativeRegion(gcClip); - if (clipRgn) { - *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn); - CFRelease(clipRgn); - } else { - *clipRgnPtr = HIShapeCreateCopy(gcClipRgn); - } - CFRelease(gcClipRgn); - TkMacOSXOffsetRegion(gcClip, -xOffset, -yOffset); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXMakeStippleMap -- - * - * Given a drawable and a stipple pattern this function draws the - * pattern repeatedly over the drawable. The drawable can then - * be used as a mask for bit-bliting a stipple pattern over an - * object. - * - * Results: - * A BitMap data structure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void * -TkMacOSXMakeStippleMap( - Drawable drawable, /* Window to apply stipple. */ - Drawable stipple) /* The stipple pattern. */ -{ - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TkpDrawHighlightBorder -- - * - * This procedure draws a rectangular ring around the outside of - * a widget to indicate that it has received the input focus. - * - * On the Macintosh, this puts a 1 pixel border in the bgGC color - * between the widget and the focus ring, except in the case where - * highlightWidth is 1, in which case the border is left out. - * - * For proper Mac L&F, use highlightWidth of 3. - * - * Results: - * None. - * - * Side effects: - * A rectangle "width" pixels wide is drawn in "drawable", - * corresponding to the outer area of "tkwin". - * - *---------------------------------------------------------------------- - */ - -void -TkpDrawHighlightBorder ( - Tk_Window tkwin, - GC fgGC, - GC bgGC, - int highlightWidth, - Drawable drawable) -{ - if (highlightWidth == 1) { - TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth, drawable, 0); - } else { - TkDrawInsetFocusHighlight (tkwin, bgGC, highlightWidth, drawable, 0); - if (fgGC != bgGC) { - TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth - 1, - drawable, 0); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpDrawFrame -- - * - * This procedure draws the rectangular frame area. If the user - * has requested themeing, it draws with the background theme. - * - * Results: - * None. - * - * Side effects: - * Draws inside the tkwin area. - * - *---------------------------------------------------------------------- - */ - -void -TkpDrawFrame( - Tk_Window tkwin, - Tk_3DBorder border, - int highlightWidth, - int borderWidth, - int relief) -{ - if (useThemedToplevel && Tk_IsTopLevel(tkwin)) { - static Tk_3DBorder themedBorder = NULL; - - if (!themedBorder) { - themedBorder = Tk_Get3DBorder(NULL, tkwin, - "systemWindowHeaderBackground"); - } - if (themedBorder) { - border = themedBorder; - } - } - - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), - border, highlightWidth, highlightWidth, - Tk_Width(tkwin) - 2 * highlightWidth, - Tk_Height(tkwin) - 2 * highlightWidth, - borderWidth, relief); -} - -/* - * Local Variables: - * mode: objc - * c-basic-offset: 4 - * fill-column: 79 - * coding: utf-8 - * End: - */ |