diff options
Diffstat (limited to 'carbon/tkMacOSXDraw.c')
-rw-r--r-- | carbon/tkMacOSXDraw.c | 2117 |
1 files changed, 0 insertions, 2117 deletions
diff --git a/carbon/tkMacOSXDraw.c b/carbon/tkMacOSXDraw.c deleted file mode 100644 index 6f40e5d..0000000 --- a/carbon/tkMacOSXDraw.c +++ /dev/null @@ -1,2117 +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, Apple Computer, Inc. - * 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. - */ - -#include "tkMacOSXPrivate.h" -#include "tkMacOSXDebug.h" -#include "xbytes.h" - -/* -#ifdef TK_MAC_DEBUG -#define TK_MAC_DEBUG_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 - -/* - * Temporary region that can be reused. - */ - -RgnHandle tkMacOSXtmpQdRgn = NULL; - -int tkMacOSXUseCGDrawing = 1; - -int tkPictureIsOpen; - -static PixPatHandle penPat = NULL, tmpPixPat = NULL; - -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 void NoQDClip(CGrafPtr port); - - -/* - *---------------------------------------------------------------------- - * - * 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::useCGDrawing", - (char *) &tkMacOSXUseCGDrawing, TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } - tkMacOSXUseCGDrawing = enable; - - 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); - } - - if (tkMacOSXtmpQdRgn == NULL) { - tkMacOSXtmpQdRgn = 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; -} - -/* - *---------------------------------------------------------------------- - * - * XCopyArea -- - * - * Copies data from one drawable to another using block transfer - * routines. - * - * 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, *dstDraw = (MacDrawable *) dst; - - display->request++; - if (!width || !height) { - /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */ - return; - } - { - CGrafPtr srcPort; - - srcPort = TkMacOSXGetDrawablePort(src); - if (srcPort) { - Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; - const BitMap *srcBit, *dstBit; - RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff}; - - if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) { - return; - } - if (dc.context) { - TkMacOSXDbgMsg("Ignored CG drawing of QD drawable"); - goto end; - } - if (!dc.port) { - TkMacOSXDbgMsg("Invalid destination drawable"); - goto end; - } - srcBit = GetPortBitMapForCopyBits(srcPort); - dstBit = GetPortBitMapForCopyBits(dc.port); - SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y, - srcDraw->xOff + src_x + width, - srcDraw->yOff + src_y + height); - if (tkPictureIsOpen) { - dstPtr = srcPtr; - } else { - SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, - dstDraw->xOff + dest_x + width, - dstDraw->yOff + dest_y + height); - } - RGBForeColor(&black); - RGBBackColor(&white); - CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL); -end: - TkMacOSXRestoreDrawingContext(&dc); - } else { - TkMacOSXDbgMsg("Invalid source drawable"); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * 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, *dstDraw = (MacDrawable *) dst; - - display->request++; - if (!width || !height) { - /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */ - return; - } - if (plane != 1) { - Tcl_Panic("Unexpected plane specified for XCopyPlane"); - } - { - CGrafPtr srcPort; - - srcPort = TkMacOSXGetDrawablePort(src); - if (srcPort) { - Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; - const BitMap *srcBit, *dstBit; - TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; - - if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) { - return; - } - if (dc.context) { - TkMacOSXDbgMsg("Ignored CG drawing of QD drawable"); - goto end; - } - if (!dc.port) { - TkMacOSXDbgMsg("Invalid destination drawable"); - goto end; - } - srcBit = GetPortBitMapForCopyBits(srcPort); - dstBit = GetPortBitMapForCopyBits(dc.port); - SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y, - srcDraw->xOff + src_x + width, - srcDraw->yOff + src_y + height); - if (tkPictureIsOpen) { - dstPtr = srcPtr; - } else { - SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, - dstDraw->xOff + dest_x + width, - dstDraw->yOff + dest_y + height); - } - TkMacOSXSetColorInPort(gc->foreground, 1, NULL, dc.port); - if (!clipPtr || clipPtr->type == TKP_CLIP_REGION) { - /* - * Opaque bitmaps. - */ - - TkMacOSXSetColorInPort(gc->background, 0, NULL, dc.port); - CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL); - } else if (clipPtr->type == TKP_CLIP_PIXMAP) { - if (clipPtr->value.pixmap == src) { - /* - * Transparent bitmaps. If it's color ignore the forecolor. - */ - short tmode = GetPixDepth(GetPortPixMap(srcPort)) == 1 ? - srcOr : transparent; - - CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); - } else { - /* - * Two arbitrary bitmaps. - */ - - CGrafPtr mskPort = TkMacOSXGetDrawablePort( - clipPtr->value.pixmap); - const BitMap *mskBit = GetPortBitMapForCopyBits(mskPort); - - CopyDeepMask(srcBit, mskBit, dstBit, srcPtr, srcPtr, - dstPtr, srcCopy, NULL); - } - } -end: - TkMacOSXRestoreDrawingContext(&dc); - } else { - TkMacOSXDbgMsg("Invalid source drawable"); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * 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; - MacDrawable *dstDraw = (MacDrawable *) d; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 0, &dc)) { - return BadDrawable; - } - if (dc.context) { - TkMacOSXDbgMsg("Ignored CG drawing of XImage"); - } else { - Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect; - const BitMap *dstBit; - RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff}; - int i, j; - char *newData = NULL; - char *dataPtr, *newPtr, *oldPtr; - int rowBytes = image->bytes_per_line, sliceRowBytes, lastSliceRowBytes; - int slices, sliceWidth, lastSliceWidth; - - dstBit = GetPortBitMapForCopyBits(dc.port); - SetRect(srcPtr, src_x, src_y, src_x + width, src_y + height); - if (tkPictureIsOpen) { - dstPtr = srcPtr; - } else { - SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, - dstDraw->xOff + dest_x + width, - dstDraw->yOff + dest_y + height); - } - RGBForeColor(&black); - RGBBackColor(&white); - if (image->obdata) { - /* - * Image from XGetImage, copy from containing GWorld directly. - */ - - CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort( - (Drawable)image->obdata)), dstBit, - srcPtr, dstPtr, srcCopy, NULL); - } else if (image->depth == 1) { - /* - * BW image - */ - - const int maxRowBytes = 0x3ffe; - BitMap bitmap; - int odd; - - if (rowBytes > maxRowBytes) { - slices = rowBytes / maxRowBytes; - sliceRowBytes = maxRowBytes; - lastSliceRowBytes = rowBytes - (slices * maxRowBytes); - if (!lastSliceRowBytes) { - slices--; - lastSliceRowBytes = maxRowBytes; - } - sliceWidth = (long) image->width * maxRowBytes / rowBytes; - lastSliceWidth = image->width - (sliceWidth * slices); - } else { - slices = 0; - sliceRowBytes = lastSliceRowBytes = rowBytes; - sliceWidth = lastSliceWidth = image->width; - } - bitmap.bounds.top = bitmap.bounds.left = 0; - bitmap.bounds.bottom = (short) image->height; - dataPtr = image->data + image->xoffset; - do { - if (slices) { - bitmap.bounds.right = bitmap.bounds.left + sliceWidth; - } else { - sliceRowBytes = lastSliceRowBytes; - bitmap.bounds.right = bitmap.bounds.left + lastSliceWidth; - } - oldPtr = dataPtr; - odd = sliceRowBytes % 2; - if (!newData) { - newData = ckalloc(image->height * (sliceRowBytes+odd)); - } - newPtr = newData; - if (image->bitmap_bit_order != MSBFirst) { - for (i = 0; i < image->height; i++) { - for (j = 0; j < sliceRowBytes; j++) { - *newPtr = xBitReverseTable[(unsigned char)*oldPtr]; - newPtr++; oldPtr++; - } - if (odd) { - *newPtr++ = 0; - } - oldPtr += rowBytes - sliceRowBytes; - } - } else { - for (i = 0; i < image->height; i++) { - memcpy(newPtr, oldPtr, sliceRowBytes); - newPtr += sliceRowBytes; - if (odd) { - *newPtr++ = 0; - } - oldPtr += rowBytes; - } - } - bitmap.baseAddr = newData; - bitmap.rowBytes = sliceRowBytes + odd; - CopyBits(&bitmap, dstBit, srcPtr, dstPtr, srcCopy, NULL); - if (slices) { - bitmap.bounds.left = bitmap.bounds.right; - dataPtr += sliceRowBytes; - } - } while (slices--); - ckfree(newData); - } else { - /* - * Color image - */ - - const int maxRowBytes = 0x3ffc; - PixMap pixmap; - - pixmap.bounds.left = 0; - pixmap.bounds.top = 0; - pixmap.bounds.bottom = (short) image->height; - pixmap.pixelType = RGBDirect; - pixmap.pmVersion = baseAddr32; /* 32bit clean */ - pixmap.packType = 0; - pixmap.packSize = 0; - pixmap.hRes = 0x00480000; - pixmap.vRes = 0x00480000; - pixmap.pixelSize = 32; - pixmap.cmpCount = 3; - pixmap.cmpSize = 8; - pixmap.pixelFormat = image->byte_order == MSBFirst ? - k32ARGBPixelFormat : k32BGRAPixelFormat; - pixmap.pmTable = NULL; - pixmap.pmExt = 0; - if (rowBytes > maxRowBytes) { - slices = rowBytes / maxRowBytes; - sliceRowBytes = maxRowBytes; - lastSliceRowBytes = rowBytes - (slices * maxRowBytes); - if (!lastSliceRowBytes) { - slices--; - lastSliceRowBytes = maxRowBytes; - } - sliceWidth = (long) image->width * maxRowBytes / rowBytes; - lastSliceWidth = image->width - (sliceWidth * slices); - dataPtr = image->data + image->xoffset; - newData = ckalloc(image->height * sliceRowBytes); - do { - if (slices) { - pixmap.bounds.right = pixmap.bounds.left + sliceWidth; - } else { - sliceRowBytes = lastSliceRowBytes; - pixmap.bounds.right = pixmap.bounds.left + lastSliceWidth; - } - oldPtr = dataPtr; - newPtr = newData; - for (i = 0; i < image->height; i++) { - memcpy(newPtr, oldPtr, sliceRowBytes); - oldPtr += rowBytes; - newPtr += sliceRowBytes; - } - pixmap.baseAddr = newData; - pixmap.rowBytes = sliceRowBytes | 0x8000; - CopyBits((BitMap*) &pixmap, dstBit, srcPtr, dstPtr, srcCopy, - NULL); - if (slices) { - pixmap.bounds.left = pixmap.bounds.right; - dataPtr += sliceRowBytes; - } - } while (slices--); - ckfree(newData); - } else { - pixmap.bounds.right = (short) image->width; - pixmap.baseAddr = image->data + image->xoffset; - pixmap.rowBytes = rowBytes | 0x8000; - CopyBits((BitMap*) &pixmap, dstBit, srcPtr, dstPtr, srcCopy, NULL); - } - } - } - TkMacOSXRestoreDrawingContext(&dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * 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, tkMacOSXUseCGDrawing, &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); - } else { - int o = -lw/2; - - /* 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++) { - if (mode == CoordModeOrigin) { - LineTo((short) (macWin->xOff + points[i].x + o), - (short) (macWin->yOff + points[i].y + o)); - } else { - Line((short) points[i].x, (short) points[i].y); - } - } - } - TkMacOSXRestoreDrawingContext(&dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XDrawSegments -- - * - * Draw unconnected lines. - * - * Results: - * None. - * - * Side effects: - * Renders a series of unconnected lines. - * - *---------------------------------------------------------------------- - */ - -void -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, tkMacOSXUseCGDrawing, &dc)) { - return; - } - 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); - } - } else { - int o = -lw/2; - - /* 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)); - } - } - TkMacOSXRestoreDrawingContext(&dc); -} - -/* - *---------------------------------------------------------------------- - * - * 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, tkMacOSXUseCGDrawing, &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); - } else { - PolyHandle polygon; - - polygon = OpenPoly(); - MoveTo((short) (macWin->xOff + points[0].x), - (short) (macWin->yOff + points[0].y)); - for (i = 1; i < npoints; i++) { - if (mode == CoordModeOrigin) { - LineTo((short) (macWin->xOff + points[i].x), - (short) (macWin->yOff + points[i].y)); - } else { - Line((short) points[i].x, (short) points[i].y); - } - } - ClosePoly(); - FillCPoly(polygon, dc.penPat); - KillPoly(polygon); - } - 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, tkMacOSXUseCGDrawing, &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); - } else { - Rect theRect; - int o = -lw/2; - - 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); - } - 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, tkMacOSXUseCGDrawing, &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); - } - } else { - Rect theRect; - int o = -lw/2; - - 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); - theRect.right = (short) (theRect.left + rectPtr->width + lw); - theRect.bottom = (short) (theRect.top + rectPtr->height + lw); - FrameRect(&theRect); - } - } - 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, tkMacOSXUseCGDrawing, &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); - } - } else { - Rect theRect; - - 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, dc.penPat); - } - } - 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, tkMacOSXUseCGDrawing, &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); - TK_IF_MAC_OS_X_API_COND (4, CGContextStrokeEllipseInRect, - angle1 == 0 && angle2 == 23040, - CGContextStrokeEllipseInRect(dc.context, rect); - ) TK_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); - ) TK_ENDIF - } else { - Rect theRect; - short start, extent; - int o = -lw/2; - - 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)); - FrameArc(&theRect, start, extent); - } - 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, tkMacOSXUseCGDrawing, &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); - - TK_IF_MAC_OS_X_API_COND (4, CGContextStrokeEllipseInRect, - arcPtr->angle1 == 0 && arcPtr->angle2 == 23040, - CGContextStrokeEllipseInRect(dc.context, rect); - ) TK_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); - ) TK_ENDIF - } - } else { - Rect theRect; - short start, extent; - int o = -lw/2; - - 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); - theRect.right = (short) (theRect.left + arcPtr->width + lw); - theRect.bottom = (short) (theRect.top + arcPtr->height + lw); - start = (short) (90 - (arcPtr->angle1/64)); - extent = (short) (-(arcPtr->angle2/64)); - FrameArc(&theRect, start, extent); - } - } - 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, tkMacOSXUseCGDrawing, &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); - - TK_IF_MAC_OS_X_API_COND (4, CGContextFillEllipseInRect, - angle1 == 0 && angle2 == 23040, - CGContextFillEllipseInRect(dc.context, rect); - ) TK_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); - ) TK_ENDIF - } else { - Rect theRect; - short start, extent; - int o = -lw/2; - PolyHandle polygon; - double sin1, cos1, sin2, cos2, angle; - double boxWidth, boxHeight; - double vertex[2], center1[2], center2[2]; - - 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)); - if (gc->arc_mode == ArcChord) { - boxWidth = theRect.right - theRect.left; - boxHeight = theRect.bottom - theRect.top; - angle = radians(-angle1/64.0); - sin1 = sin(angle); - cos1 = cos(angle); - angle -= radians(angle2/64.0); - sin2 = sin(angle); - cos2 = cos(angle); - vertex[0] = (theRect.left + theRect.right)/2.0; - vertex[1] = (theRect.top + theRect.bottom)/2.0; - center1[0] = vertex[0] + cos1*boxWidth/2.0; - center1[1] = vertex[1] + sin1*boxHeight/2.0; - center2[0] = vertex[0] + cos2*boxWidth/2.0; - center2[1] = vertex[1] + sin2*boxHeight/2.0; - - polygon = OpenPoly(); - MoveTo((short) ((theRect.left + theRect.right)/2), - (short) ((theRect.top + theRect.bottom)/2)); - LineTo((short) (center1[0] + .5), (short) (center1[1] + .5)); - LineTo((short) (center2[0] + .5), (short) (center2[1] + .5)); - ClosePoly(); - FillCArc(&theRect, start, extent, dc.penPat); - FillCPoly(polygon, dc.penPat); - KillPoly(polygon); - } else { - FillCArc(&theRect, start, extent, dc.penPat); - } - } - 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, tkMacOSXUseCGDrawing, &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); - TK_IF_MAC_OS_X_API_COND (4, CGContextFillEllipseInRect, - arcPtr->angle1 == 0 && arcPtr->angle2 == 23040, - CGContextFillEllipseInRect(dc.context, rect); - ) TK_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); - ) TK_ENDIF - } - } else { - Rect theRect; - short start, extent; - int o = -lw/2; - PolyHandle polygon; - double sin1, cos1, sin2, cos2, angle; - double boxWidth, boxHeight; - double vertex[2], center1[2], center2[2]; - - 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); - theRect.right = (short) (theRect.left + arcPtr->width + lw); - theRect.bottom = (short) (theRect.top + arcPtr->height + lw); - start = (short) (90 - (arcPtr->angle1/64)); - extent = (short) (- (arcPtr->angle2/64)); - - if (gc->arc_mode == ArcChord) { - boxWidth = theRect.right - theRect.left; - boxHeight = theRect.bottom - theRect.top; - angle = radians(-arcPtr->angle1/64.0); - sin1 = sin(angle); - cos1 = cos(angle); - angle -= radians(arcPtr->angle2/64.0); - sin2 = sin(angle); - cos2 = cos(angle); - vertex[0] = (theRect.left + theRect.right)/2.0; - vertex[1] = (theRect.top + theRect.bottom)/2.0; - center1[0] = vertex[0] + cos1*boxWidth/2.0; - center1[1] = vertex[1] + sin1*boxHeight/2.0; - center2[0] = vertex[0] + cos2*boxWidth/2.0; - center2[1] = vertex[1] + sin2*boxHeight/2.0; - - polygon = OpenPoly(); - MoveTo((short) ((theRect.left + theRect.right)/2), - (short) ((theRect.top + theRect.bottom)/2)); - LineTo((short) (center1[0] + .5), (short) (center1[1] + .5)); - LineTo((short) (center2[0] + .5), (short) (center2[1] + .5)); - ClosePoly(); - FillCArc(&theRect, start, extent, dc.penPat); - FillCPoly(polygon, dc.penPat); - KillPoly(polygon); - } else { - FillCArc(&theRect, start, extent, dc.penPat); - } - } - } - 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. */ -{ - MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin); - CGrafPtr destPort, savePort; - Boolean portChanged; - Rect scrollRect; - int result; - HIShapeRef dmgRgn; - - /* - * Due to the implementation below the behavior may be differnt - * 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 - * to "skip" over an area if the offset makes the source and - * destination rects disjoint and non-aligned. - */ - - scrollRect.left = destDraw->xOff + x; - scrollRect.top = destDraw->yOff + y; - scrollRect.right = scrollRect.left + width; - scrollRect.bottom = scrollRect.top + height; - if (dx < 0) { - scrollRect.left += dx; - } else { - scrollRect.right += dx; - } - if (dy < 0) { - scrollRect.top += dy; - } else { - scrollRect.bottom += dy; - } - - destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); - TkMacOSXCheckTmpQdRgnEmpty(); - portChanged = QDSwapPort(destPort, &savePort); - ScrollRect(&scrollRect, dx, dy, tkMacOSXtmpQdRgn); - if (portChanged) { - QDSwapPort(savePort, NULL); - } - - /* - * 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. - */ - - dmgRgn = HIShapeCreateWithQDRgn(tkMacOSXtmpQdRgn); - SetEmptyRgn(tkMacOSXtmpQdRgn); - TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); - result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; - CFRelease(dmgRgn); - - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXSetUpGraphicsPort -- - * - * Set up the graphics port from the given GC. - * - * Results: - * None. - * - * Side effects: - * The current port is adjusted. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXSetUpGraphicsPort( - GC gc, /* GC to apply to current port. */ - void *destPort) -{ - CGrafPtr savePort; - Boolean portChanged; - - portChanged = QDSwapPort(destPort, &savePort); - PenNormal(); - if (gc) { - if (!penPat) { - if (!tmpPixPat) { - penPat = NewPixPat(); - } else { - penPat = tmpPixPat; - tmpPixPat = NULL; - } - } - TkMacOSXSetColorInPort(gc->foreground, 1, penPat, destPort); - PenPixPat(penPat); - 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. - */ - } - } - if (portChanged) { - QDSwapPort(savePort, NULL); - } -} - -/* - *---------------------------------------------------------------------- - * - * 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; - TkMacOSXDrawingContext dc = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, - {SHRT_MIN, SHRT_MIN, SHRT_MAX, SHRT_MAX}, false}; - - if (tkPictureIsOpen) { - if (useCG) { - TkMacOSXDbgMsg("Ignored CG Drawing with QD Picture open"); - dontDraw = 1; - } - } else { - dc.clipRgn = TkMacOSXGetClipRgn(d); - } - if (!dontDraw) { - ClipToGC(d, gc, &dc.clipRgn); - dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0; - } - if (dontDraw) { - if (dc.clipRgn) { - CFRelease(dc.clipRgn); - dc.clipRgn = NULL; - } - goto end; - } - if (useCG) { - dc.context = macDraw->context; - } - if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) { - dc.port = TkMacOSXGetDrawablePort(d); - if (dc.port) { - GetPortBounds(dc.port, &dc.portBounds); - } - } - if (dc.context) { - if (!dc.port) { - CGRect r; - - TK_IF_MAC_OS_X_API (3, CGContextGetClipBoundingBox, - r = CGContextGetClipBoundingBox(dc.context); - ) TK_ELSE_MAC_OS_X (3, - r.origin = CGPointZero; - r.size = macDraw->size; - ) TK_ENDIF - SetRect(&dc.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); - } - CGContextSaveGState(dc.context); - dc.saveState = (void*)1; - dc.port = NULL; - } else if (dc.port) { - dc.portChanged = QDSwapPort(dc.port, &dc.savePort); - if (useCG && ChkErr(QDBeginCGContext, dc.port, &dc.context) == noErr) { - SyncCGContextOriginWithPort(dc.context, dc.port); - } else { - dc.context = NULL; - } - } else { - Tcl_Panic("TkMacOSXSetupDrawingContext(): " - "no port or context to draw into !"); - } - if (dc.context) { - CGContextConcatCTM(dc.context, CGAffineTransformMake(1.0, 0.0, 0.0, - -1.0, 0.0, dc.portBounds.bottom - dc.portBounds.top)); - 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.2); - CGContextEOFillPath(dc.context); - CGContextRestoreGState(dc.context); -#endif /* TK_MAC_DEBUG_DRAWING */ - 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->foreground, dc.context); - if (dc.port) { - CGContextSetPatternPhase(dc.context, CGSizeMake( - dc.portBounds.right - dc.portBounds.left, - dc.portBounds.bottom - dc.portBounds.top)); - } - 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); - double dashOffset = gc->dash_offset; - float 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]); - } - } - } else if (dc.port) { - PixPatHandle savePat = penPat; - - ChkErr(GetThemeDrawingState, &dc.saveState); - penPat = NULL; - TkMacOSXSetUpGraphicsPort(gc, dc.port); - dc.penPat = penPat; - penPat = savePat; - dc.saveClip = NewRgn(); - GetPortClipRegion(dc.port, dc.saveClip); - if (dc.clipRgn) { - ChkErr(HIShapeSetQDClip, dc.clipRgn, dc.port); - } else { - NoQDClip(dc.port); - } - if (!tkPictureIsOpen) { - ShowPen(); - } - } -end: - *dcPtr = dc; - return !dontDraw; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXRestoreDrawingContext -- - * - * Restore drawing context. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXRestoreDrawingContext( - TkMacOSXDrawingContext *dcPtr) -{ - if (dcPtr->context) { - CGContextSynchronize(dcPtr->context); - if (dcPtr->saveState) { - CGContextRestoreGState(dcPtr->context); - } - if (dcPtr->port) { - ChkErr(QDEndCGContext, dcPtr->port, &(dcPtr->context)); - } - } else if (dcPtr->port) { - if (!tkPictureIsOpen) { - HidePen(); - } - PenNormal(); - if (dcPtr->saveClip) { - SetPortClipRegion(dcPtr->port, dcPtr->saveClip); - DisposeRgn(dcPtr->saveClip); - } - if (dcPtr->penPat) { - if (!tmpPixPat) { - tmpPixPat = dcPtr->penPat; - } else { - DisposePixPat(dcPtr->penPat); - } - } - if (dcPtr->saveState) { - ChkErr(SetThemeDrawingState, dcPtr->saveState, true); - } - } - if (dcPtr->clipRgn) { - CFRelease(dcPtr->clipRgn); - } - if (dcPtr->portChanged) { - QDSwapPort(dcPtr->savePort, NULL); - } -#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; - CGRect r; - - if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) { - TkMacOSXUpdateClipRgn(macDraw->winPtr); -#ifdef TK_MAC_DEBUG_DRAWING - TkMacOSXDbgMsg("%s visRgn ", macDraw->winPtr->pathName); - TkMacOSXDebugFlashRegion(drawable, macDraw->visRgn); -#endif /* TK_MAC_DEBUG_DRAWING */ - } - - if (macDraw->flags & TK_CLIPPED_DRAW) { - r = CGRectOffset(macDraw->drawRect, macDraw->xOff, macDraw->yOff); - } - if (macDraw->visRgn) { - if (macDraw->flags & TK_CLIPPED_DRAW) { - HIShapeRef rgn = HIShapeCreateWithRect(&r); - - clipRgn = HIShapeCreateIntersection(macDraw->visRgn, rgn); - CFRelease(rgn); - } else { - clipRgn = HIShapeCreateCopy(macDraw->visRgn); - } - } else if (macDraw->flags & TK_CLIPPED_DRAW) { - clipRgn = HIShapeCreateWithRect(&r); - } -#ifdef TK_MAC_DEBUG_DRAWING - TkMacOSXDbgMsg("%s clipRgn ", macDraw->winPtr->pathName); - TkMacOSXDebugFlashRegion(drawable, clipRgn); -#endif /* TK_MAC_DEBUG_DRAWING */ - - return clipRgn; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXSetUpClippingRgn -- - * - * Set up the clipping region so that drawing only occurs on the - * specified X subwindow. - * - * Results: - * None. - * - * Side effects: - * The clipping region in the current port is changed. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXSetUpClippingRgn( - Drawable drawable) /* Drawable to update. */ -{ - CGrafPtr port = TkMacOSXGetDrawablePort(drawable); - - if (port) { - HIShapeRef clipRgn = TkMacOSXGetClipRgn(drawable); - - if (clipRgn) { - ChkErr(HIShapeSetQDClip, clipRgn, port); - CFRelease(clipRgn); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * 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. - * - *---------------------------------------------------------------------- - */ - -void -TkpClipDrawableToRect( - Display *display, - Drawable d, - int x, int y, - int width, int height) -{ - MacDrawable *macDraw = (MacDrawable *) d; - - if (width < 0 && height < 0) { - macDraw->drawRect = CGRectNull; - macDraw->flags &= ~TK_CLIPPED_DRAW; - } else { - macDraw->drawRect = CGRectMake(x, y, width, height); - macDraw->flags |= TK_CLIPPED_DRAW; - } -} - -/* - *---------------------------------------------------------------------- - * - * 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; - - if (!tkPictureIsOpen) { - TkMacOSXOffsetRegion(gcClip, xOffset, yOffset); - } - gcClipRgn = TkMacOSXGetNativeRegion(gcClip); - if (clipRgn) { - *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn); - CFRelease(clipRgn); - } else { - *clipRgnPtr = HIShapeCreateCopy(gcClipRgn); - } - CFRelease(gcClipRgn); - if (!tkPictureIsOpen) { - TkMacOSXOffsetRegion(gcClip, -xOffset, -yOffset); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * NoQDClip -- - * - * Helper function to setup a QD port to not clip anything. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -NoQDClip( - CGrafPtr port) -{ - static RgnHandle noClipRgn = NULL; - - if (!noClipRgn) { - noClipRgn = NewRgn(); - SetRectRgn(noClipRgn, SHRT_MIN, SHRT_MIN, SHRT_MAX, SHRT_MAX); - } - SetPortClipRegion(port, noClipRgn); -} - -/* - *---------------------------------------------------------------------- - * - * 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. */ -{ - CGrafPtr stipplePort; - BitMapPtr bitmapPtr; - const BitMap *stippleBitmap; - Rect portRect; - int width, height, stippleHeight, stippleWidth, i, j; - Rect bounds; - - GetPortBounds(TkMacOSXGetDrawablePort(drawable), &portRect); - width = portRect.right - portRect.left; - height = portRect.bottom - portRect.top; - bitmapPtr = ckalloc(sizeof(BitMap)); - bitmapPtr->bounds.top = bitmapPtr->bounds.left = 0; - bitmapPtr->bounds.right = (short) width; - bitmapPtr->bounds.bottom = (short) height; - bitmapPtr->rowBytes = (width / 8) + 1; - bitmapPtr->baseAddr = ckalloc(height * bitmapPtr->rowBytes); - - stipplePort = TkMacOSXGetDrawablePort(stipple); - stippleBitmap = GetPortBitMapForCopyBits(stipplePort); - GetPortBounds(stipplePort, &portRect); - stippleWidth = portRect.right - portRect.left; - stippleHeight = portRect.bottom - portRect.top; - - for (i = 0; i < height; i += stippleHeight) { - for (j = 0; j < width; j += stippleWidth) { - bounds.left = j; - bounds.top = i; - bounds.right = j + stippleWidth; - bounds.bottom = i + stippleHeight; - CopyBits(stippleBitmap, bitmapPtr, &portRect, &bounds, srcCopy, - NULL); - } - } - return bitmapPtr; -} - -/* - *---------------------------------------------------------------------- - * - * 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 request themeing, it draws with a 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); -} |