diff options
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r-- | macosx/tkMacOSXDraw.c | 1508 |
1 files changed, 716 insertions, 792 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index aca5ee0..2f8464b 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -1,18 +1,18 @@ -/* +/* * tkMacOSXDraw.c -- * - * This file contains functions that perform drawing to - * Xlib windows. Most of the functions simple emulate - * Xlib functions. + * 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, Apple Computer, Inc. - * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.20 2006/10/31 22:26:10 das Exp $ + * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.21 2007/04/29 02:26:48 das Exp $ */ #include "tkMacOSXInt.h" @@ -26,10 +26,7 @@ #endif */ -#define RGBFLOATRED(c) ((c).red / 65535.0) -#define RGBFLOATGREEN(c) ((c).green / 65535.0) -#define RGBFLOATBLUE(c) ((c).blue / 65535.0) -#define radians(d) ((d) * (M_PI/180.0)) +#define radians(d) ((d) * (M_PI/180.0)) /* * Non-antialiased CG drawing looks better and more like X11 drawing when using @@ -41,8 +38,9 @@ * Temporary regions that can be reused. */ -static RgnHandle tmpRgn = NULL; -static RgnHandle tmpRgn2 = NULL; +RgnHandle tkMacOSXtmpRgn1 = NULL; +RgnHandle tkMacOSXtmpRgn2 = NULL; + static PixPatHandle gPenPat = NULL; static int useCGDrawing = 1; @@ -56,32 +54,29 @@ static int useThemedFrame = 0; * Prototypes for functions used only in this file. */ static unsigned char InvertByte(unsigned char data); -static void TkMacOSXSetUpCGContext(MacDrawable *macWin, CGrafPtr destPort, - GC gc, CGContextRef *contextPtr); -static void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort, - CGContextRef *context); + /* *---------------------------------------------------------------------- * * TkMacOSXInitCGDrawing -- * - * Initializes link vars that control CG drawing. + * Initializes link vars that control CG drawing. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ MODULE_SCOPE int -TkMacOSXInitCGDrawing(interp, enable, limit) - Tcl_Interp *interp; - int enable; - int limit; +TkMacOSXInitCGDrawing( + Tcl_Interp *interp, + int enable, + int limit) { static Boolean initialized = FALSE; @@ -106,15 +101,29 @@ TkMacOSXInitCGDrawing(interp, enable, limit) /* * Piggy-back the themed drawing var init here. */ + if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel", - (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) { + (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) { Tcl_ResetResult(interp); } if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame", - (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) { + (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) { Tcl_ResetResult(interp); } + + if (tkMacOSXtmpRgn1 == NULL) { + tkMacOSXtmpRgn1 = NewRgn(); + } + if (tkMacOSXtmpRgn2 == NULL) { + tkMacOSXtmpRgn2 = NewRgn(); + } } +#ifdef TK_MAC_DEBUG_DRAWING + TkMacOSXInitNamedDebugSymbol(QD, void, QD_DebugPrint, char*); + if (QD_DebugPrint) { + ; /* gdb: b *QD_DebugPrint */ + } +#endif /* TK_MAC_DEBUG_WINDOWS */ return TCL_OK; } @@ -123,41 +132,37 @@ TkMacOSXInitCGDrawing(interp, enable, limit) * * XCopyArea -- * - * Copies data from one drawable to another using block transfer - * routines. + * Copies data from one drawable to another using block transfer + * routines. * * Results: - * None. + * None. * * Side effects: - * Data is moved from a window or bitmap to a second window or - * bitmap. + * 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, /* the will be copied. */ + 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, /* the will be copied. */ unsigned int height, - int dest_x, /* Dest X & Y on dest rect. */ + int dest_x, /* Dest X & Y on dest rect. */ int dest_y) { - Rect srcRect, dstRect; - Rect * srcPtr, * dstPtr; - const BitMap * srcBit; - const BitMap * dstBit; - MacDrawable *srcDraw = (MacDrawable *) src; - MacDrawable *dstDraw = (MacDrawable *) dst; - CGrafPtr srcPort, dstPort; - CGrafPtr saveWorld; - GDHandle saveDevice; + Rect srcRect, dstRect, *srcPtr, *dstPtr; + const BitMap *srcBit, *dstBit; + MacDrawable *srcDraw = (MacDrawable *) src, *dstDraw = (MacDrawable *) dst; + CGrafPtr srcPort, dstPort, savePort; + Boolean portChanged; short tmode; RGBColor origForeColor, origBackColor, whiteColor, blackColor; Rect clpRect; @@ -166,8 +171,7 @@ XCopyArea( srcPort = TkMacOSXGetDrawablePort(src); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(dstPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); GetForeColor(&origForeColor); GetBackColor(&origBackColor); whiteColor.red = 0; @@ -179,9 +183,6 @@ XCopyArea( blackColor.green = 0xFFFF; RGBBackColor(&blackColor); - if (tmpRgn2 == NULL) { - tmpRgn2 = NewRgn(); - } srcPtr = &srcRect; SetRect(&srcRect, (short) (srcDraw->xOff + src_x), (short) (srcDraw->yOff + src_y), @@ -197,18 +198,20 @@ XCopyArea( (short) (dstDraw->yOff + dest_y + height)); } TkMacOSXSetUpClippingRgn(dst); + /* - * We will change the clip rgn in this routine, so we need to - * be able to restore it when we exit. + * We will change the clip rgn in this routine, so we need to + * be able to restore it when we exit. */ - GetClip(tmpRgn2); + TkMacOSXCheckTmpRgnEmpty(2); + GetClip(tkMacOSXtmpRgn2); if (tkPictureIsOpen) { /* * When rendering into a picture, after a call to "OpenCPicture" * the clipping is seriously WRONG and also INCONSISTENT with the * clipping for single plane bitmaps. - * To circumvent this problem, we clip to the whole window + * To circumvent this problem, we clip to the whole window * In this case, would have also clipped to the srcRect * ClipRect(&srcRect); */ @@ -217,23 +220,22 @@ XCopyArea( dstPtr = &srcRect; ClipRect(&clpRect); } - if (!gc->clip_mask) { - } else if (((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) { + if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { RgnHandle clipRgn = (RgnHandle) ((TkpClipMask*)gc->clip_mask)->value.region; - int xOffset = 0, yOffset = 0; - if (tmpRgn == NULL) { - tmpRgn = NewRgn(); - } + if (!tkPictureIsOpen) { xOffset = dstDraw->xOff + gc->clip_x_origin; yOffset = dstDraw->yOff + gc->clip_y_origin; OffsetRgn(clipRgn, xOffset, yOffset); } - GetClip(tmpRgn); - SectRgn(tmpRgn, clipRgn, tmpRgn); - SetClip(tmpRgn); + TkMacOSXCheckTmpRgnEmpty(1); + GetClip(tkMacOSXtmpRgn1); + SectRgn(tkMacOSXtmpRgn1, clipRgn, tkMacOSXtmpRgn1); + SetClip(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); if (!tkPictureIsOpen) { OffsetRgn(clipRgn, -xOffset, -yOffset); } @@ -245,8 +247,11 @@ XCopyArea( CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); RGBForeColor(&origForeColor); RGBBackColor(&origBackColor); - SetClip(tmpRgn2); - SetGWorld(saveWorld, saveDevice); + SetClip(tkMacOSXtmpRgn2); + SetEmptyRgn(tkMacOSXtmpRgn2); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -254,45 +259,37 @@ XCopyArea( * * 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. + * 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. + * None. * * Side effects: - * Changes the destination drawable. + * Changes the destination drawable. * *---------------------------------------------------------------------- */ void XCopyPlane( - Display* display, /* Display. */ - Drawable src, /* Source drawable. */ - Drawable dst, /* Destination drawable. */ - GC gc, /* The GC to use. */ - int src_x, /* X, Y, width & height */ - int src_y, /* define the source rect. */ - unsigned int width, - unsigned int height, - int dest_x, /* X & Y on dest where we will copy. */ - int dest_y, - unsigned long plane) /* Which plane to copy. */ + Display *display, /* Display. */ + Drawable src, /* Source drawable. */ + Drawable dst, /* Destination drawable. */ + GC gc, /* The GC to use. */ + int src_x, int src_y, /* X, Y, width & height define the source + * rect. */ + unsigned int width, unsigned int height, + int dest_x, int dest_y, /* X & Y on dest where we will copy. */ + unsigned long plane) /* Which plane to copy. */ { - Rect srcRect, dstRect; - Rect * srcPtr, * dstPtr; - const BitMap * srcBit; - const BitMap * dstBit; - const BitMap * mskBit; - MacDrawable *srcDraw = (MacDrawable *) src; - MacDrawable *dstDraw = (MacDrawable *) dst; - GWorldPtr srcPort, dstPort, mskPort; - CGrafPtr saveWorld; - GDHandle saveDevice; - RGBColor macColor; + Rect srcRect, dstRect, *srcPtr, *dstPtr; + const BitMap *srcBit, *dstBit, *mskBit; + MacDrawable *srcDraw = (MacDrawable *) src, *dstDraw = (MacDrawable *) dst; + CGrafPtr srcPort, dstPort, mskPort, savePort; + Boolean portChanged; TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; short tmode; @@ -300,8 +297,7 @@ XCopyPlane( dstPort = TkMacOSXGetDrawablePort(dst); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(dstPort, NULL); + portChanged = QDSwapPort(dstPort, &savePort); TkMacOSXSetUpClippingRgn(dst); srcBit = GetPortBitMapForCopyBits(srcPort); @@ -316,7 +312,7 @@ XCopyPlane( * When rendering into a picture, after a call to "OpenCPicture" * the clipping is seriously WRONG and also INCONSISTENT with the * clipping for color bitmaps. - * To circumvent this problem, we clip to the whole window + * To circumvent this problem, we clip to the whole window */ Rect clpRect; @@ -333,24 +329,21 @@ XCopyPlane( tmode = srcOr; tmode = srcCopy + transparent; - if (TkSetMacColor(gc->foreground, &macColor) == true) { - RGBForeColor(&macColor); - } + TkMacOSXSetColorInPort(gc->foreground, 1, NULL); if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) { /* * Case 1: opaque bitmaps. */ - TkSetMacColor(gc->background, &macColor); - RGBBackColor(&macColor); + TkMacOSXSetColorInPort(gc->background, 0, NULL); tmode = srcCopy; CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); } else if (clipPtr->type == TKP_CLIP_PIXMAP) { if (clipPtr->value.pixmap == src) { PixMapHandle pm; /* - * Case 2: transparent bitmaps. If it's color we ignore + * Case 2: transparent bitmaps. If it's color we ignore * the forecolor. */ @@ -373,8 +366,9 @@ XCopyPlane( srcPtr, srcPtr, dstPtr, tmode, NULL); } } - - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -382,14 +376,14 @@ XCopyPlane( * * TkPutImage -- * - * Copies a subimage from an in-memory image to a rectangle of - * of the specified drawable. + * Copies a subimage from an in-memory image to a rectangle of + * of the specified drawable. * * Results: - * None. + * None. * * Side effects: - * Draws the image on the specified drawable. + * Draws the image on the specified drawable. * *---------------------------------------------------------------------- */ @@ -409,9 +403,8 @@ TkPutImage( unsigned int width, /* Same width & height for both */ unsigned int height) /* distination and source. */ { - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; const BitMap * destBits; MacDrawable *dstDraw = (MacDrawable *) d; int i, j; @@ -422,9 +415,8 @@ TkPutImage( int slices, sliceRowBytes, lastSliceRowBytes, sliceWidth, lastSliceWidth; display->request++; - GetGWorld(&saveWorld, &saveDevice); destPort = TkMacOSXGetDrawablePort(d); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); destBits = GetPortBitMapForCopyBits(destPort); TkMacOSXSetUpClippingRgn(d); @@ -435,10 +427,11 @@ TkPutImage( * When rendering into a picture, after a call to "OpenCPicture" * the clipping is seriously WRONG and also INCONSISTENT with the * clipping for single plane bitmaps. - * To circumvent this problem, we clip to the whole window + * To circumvent this problem, we clip to the whole window */ Rect clpRect; + GetPortBounds(destPort,&clpRect); ClipRect(&clpRect); destPtr = srcPtr; @@ -449,14 +442,17 @@ TkPutImage( } if (image->obdata) { - /* Image from XGetImage, copy from containing GWorld directly */ - GWorldPtr srcPort = TkMacOSXGetDrawablePort((Drawable)image->obdata); - CopyBits(GetPortBitMapForCopyBits(srcPort), - destBits, srcPtr, destPtr, srcCopy, NULL); + /* + * Image from XGetImage, copy from containing GWorld directly. + */ + + CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort((Drawable) + image->obdata)), destBits, srcPtr, destPtr, srcCopy, NULL); } else if (image->depth == 1) { /* * BW image */ + const int maxRowBytes = 0x3ffe; BitMap bitmap; int odd; @@ -489,7 +485,7 @@ TkPutImage( oldPtr = dataPtr; odd = sliceRowBytes % 2; if (!newData) { - newData = (char *) ckalloc(image->height * (sliceRowBytes+odd)); + newData = ckalloc(image->height * (sliceRowBytes+odd)); } newPtr = newData; for (i = 0; i < image->height; i++) { @@ -514,6 +510,7 @@ TkPutImage( /* * Color image */ + const int maxRowBytes = 0x3ffc; PixMap pixmap; @@ -521,7 +518,7 @@ TkPutImage( pixmap.bounds.top = 0; pixmap.bounds.bottom = (short) image->height; pixmap.pixelType = RGBDirect; - pixmap.pmVersion = baseAddr32; /* 32bit clean */ + pixmap.pmVersion = baseAddr32; /* 32bit clean */ pixmap.packType = 0; pixmap.packSize = 0; pixmap.hRes = 0x00480000; @@ -582,8 +579,9 @@ TkPutImage( if (newData != NULL) { ckfree(newData); } - - SetGWorld(saveWorld, saveDevice); + if (portChanged) { + QDSwapPort(savePort, NULL); + } } /* @@ -591,74 +589,62 @@ TkPutImage( * * XDrawLines -- * - * Draw connected lines. + * Draw connected lines. * * Results: - * None. + * None. * * Side effects: - * Renders a series of connected lines. + * Renders a series of connected lines. * *---------------------------------------------------------------------- */ void XDrawLines( - Display* display, /* Display. */ + Display *display, /* Display. */ Drawable d, /* Draw on this. */ GC gc, /* Use this GC. */ - XPoint* points, /* Array of points. */ + XPoint *points, /* Array of points. */ int npoints, /* Number of points. */ int mode) /* Line drawing mode. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GWorldPtr destPort; - GDHandle saveDevice; + TkMacOSXDrawingContext dc; int i, lw = gc->line_width; if (npoints < 2) { return; /* TODO: generate BadValue error. */ } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; - float prevx, prevy; - float o = (lw % 2) ? .5 : 0; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { + double prevx, prevy; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - CGContextBeginPath(outContext); + CGContextBeginPath(dc.context); prevx = macWin->xOff + points[0].x + o; prevy = macWin->yOff + points[0].y + o; - CGContextMoveToPoint(outContext, prevx, prevy); + CGContextMoveToPoint(dc.context, prevx, prevy); for (i = 1; i < npoints; i++) { if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(outContext, + 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(outContext, prevx, prevy); + CGContextAddLineToPoint(dc.context, prevx, prevy); } } - CGContextStrokePath(outContext); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextStrokePath(dc.context); } else { int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); /* This is broken for fat lines, it is not possible to correctly * imitate X11 drawing of oblique fat lines with QD line drawing, * we should draw a filled polygon instead. */ + MoveTo((short) (macWin->xOff + points[0].x + o), (short) (macWin->yOff + points[0].y + o)); for (i = 1; i < npoints; i++) { @@ -669,10 +655,8 @@ XDrawLines( Line((short) points[i].x, (short) points[i].y); } } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -680,71 +664,58 @@ XDrawLines( * * XDrawSegments -- * - * Draw unconnected lines. + * Draw unconnected lines. * * Results: - * None. + * None. * * Side effects: - * Renders a series of unconnected lines. + * Renders a series of unconnected lines. * *---------------------------------------------------------------------- */ -void XDrawSegments( +void +XDrawSegments( Display *display, - Drawable d, + Drawable d, GC gc, XSegment *segments, - int nsegments) + int nsegments) { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GWorldPtr destPort; - GDHandle saveDevice; + TkMacOSXDrawingContext dc; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { + double o = (lw % 2) ? .5 : 0; - if (useCGDrawing) { - CGContextRef outContext; - float o = (lw % 2) ? .5 : 0; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0; i < nsegments; i++) { - CGContextBeginPath(outContext); - CGContextMoveToPoint(outContext, + CGContextBeginPath(dc.context); + CGContextMoveToPoint(dc.context, macWin->xOff + segments[i].x1 + o, macWin->yOff + segments[i].y1 + o); - CGContextAddLineToPoint(outContext, + CGContextAddLineToPoint(dc.context, macWin->xOff + segments[i].x2 + o, macWin->yOff + segments[i].y2 + o); - CGContextStrokePath(outContext); + CGContextStrokePath(dc.context); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); /* This is broken for fat lines, it is not possible to correctly * imitate X11 drawing of oblique fat lines with QD line drawing, * we should draw a filled polygon instead. */ + for (i = 0; i < nsegments; i++) { MoveTo((short) (macWin->xOff + segments[i].x1 + o), (short) (macWin->yOff + segments[i].y1 + o)); LineTo((short) (macWin->xOff + segments[i].x2 + o), (short) (macWin->yOff + segments[i].y2 + o)); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -752,13 +723,13 @@ void XDrawSegments( * * XFillPolygon -- * - * Draws a filled polygon. + * Draws a filled polygon. * * Results: - * None. + * None. * * Side effects: - * Draws a filled polygon on the specified drawable. + * Draws a filled polygon on the specified drawable. * *---------------------------------------------------------------------- */ @@ -774,45 +745,33 @@ XFillPolygon( int mode) /* Drawing mode. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int i; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; - float prevx, prevy; - float o = (gc->line_width % 2) ? .5 : 0; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { + double prevx, prevy; + double o = (gc->line_width % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - CGContextBeginPath(outContext); + CGContextBeginPath(dc.context); prevx = macWin->xOff + points[0].x + o; prevy = macWin->yOff + points[0].y + o; - CGContextMoveToPoint(outContext, prevx, prevy); + CGContextMoveToPoint(dc.context, prevx, prevy); for (i = 1; i < npoints; i++) { if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(outContext, + 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(outContext, prevx, prevy); + CGContextAddLineToPoint(dc.context, prevx, prevy); } } - CGContextEOFillPath(outContext); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextEOFillPath(dc.context); } else { PolyHandle polygon; - TkMacOSXSetUpGraphicsPort(gc, destPort); - PenNormal(); polygon = OpenPoly(); MoveTo((short) (macWin->xOff + points[0].x), (short) (macWin->yOff + points[0].y)); @@ -825,11 +784,10 @@ XFillPolygon( } } ClosePoly(); - FillCPoly(polygon, gPenPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -837,71 +795,55 @@ XFillPolygon( * * XDrawRectangle -- * - * Draws a rectangle. + * Draws a rectangle. * * Results: - * None. + * None. * * Side effects: - * Draws a rectangle on the specified drawable. + * Draws a rectangle on the specified drawable. * *---------------------------------------------------------------------- */ void XDrawRectangle( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, /* Upper left corner. */ - int y, - unsigned int width, /* Width & height of rect. */ + 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; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int lw = gc->line_width; if (width == 0 || height == 0) { return; } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); rect = CGRectMake( macWin->xOff + x + o, macWin->yOff + y + o, width, height); - CGContextStrokeRect(outContext, rect); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextStrokeRect(dc.context, rect); } else { Rect theRect; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); - theRect.left = (short) (macWin->xOff + x + o); - theRect.top = (short) (macWin->yOff + y + o); - theRect.right = (short) (theRect.left + width + lw); + theRect.left = (short) (macWin->xOff + x + o); + theRect.top = (short) (macWin->yOff + y + o); + theRect.right = (short) (theRect.left + width + lw); theRect.bottom = (short) (theRect.top + height + lw); FrameRect(&theRect); - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #ifdef TK_MACOSXDRAW_UNUSED @@ -910,27 +852,27 @@ XDrawRectangle( * * XDrawRectangles -- * - * Draws the outlines of the specified rectangles as if a - * five-point PolyLine protocol request were specified for each - * rectangle: + * 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] + * [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. + * 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. + * None. * * Side effects: - * Draws rectangles on the specified drawable. + * Draws rectangles on the specified drawable. * *---------------------------------------------------------------------- */ + void XDrawRectangles( Display *display, @@ -940,24 +882,15 @@ XDrawRectangles( int nRects) { MacDrawable *macWin = (MacDrawable *) drawable; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XRectangle * rectPtr; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(drawable); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(drawable); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) { if (rectPtr->width == 0 || rectPtr->height == 0) { continue; @@ -966,16 +899,12 @@ XDrawRectangles( macWin->xOff + rectPtr->x + o, macWin->yOff + rectPtr->y + o, rectPtr->width, rectPtr->height); - CGContextStrokeRect(outContext, rect); + CGContextStrokeRect(dc.context, rect); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); for (i = 0, rectPtr = rectArr; i < nRects;i++, rectPtr++) { theRect.left = (short) (macWin->xOff + rectPtr->x + o); theRect.top = (short) (macWin->yOff + rectPtr->y + o); @@ -983,10 +912,8 @@ XDrawRectangles( theRect.bottom = (short) (theRect.top + rectPtr->height + lw); FrameRect(&theRect); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -995,42 +922,34 @@ XDrawRectangles( * * XFillRectangles -- * - * Fill multiple rectangular areas in the given drawable. + * Fill multiple rectangular areas in the given drawable. * * Results: - * None. + * None. * * Side effects: - * Draws onto the specified drawable. + * Draws onto the specified drawable. * *---------------------------------------------------------------------- */ + void XFillRectangles( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - XRectangle *rectangles, /* Rectangle array. */ - int n_rectangles) /* Number of rectangles. */ + 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; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XRectangle * rectPtr; int i; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) { if (rectPtr->width == 0 || rectPtr->height == 0) { continue; @@ -1039,23 +958,20 @@ XFillRectangles( macWin->xOff + rectPtr->x, macWin->yOff + rectPtr->y, rectPtr->width, rectPtr->height); - CGContextFillRect(outContext, rect); + CGContextFillRect(dc.context, rect); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; - TkMacOSXSetUpGraphicsPort(gc, destPort); for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) { theRect.left = (short) (macWin->xOff + rectPtr->x); theRect.top = (short) (macWin->yOff + rectPtr->y); theRect.right = (short) (theRect.left + rectPtr->width); theRect.bottom = (short) (theRect.top + rectPtr->height); - FillCRect(&theRect, gPenPat); + FillCRect(&theRect, dc.penPat); } } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } /* @@ -1063,98 +979,85 @@ XFillRectangles( * * XDrawArc -- * - * Draw an arc. + * Draw an arc. * * Results: - * None. + * None. * * Side effects: - * Draws an arc on the specified drawable. + * Draws an arc on the specified drawable. * *---------------------------------------------------------------------- */ void XDrawArc( - Display* display, /* Display. */ - Drawable d, /* Draw on this. */ - GC gc, /* Use this GC. */ - int x, /* Upper left of */ - int y, /* bounding rect. */ - unsigned int width, /* Width & height. */ + 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. */ + int angle1, /* Staring angle of arc. */ + int angle2) /* Extent of arc. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int lw = gc->line_width; if (width == 0 || height == 0 || angle2 == 0) { return; } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); rect = CGRectMake( macWin->xOff + x + o, macWin->yOff + y + o, width, height); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (angle1 == 0 && angle2 == 23040 && - CGContextStrokeEllipseInRect != NULL) { - CGContextStrokeEllipseInRect(outContext, rect); + if (angle1 == 0 && angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextStrokeEllipseInRect != NULL +#endif + ) { + CGContextStrokeEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + double w = CGRectGetWidth(rect); if (width != height) { - t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); + 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(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextStrokePath(outContext); + CGContextStrokePath(dc.context); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); - theRect.left = (short) (macWin->xOff + x + o); - theRect.top = (short) (macWin->yOff + y + o); - theRect.right = (short) (theRect.left + width + lw); + theRect.left = (short) (macWin->xOff + x + o); + theRect.top = (short) (macWin->yOff + y + o); + theRect.right = (short) (theRect.left + width + lw); theRect.bottom = (short) (theRect.top + height + lw); - start = (short) (90 - (angle1/64)); + start = (short) (90 - (angle1/64)); extent = (short) (-(angle2/64)); FrameArc(&theRect, start, extent); - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #ifdef TK_MACOSXDRAW_UNUSED @@ -1163,23 +1066,24 @@ XDrawArc( * * 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. + * 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. + * None. * * Side effects: - * Draws an arc for each array element on the specified drawable. + * Draws an arc for each array element on the specified drawable. * *---------------------------------------------------------------------- */ + void XDrawArcs( Display *display, @@ -1190,24 +1094,15 @@ XDrawArcs( { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - XArc * arcPtr; + TkMacOSXDrawingContext dc; + XArc *arcPtr; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0; + double o = (lw % 2) ? .5 : 0; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { if (arcPtr->width == 0 || arcPtr->height == 0 || arcPtr->angle2 == 0) { @@ -1219,41 +1114,40 @@ XDrawArcs( arcPtr->width, arcPtr->height); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 && - CGContextStrokeEllipseInRect != NULL) { - CGContextStrokeEllipseInRect(outContext, rect); + if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextStrokeEllipseInRect != NULL +#endif + ) { + CGContextStrokeEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), - CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + CGRectGetMidY(rect)); + double w = CGRectGetWidth(rect); if (arcPtr->width != arcPtr->height) { t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); c = CGPointApplyAffineTransform(c, - CGAffineTransformInvert(t)); + 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(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextStrokePath(outContext); + CGContextStrokePath(dc.context); } } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; int o = -lw/2; - TkMacOSXSetUpGraphicsPort(gc, destPort); - ShowPen(); - PenPixPat(gPenPat); for (i = 0, arcPtr = arcArr;i < nArcs;i++, arcPtr++) { theRect.left = (short) (macWin->xOff + arcPtr->x + o); theRect.top = (short) (macWin->yOff + arcPtr->y + o); @@ -1263,10 +1157,8 @@ XDrawArcs( extent = (short) (-(arcPtr->angle2/64)); FrameArc(&theRect, start, extent); } - HidePen(); } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -1275,71 +1167,64 @@ XDrawArcs( * * XFillArc -- * - * Draw a filled arc. + * Draw a filled arc. * * Results: - * None. + * None. * * Side effects: - * Draws a filled arc on the specified drawable. + * 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, /* Upper left of */ - int y, /* bounding rect. */ - unsigned int width, /* Width & height. */ + 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. */ + int angle1, /* Staring angle of arc. */ + int angle2) /* Extent of arc. */ { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; int lw = gc->line_width; if (width == 0 || height == 0 || angle2 == 0) { return; } - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0, u = 0; + double o = (lw % 2) ? .5 : 0, u = 0; if (notAA(lw)) { o += NON_AA_CG_OFFSET/2; u += NON_AA_CG_OFFSET; } - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); rect = CGRectMake( macWin->xOff + x + o, macWin->yOff + y + o, width - u, height - u); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (angle1 == 0 && angle2 == 23040 && - CGContextFillEllipseInRect != NULL) { - CGContextFillEllipseInRect(outContext, rect); + if (angle1 == 0 && angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextFillEllipseInRect != NULL +#endif + ) { + CGContextFillEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + double w = CGRectGetWidth(rect); if (width != height) { t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); @@ -1351,11 +1236,10 @@ XFillArc( CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0), radians(-(angle1 + angle2)/64.0), angle2 > 0); CGPathCloseSubpath(p); - CGContextAddPath(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextFillPath(outContext); + CGContextFillPath(dc.context); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; @@ -1365,10 +1249,9 @@ XFillArc( double boxWidth, boxHeight; double vertex[2], center1[2], center2[2]; - TkMacOSXSetUpGraphicsPort(gc, destPort); - theRect.left = (short) (macWin->xOff + x + o); - theRect.top = (short) (macWin->yOff + y + o); - theRect.right = (short) (theRect.left + width + lw); + theRect.left = (short) (macWin->xOff + x + o); + theRect.top = (short) (macWin->yOff + y + o); + theRect.right = (short) (theRect.left + width + lw); theRect.bottom = (short) (theRect.top + height + lw); start = (short) (90 - (angle1/64)); extent = (short) (-(angle2/64)); @@ -1394,19 +1277,14 @@ XFillArc( LineTo((short) (center1[0] + .5), (short) (center1[1] + .5)); LineTo((short) (center2[0] + .5), (short) (center2[1] + .5)); ClosePoly(); - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - FillCPoly(polygon, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } else { - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); } } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #ifdef TK_MACOSXDRAW_UNUSED @@ -1415,16 +1293,17 @@ XFillArc( * * XFillArcs -- * - * Draw a filled arc. + * Draw a filled arc. * * Results: - * None. + * None. * * Side effects: - * Draws a filled arc for each array element on the specified drawable. + * Draws a filled arc for each array element on the specified drawable. * *---------------------------------------------------------------------- */ + void XFillArcs( Display *display, @@ -1434,28 +1313,19 @@ XFillArcs( int nArcs) { MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + TkMacOSXDrawingContext dc; XArc * arcPtr; int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); - - if (useCGDrawing) { - CGContextRef outContext; + if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) { CGRect rect; - float o = (lw % 2) ? .5 : 0, u = 0; + double o = (lw % 2) ? .5 : 0, u = 0; if (notAA(lw)) { o += NON_AA_CG_OFFSET/2; u += NON_AA_CG_OFFSET; } - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i = 0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { if (arcPtr->width == 0 || arcPtr->height == 0 || arcPtr->angle2 == 0) { @@ -1467,22 +1337,25 @@ XFillArcs( arcPtr->width - u, arcPtr->height - u); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 && - CGContextFillEllipseInRect != NULL) { - CGContextFillEllipseInRect(outContext, rect); + if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 + && CGContextFillEllipseInRect != NULL +#endif + ) { + CGContextFillEllipseInRect(dc.context, rect); } else #endif { CGMutablePathRef p = CGPathCreateMutable(); CGAffineTransform t = CGAffineTransformIdentity; CGPoint c = CGPointMake(CGRectGetMidX(rect), - CGRectGetMidY(rect)); - float w = CGRectGetWidth(rect); + CGRectGetMidY(rect)); + double w = CGRectGetWidth(rect); if (arcPtr->width != arcPtr->height) { t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w); c = CGPointApplyAffineTransform(c, - CGAffineTransformInvert(t)); + CGAffineTransformInvert(t)); } if (gc->arc_mode == ArcPieSlice) { CGPathMoveToPoint(p, &t, c.x, c.y); @@ -1492,12 +1365,11 @@ XFillArcs( radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0), arcPtr->angle2 > 0); CGPathCloseSubpath(p); - CGContextAddPath(outContext, p); + CGContextAddPath(dc.context, p); CGPathRelease(p); - CGContextFillPath(outContext); + CGContextFillPath(dc.context); } } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { Rect theRect; short start, extent; @@ -1507,7 +1379,6 @@ XFillArcs( double boxWidth, boxHeight; double vertex[2], center1[2], center2[2]; - TkMacOSXSetUpGraphicsPort(gc, destPort); for (i = 0, arcPtr = arcArr;i<nArcs;i++, arcPtr++) { theRect.left = (short) (macWin->xOff + arcPtr->x + o); theRect.top = (short) (macWin->yOff + arcPtr->y + o); @@ -1538,20 +1409,15 @@ XFillArcs( LineTo((short) (center1[0] + .5), (short) (center1[1] + .5)); LineTo((short) (center2[0] + .5), (short) (center2[1] + .5)); ClosePoly(); - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - FillCPoly(polygon, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); + FillCPoly(polygon, dc.penPat); KillPoly(polygon); } else { - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - HidePen(); + FillCArc(&theRect, start, extent, dc.penPat); } } } - - SetGWorld(saveWorld, saveDevice); + TkMacOSXRestoreDrawingContext(&dc); } #endif @@ -1563,8 +1429,10 @@ XFillArcs( * *---------------------------------------------------------------------- */ + long -XMaxRequestSize(Display *display) +XMaxRequestSize( + Display *display) { return (SHRT_MAX / 4); } @@ -1575,51 +1443,45 @@ XMaxRequestSize(Display *display) * * TkScrollWindow -- * - * Scroll a rectangle of the specified window and accumulate - * a damage region. + * 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. + * 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. + * 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, /* Position rectangle to be scrolled. */ - int y, - int width, - int height, - int dx, /* Distance rectangle should be moved. */ - int dy, - TkRegion damageRgn) /* Region to accumulate damage in. */ + 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. */ { MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin); RgnHandle rgn = (RgnHandle) damageRgn; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; + CGrafPtr destPort, savePort; + Boolean portChanged; Rect srcRect, scrollRect; - RgnHandle visRgn, clipRgn; destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); /* * Due to the implementation below the behavior may be differnt - * than X in certain cases that should never occur in Tk. The + * than X in certain cases that should never occur in Tk. The * scrollRect is the source rect extended by the offset (the union - * of the source rect and the offset rect). Everything - * in the extended scrollRect is scrolled. On X, it's possible + * of the source rect and the offset rect). Everything + * in the extended scrollRect is scrolled. On X, it's possible * to "skip" over an area if the offset makes the source and * destination rects disjoint and non-aligned. */ @@ -1644,45 +1506,27 @@ TkScrollWindow( * Adjust clip region so that we don't copy any windows * that may overlap us. */ - visRgn = NewRgn(); - clipRgn = NewRgn(); + + TkMacOSXCheckTmpRgnEmpty(1); + TkMacOSXCheckTmpRgnEmpty(2); RectRgn(rgn, &srcRect); - GetPortVisibleRegion(destPort,visRgn); - DiffRgn(rgn, visRgn, rgn); + GetPortVisibleRegion(destPort,tkMacOSXtmpRgn1); + DiffRgn(rgn, tkMacOSXtmpRgn1, rgn); OffsetRgn(rgn, dx, dy); - GetPortClipRegion(destPort, clipRgn); - DiffRgn(clipRgn, rgn, clipRgn); - SetPortClipRegion(destPort, clipRgn); + GetPortClipRegion(destPort, tkMacOSXtmpRgn2); + DiffRgn(tkMacOSXtmpRgn2, rgn, tkMacOSXtmpRgn2); + SetPortClipRegion(destPort, tkMacOSXtmpRgn2); + SetEmptyRgn(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn2); SetEmptyRgn(rgn); - /* - * When a menu is up, the Mac does not expect drawing to occur and - * does not clip out the menu. We have to do it ourselves. This - * is pretty gross. - */ - - if (tkUseMenuCascadeRgn == 1) { - Point scratch = {0, 0}; - MacDrawable *macDraw = (MacDrawable *) Tk_WindowId(tkwin); - - LocalToGlobal(&scratch); - CopyRgn(tkMenuCascadeRgn, rgn); - OffsetRgn(rgn, -scratch.h, -scratch.v); - DiffRgn(clipRgn, rgn, clipRgn); - SetPortClipRegion(destPort, clipRgn); - SetEmptyRgn(rgn); - macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU; - } - ScrollRect(&scrollRect, dx, dy, rgn); - - SetGWorld(saveWorld, saveDevice); - - DisposeRgn(clipRgn); - DisposeRgn(visRgn); + if (portChanged) { + QDSwapPort(savePort, NULL); + } /* - * Fortunantly, the region returned by ScrollRect is symanticlly - * the same as what we need to return in this function. If the + * Fortunately, the region returned by ScrollRect is semantically + * the same as what we need to return in this function. If the * region is empty we return zero to denote that no damage was * created. */ @@ -1698,220 +1542,300 @@ TkScrollWindow( * * TkMacOSXSetUpGraphicsPort -- * - * Set up the graphics port from the given GC. + * Set up the graphics port from the given GC. * * Results: - * None. + * None. * * Side effects: - * The current port is adjusted. + * The current port is adjusted. * *---------------------------------------------------------------------- */ void TkMacOSXSetUpGraphicsPort( - GC gc, - GWorldPtr destPort) /* GC to apply to current port. */ + GC gc, /* GC to apply to current port. */ + GWorldPtr destPort) { - RGBColor macColor; - - if (gPenPat == NULL) { - gPenPat = NewPixPat(); - } - - if (TkSetMacColor(gc->foreground, &macColor) == true) { - /* TODO: cache RGBPats for preformace - measure gains... */ - MakeRGBPat(gPenPat, &macColor); - } - PenNormal(); - if(gc->function == GXxor) { - PenMode(patXor); - } - if (gc->line_width > 1) { - PenSize(gc->line_width, gc->line_width); - } - if (gc->line_style != LineSolid) { - /* - * Here the dash pattern should be set in the drawing, - * environment, but I don't know how to do that for the Mac. - * - * p[] is an array of unsigned chars containing the dash list. - * A '\0' indicates the end of this list. - * - * Someone knows how to implement this? If you have a more - * complete implementation of SetUpGraphicsPort() for - * the Mac (or for Windows), please let me know. - * - * Jan Nijtmans - * CMG Arnhem, B.V. - * email: j.nijtmans@chello.nl (private) - * jan.nijtmans@cmg.nl (work) - * url: http://purl.oclc.org/net/nijtmans/ - * - * FIXME: - * This is not possible with QuickDraw line drawing. As of - * Tk 8.4.7 we have a complete set of drawing routines using - * CG, so there is no reason to support this here. - */ + if (gc) { + if (gPenPat == NULL) { + gPenPat = NewPixPat(); + } + TkMacOSXSetColorInPort(gc->foreground, 1, gPenPat); + PenPixPat(gPenPat); + if(gc->function == GXxor) { + PenMode(patXor); + } + if (gc->line_width > 1) { + PenSize(gc->line_width, gc->line_width); + } + if (gc->line_style != LineSolid) { + /* + * FIXME: + * Here the dash pattern should be set in the drawing environment. + * This is not possible with QuickDraw line drawing. + */ + } } } /* *---------------------------------------------------------------------- * - * TkMacOSXSetUpCGContext -- + * TkMacOSXSetUpDrawingContext -- * - * Set up a CGContext for the given graphics port. + * Set up a drawing context for the given drawable and GC. * * Results: - * None. + * Boolean indicating whether to use CG drawing. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static void -TkMacOSXSetUpCGContext( - MacDrawable *macWin, - CGrafPtr destPort, - GC gc, - CGContextRef *contextPtr) +int +TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG, + TkMacOSXDrawingContext *dc) { - RGBColor macColor; - CGContextRef outContext; - OSStatus err; - Rect boundsRect; - CGAffineTransform coordsTransform; - static RgnHandle clipRgn = NULL; - float w; - - err = QDBeginCGContext(destPort, contextPtr); - outContext = *contextPtr; - - /* - * Now clip the CG Context to the port. Note, we have already - * set up the port with our clip region, so we can just get - * the clip back out of there. If we use the macWin->clipRgn - * directly at this point, we get some odd drawing effects. - * - * We also have to intersect our clip region with the port - * visible region so we don't overwrite the window decoration. - */ - - if (!clipRgn) { - clipRgn = NewRgn(); + MacDrawable *macDraw = ((MacDrawable*)d); + CGContextRef context = macDraw->context; + CGrafPtr port; + Rect portBounds; + + port = TkMacOSXGetDrawablePort(d); + if (port) { + GetPortBounds(port, &portBounds); } - GetPortBounds(destPort, &boundsRect); - - RectRgn(clipRgn, &boundsRect); - SectRegionWithPortClipRegion(destPort, clipRgn); - SectRegionWithPortVisibleRegion(destPort, clipRgn); - ClipCGContextToRegion(outContext, &boundsRect, clipRgn); - SetEmptyRgn(clipRgn); + dc->saveState = NULL; + if (port && !context) { + dc->portChanged = QDSwapPort(port, &(dc->savePort)); + TkMacOSXSetUpClippingRgn(d); + TkMacOSXCheckTmpRgnEmpty(1); + if (useCG) { + if (ChkErr(QDBeginCGContext, port, &context) == noErr) { + /* + * Now clip the CG Context to the port. Note, we have already + * set up the port with our clip region, so we can just get + * the clip back out of there. If we use the macWin->clipRgn + * directly at this point, we get some odd drawing effects. + * + * We also have to intersect our clip region with the port + * visible region so we don't overwrite the window decoration. + */ + + RectRgn(tkMacOSXtmpRgn1, &portBounds); + SectRegionWithPortClipRegion(port, tkMacOSXtmpRgn1); + SectRegionWithPortVisibleRegion(port, tkMacOSXtmpRgn1); + if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + RgnHandle clipRgn = (RgnHandle) + ((TkpClipMask*)gc->clip_mask)->value.region; + int xOffset = macDraw->xOff + gc->clip_x_origin; + int yOffset = macDraw->yOff + gc->clip_y_origin; + + OffsetRgn(clipRgn, xOffset, yOffset); + SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + OffsetRgn(clipRgn, -xOffset, -yOffset); + } + ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); - /* - * Note: You have to call SyncCGContextOriginWithPort - * AFTER all the clip region manipulations. - */ + /* + * Note: You have to call SyncCGContextOriginWithPort + * AFTER all the clip region manipulations. + */ - SyncCGContextOriginWithPort(outContext, destPort); - - coordsTransform = CGAffineTransformMake(1, 0, 0, -1, 0, - boundsRect.bottom - boundsRect.top); - CGContextConcatCTM(outContext, coordsTransform); - - /* Now offset the CTM to the subwindow offset */ - - if (TkSetMacColor(gc->foreground, &macColor) == true) { - CGContextSetRGBFillColor(outContext, - RGBFLOATRED(macColor), - RGBFLOATGREEN(macColor), - RGBFLOATBLUE(macColor), - 1); - CGContextSetRGBStrokeColor(outContext, - RGBFLOATRED(macColor), - RGBFLOATGREEN(macColor), - RGBFLOATBLUE(macColor), - 1); - } + SyncCGContextOriginWithPort(context, port); + } else { + context = NULL; + useCG = 0; + } + } + } else if (context) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (!port +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 + && CGContextGetClipBoundingBox != NULL +#endif + ) { + CGRect r = CGContextGetClipBoundingBox(context); - if(gc->function == GXxor) { - } + SetRect(&portBounds, r.origin.x + macDraw->xOff, + r.origin.y + macDraw->yOff, + r.origin.x + r.size.width + macDraw->xOff, + r.origin.y + r.size.height + macDraw->yOff); + } +#endif + CGContextSaveGState(context); + TkMacOSXCheckTmpRgnEmpty(1); + RectRgn(tkMacOSXtmpRgn1, &portBounds); + if (port) { + TkMacOSXSetUpClippingRgn(d); + SectRegionWithPortClipRegion(port, tkMacOSXtmpRgn1); + SectRegionWithPortVisibleRegion(port, tkMacOSXtmpRgn1); + } else if (macDraw->flags & TK_CLIPPED_DRAW) { + OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); + SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpRgn1); + OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + } + if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + RgnHandle clipRgn = (RgnHandle) + ((TkpClipMask*)gc->clip_mask)->value.region; + int xOffset = macDraw->xOff + gc->clip_x_origin; + int yOffset = macDraw->yOff + gc->clip_y_origin; - w = gc->line_width; - /* When should we antialias? */ - if (notAA(gc->line_width)) { - /* Make non-antialiased CG drawing look more like X11 */ - w -= (gc->line_width ? NON_AA_CG_OFFSET : 0); - CGContextSetShouldAntialias(outContext, 0); - } else { - CGContextSetShouldAntialias(outContext, 1); + OffsetRgn(clipRgn, xOffset, yOffset); + SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + OffsetRgn(clipRgn, -xOffset, -yOffset); + } + ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); + port = NULL; + dc->portChanged = false; + dc->saveState = (void*)1; + useCG = 1; } - CGContextSetLineWidth(outContext, w); + if (useCG) { + CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, + 0.0, portBounds.bottom - portBounds.top)); + if (gc) { + double w = gc->line_width; + + TkMacOSXSetColorInContext(gc->foreground, context); + if (port) { + CGContextSetPatternPhase(context, CGSizeMake(portBounds.right - + portBounds.left, portBounds.bottom - portBounds.top)); + } + if(gc->function == GXxor) { + TkMacOSXDbgMsg("GXxor mode not supported for CG drawing!"); + } + /* When should we antialias? */ + if (notAA(gc->line_width)) { + /* Make non-antialiased CG drawing look more like X11 */ + w -= (gc->line_width ? NON_AA_CG_OFFSET : 0); + CGContextSetShouldAntialias(context, 0); + } else { + CGContextSetShouldAntialias(context, 1); + } + CGContextSetLineWidth(context, w); - if (gc->line_style != LineSolid) { - int num = 0; - char *p = &(gc->dashes); - float dashOffset = gc->dash_offset; - float lengths[10]; + if (gc->line_style != LineSolid) { + int num = 0; + char *p = &(gc->dashes); + double dashOffset = gc->dash_offset; + float lengths[10]; - while (p[num] != '\0') { - lengths[num] = p[num]; - num++; - } - CGContextSetLineDash(outContext, dashOffset, lengths, num); - } + while (p[num] != '\0' && num < 10) { + lengths[num] = p[num]; + num++; + } + CGContextSetLineDash(context, dashOffset, lengths, num); + } - if (gc->cap_style == CapButt) { - /* - * What about CapNotLast, CapProjecting? - */ + if (gc->cap_style == CapButt) { + /* + * What about CapNotLast, CapProjecting? + */ - CGContextSetLineCap(outContext, kCGLineCapButt); - } else if (gc->cap_style == CapRound) { - CGContextSetLineCap(outContext, kCGLineCapRound); - } else if (gc->cap_style == CapProjecting) { - CGContextSetLineCap(outContext, kCGLineCapSquare); - } + CGContextSetLineCap(context, kCGLineCapButt); + } else if (gc->cap_style == CapRound) { + CGContextSetLineCap(context, kCGLineCapRound); + } else if (gc->cap_style == CapProjecting) { + CGContextSetLineCap(context, kCGLineCapSquare); + } - if (gc->join_style == JoinMiter) { - CGContextSetLineJoin(outContext, kCGLineJoinMiter); - } else if (gc->join_style == JoinRound) { - CGContextSetLineJoin(outContext, kCGLineJoinRound); - } else if (gc->join_style == JoinBevel) { - CGContextSetLineJoin(outContext, kCGLineJoinBevel); + if (gc->join_style == JoinMiter) { + CGContextSetLineJoin(context, kCGLineJoinMiter); + } else if (gc->join_style == JoinRound) { + CGContextSetLineJoin(context, kCGLineJoinRound); + } else if (gc->join_style == JoinBevel) { + CGContextSetLineJoin(context, kCGLineJoinBevel); + } + } + } else { + ChkErr(GetThemeDrawingState, &(dc->saveState)); + if (gc) { + PixPatHandle savePat = gPenPat; + + gPenPat = NULL; + TkMacOSXSetUpGraphicsPort(gc, port); + dc->penPat = gPenPat; + gPenPat = savePat; + if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type + == TKP_CLIP_REGION) { + RgnHandle clipRgn = (RgnHandle) + ((TkpClipMask*)gc->clip_mask)->value.region; + int xOffset = macDraw->xOff + gc->clip_x_origin; + int yOffset = macDraw->yOff + gc->clip_y_origin; + + OffsetRgn(clipRgn, xOffset, yOffset); + GetClip(tkMacOSXtmpRgn1); + SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1); + SetClip(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); + OffsetRgn(clipRgn, -xOffset, -yOffset); + } + } else { + TkMacOSXSetUpGraphicsPort(NULL, port); + dc->penPat = NULL; + } + ShowPen(); } + dc->port = port; + dc->portBounds = portBounds; + dc->context = context; + return useCG; } /* *---------------------------------------------------------------------- * - * TkMacOSXReleaseCGContext -- + * TkMacOSXRestoreDrawingContext -- * - * Release the CGContext for the given graphics port. + * Restore drawing context. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ -static void -TkMacOSXReleaseCGContext( - MacDrawable *macWin, - CGrafPtr destPort, - CGContextRef *outContext) +void +TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc) { - CGContextSynchronize(*outContext); - QDEndCGContext(destPort, outContext); + if (dc->context) { + CGContextSynchronize(dc->context); + if (dc->saveState) { + CGContextRestoreGState(dc->context); + } + if (dc->port) { + ChkErr(QDEndCGContext, dc->port, &(dc->context)); + } + } else { + HidePen(); + PenNormal(); + if (dc->penPat) { + DisposePixPat(dc->penPat); + } + if (dc->saveState) { + ChkErr(SetThemeDrawingState, dc->saveState, true); + } + } + if (dc->portChanged) { + QDSwapPort(dc->savePort, NULL); + } +#ifdef TK_MAC_DEBUG + bzero(dc, sizeof(dc)); +#endif /* TK_MAC_DEBUG */ } /* @@ -1919,21 +1843,21 @@ TkMacOSXReleaseCGContext( * * TkMacOSXSetUpClippingRgn -- * - * Set up the clipping region so that drawing only occurs on the - * specified X subwindow. + * Set up the clipping region so that drawing only occurs on the + * specified X subwindow. * * Results: - * None. + * None. * * Side effects: - * The clipping region in the current port is changed. + * The clipping region in the current port is changed. * *---------------------------------------------------------------------- */ void TkMacOSXSetUpClippingRgn( - Drawable drawable) /* Drawable to update. */ + Drawable drawable) /* Drawable to update. */ { MacDrawable *macDraw = (MacDrawable *) drawable; @@ -1942,43 +1866,72 @@ TkMacOSXSetUpClippingRgn( TkMacOSXUpdateClipRgn(macDraw->winPtr); } -#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_DRAWING) +#ifdef TK_MAC_DEBUG_DRAWING TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, - CGrafPtr port, RgnHandle region); + CGrafPtr port, RgnHandle region); if (QDDebugFlashRegion) { CGrafPtr grafPtr = TkMacOSXGetDrawablePort(drawable); - /* Carbon-internal region flashing SPI (c.f. Technote 2124) */ + + /* + * Carbon-internal region flashing SPI (c.f. Technote 2124) + */ + QDDebugFlashRegion(grafPtr, macDraw->clipRgn); } #endif /* TK_MAC_DEBUG_DRAWING */ + } - /* - * When a menu is up, the Mac does not expect drawing to occur and - * does not clip out the menu. We have to do it ourselves. This - * is pretty gross. - */ + if (macDraw->clipRgn != NULL) { + if (macDraw->flags & TK_CLIPPED_DRAW) { + TkMacOSXCheckTmpRgnEmpty(1); + OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); + SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpRgn1); + OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + SetClip(tkMacOSXtmpRgn1); + SetEmptyRgn(tkMacOSXtmpRgn1); + } else { + SetClip(macDraw->clipRgn); + } + } else if (macDraw->flags & TK_CLIPPED_DRAW) { + OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff); + SetClip(macDraw->drawRgn); + OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkpClipDrawableToRect -- + * + * Clip all drawing into the drawable d to the given rectangle. + * If width and height are negative, reset to no clipping. + * + * Results: + * None. + * + * Side effects: + * Subsequent drawing into d is offset and clipped as specified. + * + *---------------------------------------------------------------------- + */ - if (macDraw->clipRgn != NULL) { - if (tkUseMenuCascadeRgn == 1) { - Point scratch = {0, 0}; - GDHandle saveDevice; - GWorldPtr saveWorld; - - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(TkMacOSXGetDrawablePort(drawable), NULL); - LocalToGlobal(&scratch); - SetGWorld(saveWorld, saveDevice); - if (tmpRgn == NULL) { - tmpRgn = NewRgn(); - } - CopyRgn(tkMenuCascadeRgn, tmpRgn); - OffsetRgn(tmpRgn, -scratch.h, -scratch.v); - DiffRgn(macDraw->clipRgn, tmpRgn, tmpRgn); - SetClip(tmpRgn); - macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU; - } else { - SetClip(macDraw->clipRgn); - } +void +TkpClipDrawableToRect( + Display *display, + Drawable d, + int x, int y, + int width, int height) +{ + MacDrawable *macDraw = (MacDrawable *) d; + + if (macDraw->drawRgn) { + if (width < 0 && height < 0) { + SetEmptyRgn(macDraw->drawRgn); + macDraw->flags &= ~TK_CLIPPED_DRAW; + } else { + SetRectRgn(macDraw->drawRgn, x, y, x + width, y + height); + macDraw->flags |= TK_CLIPPED_DRAW; } } } @@ -1988,48 +1941,45 @@ TkMacOSXSetUpClippingRgn( * * 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. + * 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. + * A BitMap data structure. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ BitMapPtr TkMacOSXMakeStippleMap( - Drawable drawable, /* Window to apply stipple. */ - Drawable stipple) /* The stipple pattern. */ + Drawable drawable, /* Window to apply stipple. */ + Drawable stipple) /* The stipple pattern. */ { - GWorldPtr destPort; + CGrafPtr stipplePort; BitMapPtr bitmapPtr; - Rect portRect; - int width, height, stippleHeight, stippleWidth; - int i, j; - char * data; + const BitMap *stippleBitmap; + Rect portRect; + int width, height, stippleHeight, stippleWidth, i, j; Rect bounds; - destPort = TkMacOSXGetDrawablePort(drawable); - - GetPortBounds (destPort, &portRect); + GetPortBounds(TkMacOSXGetDrawablePort(drawable), &portRect); width = portRect.right - portRect.left; height = portRect.bottom - portRect.top; - bitmapPtr = (BitMap *) ckalloc(sizeof(BitMap)); - data = (char *) ckalloc(height * ((width / 8) + 1)); bitmapPtr->bounds.top = bitmapPtr->bounds.left = 0; bitmapPtr->bounds.right = (short) width; bitmapPtr->bounds.bottom = (short) height; - bitmapPtr->baseAddr = data; bitmapPtr->rowBytes = (width / 8) + 1; + bitmapPtr->baseAddr = ckalloc(height * bitmapPtr->rowBytes); - destPort = TkMacOSXGetDrawablePort(stipple); + stipplePort = TkMacOSXGetDrawablePort(stipple); + stippleBitmap = GetPortBitMapForCopyBits(stipplePort); + GetPortBounds(stipplePort, &portRect); stippleWidth = portRect.right - portRect.left; stippleHeight = portRect.bottom - portRect.top; @@ -2039,9 +1989,8 @@ TkMacOSXMakeStippleMap( bounds.top = i; bounds.right = j + stippleWidth; bounds.bottom = i + stippleHeight; - - CopyBits(GetPortBitMapForCopyBits(destPort), bitmapPtr, - &portRect, &bounds, srcCopy, NULL); + CopyBits(stippleBitmap, bitmapPtr, &portRect, &bounds, srcCopy, + NULL); } } return bitmapPtr; @@ -2052,20 +2001,20 @@ TkMacOSXMakeStippleMap( * * InvertByte -- * - * This function reverses the bits in the passed in Byte of data. + * This function reverses the bits in the passed in Byte of data. * * Results: - * The incoming byte in reverse bit order. + * The incoming byte in reverse bit order. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ static unsigned char InvertByte( - unsigned char data) /* Byte of data. */ + unsigned char data) /* Byte of data. */ { unsigned char i; unsigned char mask = 1, result = 0; @@ -2084,32 +2033,32 @@ InvertByte( * * TkpDrawHighlightBorder -- * - * This procedure draws a rectangular ring around the outside of - * a widget to indicate that it has received the input focus. + * 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. + * 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. + * For proper Mac L&F, use highlightWidth of 3. * * Results: - * None. + * None. * * Side effects: - * A rectangle "width" pixels wide is drawn in "drawable", - * corresponding to the outer area of "tkwin". + * 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) + Tk_Window tkwin, + GC fgGC, + GC bgGC, + int highlightWidth, + Drawable drawable) { if (highlightWidth == 1) { TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth, drawable, 0); @@ -2127,7 +2076,7 @@ TkpDrawHighlightBorder ( * * TkpDrawFrame -- * - * This procedure draws the rectangular frame area. If the user + * This procedure draws the rectangular frame area. If the user * has request themeing, it draws with a the background theme. * * Results: @@ -2140,52 +2089,27 @@ TkpDrawHighlightBorder ( */ void -TkpDrawFrame (Tk_Window tkwin, Tk_3DBorder border, - int highlightWidth, int borderWidth, int relief) +TkpDrawFrame( + Tk_Window tkwin, + Tk_3DBorder border, + int highlightWidth, + int borderWidth, + int relief) { if (useThemedToplevel && Tk_IsTopLevel(tkwin)) { - /* - * Currently only support themed toplevels, until we can better - * factor this to handle individual windows (blanket theming of - * frames will work for very few UIs). - */ - Rect bounds; - Point origin; - CGrafPtr saveWorld; - GDHandle saveDevice; - XGCValues gcValues; - GC gc; - Pixmap pixmap; - Display *display = Tk_Display(tkwin); - - pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); - - gc = Tk_GetGC(tkwin, 0, &gcValues); - TkMacOSXWinBounds((TkWindow *) tkwin, &bounds); - origin.v = -bounds.top; - origin.h = -bounds.left; - bounds.top = bounds.left = 0; - bounds.right = Tk_Width(tkwin); - bounds.bottom = Tk_Height(tkwin); - - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(TkMacOSXGetDrawablePort(pixmap), 0); - ApplyThemeBackground(kThemeBackgroundWindowHeader, &bounds, - kThemeStateActive, 32 /* depth */, true /* inColor */); - QDSetPatternOrigin(origin); - EraseRect(&bounds); - SetGWorld(saveWorld, saveDevice); - - XCopyArea(display, pixmap, Tk_WindowId(tkwin), - gc, 0, 0, bounds.right, bounds.bottom, 0, 0); - Tk_FreePixmap(display, pixmap); - Tk_FreeGC(display, gc); - } else { - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), - border, highlightWidth, highlightWidth, - Tk_Width(tkwin) - 2 * highlightWidth, - Tk_Height(tkwin) - 2 * highlightWidth, - borderWidth, relief); + 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); } |