From da455d8528eca0baa4cc40a62c75622ff17d4143 Mon Sep 17 00:00:00 2001 From: das Date: Mon, 16 Oct 2006 15:35:27 +0000 Subject: * changes: updates for 8.5a5 release. * macosx/tkMacOSXDraw.c: fix numerous issues in CG and QD drawing procs so that they now match X11 drawing much more closely [Bug 1558051]; use Tiger ellipse drawing API when available; fix comments & whitespace. * macosx/tkMacOSXInit.c: set default linewidth limit for CG antialiasing to 0 as thin horizontal/vertical lines look good now. * generic/tkCanvLine.c (ConfigureLine): on TkAqua, pass outline * generic/tkCanvPoly.c (ConfigurePolygon): linewidth in gc even for * generic/tkRectOval.c (ConfigureRectOval): fills (as it controls AA). --- ChangeLog | 17 +- changes | 12 +- generic/tkCanvLine.c | 10 +- generic/tkCanvPoly.c | 11 +- generic/tkRectOval.c | 11 +- macosx/tkMacOSXDraw.c | 1677 ++++++++++++++++++++++++------------------------- macosx/tkMacOSXInit.c | 4 +- 7 files changed, 881 insertions(+), 861 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9d396d..0695e06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,22 @@ -2006-10-10 Don Porter +2006-10-16 Daniel Steffen *** 8.5a5 TAGGED FOR RELEASE *** + * changes: updates for 8.5a5 release. + + * macosx/tkMacOSXDraw.c: fix numerous issues in CG and QD drawing procs + so that they now match X11 drawing much more closely [Bug 1558051]; + use Tiger ellipse drawing API when available; fix comments & whitespace. + + * macosx/tkMacOSXInit.c: set default linewidth limit for CG + antialiasing to 0 as thin horizontal/vertical lines look good now. + + * generic/tkCanvLine.c (ConfigureLine): on TkAqua, pass outline + * generic/tkCanvPoly.c (ConfigurePolygon): linewidth in gc even for + * generic/tkRectOval.c (ConfigureRectOval): fills (as it controls AA). + +2006-10-10 Don Porter + * changes: Updates for 8.5a5 release 2006-10-08 Pat Thoyts diff --git a/changes b/changes index 1e0a3a7..909cc06 100644 --- a/changes +++ b/changes @@ -2,7 +2,7 @@ This file summarizes all changes made to Tk since version 1.0 was released on March 13, 1991. Changes that aren't backward compatible are marked specially. -RCS: @(#) $Id: changes,v 1.100 2006/10/11 03:56:14 dgp Exp $ +RCS: @(#) $Id: changes,v 1.101 2006/10/16 15:35:27 das Exp $ 3/16/91 (bug fix) Modified tkWindow.c to remove Tk's Tcl commands from the interpreter when the main window is deleted (otherwise there will @@ -6221,8 +6221,16 @@ Documentation improvements [1224983,1247835,1151523,1357575,1083838] 2006-08-21 (bug fix) Aqua: recursively called event loop (steffen) +2006-08-24 (bug fix) Aqua: window grow icon obscuring scrollbar (steffen) + 2006-08-30 (new feature)[1518677] WM_UNICHAR window message (hobbs,petasis) +2006-09-10 (bug fix) Aqua: active/inactive text selection color&relief (steffen) + +2006-09-10 (bug fix)[1472624] Aqua: mouse events in overrideredir wins (steffen) + +2006-09-11 (bug fix) Aqua: app menu shortcuts with custom .apple menu (steffen) + 2006-09-22 (bug fix)[1562528] NULL terminates variadic calls (fellows,ryazanov) 2006-09-22 (new feature)[TIP 268] [package provide] full patchlevel (kupries) @@ -6232,4 +6240,6 @@ Documentation improvements [1224983,1247835,1151523,1357575,1083838] 2006-10-08 (new feature)[TIP 264] New public routine Tk_Interp() (thoyts) +2006-10-16 (bug fix)[1558051] Aqua: CG drawing matches X11 (steffen) + ---- Released 8.5a5, October XX, 2006 --- See ChangeLog for details --- diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c index f645243..f74bc5a 100644 --- a/generic/tkCanvLine.c +++ b/generic/tkCanvLine.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvLine.c,v 1.18 2005/11/17 10:57:35 dkf Exp $ + * RCS: @(#) $Id: tkCanvLine.c,v 1.19 2006/10/16 15:35:27 das Exp $ */ #include @@ -523,7 +523,15 @@ ConfigureLine( gcValues.join_style = linePtr->joinStyle; mask |= GCJoinStyle; newGC = Tk_GetGC(tkwin, mask, &gcValues); +#ifdef MAC_OSX_TK + /* + * Mac OS X CG drawing needs access to linewidth even for + * arrow fills (as linewidth controls antialiasing). + */ + mask |= GCLineWidth; +#else gcValues.line_width = 0; +#endif arrowGC = Tk_GetGC(tkwin, mask, &gcValues); } else { newGC = arrowGC = None; diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c index 05d4dfb..7338d6d 100644 --- a/generic/tkCanvPoly.c +++ b/generic/tkCanvPoly.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvPoly.c,v 1.15 2005/11/17 10:57:35 dkf Exp $ + * RCS: @(#) $Id: tkCanvPoly.c,v 1.16 2006/10/16 15:35:28 das Exp $ */ #include @@ -522,6 +522,15 @@ ConfigurePolygon( gcValues.fill_style = FillStippled; mask |= GCStipple|GCFillStyle; } +#ifdef MAC_OSX_TK + /* + * Mac OS X CG drawing needs access to the outline linewidth + * even for fills (as linewidth controls antialiasing). + */ + gcValues.line_width = polyPtr->outline.gc != None ? + polyPtr->outline.gc->line_width : 0; + mask |= GCLineWidth; +#endif newGC = Tk_GetGC(tkwin, mask, &gcValues); } if (polyPtr->fillGC != None) { diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c index 07c4ced..b0fb6be 100644 --- a/generic/tkRectOval.c +++ b/generic/tkRectOval.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkRectOval.c,v 1.14 2005/11/17 10:57:35 dkf Exp $ + * RCS: @(#) $Id: tkRectOval.c,v 1.15 2006/10/16 15:35:28 das Exp $ */ #include @@ -521,6 +521,15 @@ ConfigureRectOval( } else { mask = GCForeground; } +#ifdef MAC_OSX_TK + /* + * Mac OS X CG drawing needs access to the outline linewidth + * even for fills (as linewidth controls antialiasing). + */ + gcValues.line_width = rectOvalPtr->outline.gc != None ? + rectOvalPtr->outline.gc->line_width : 0; + mask |= GCLineWidth; +#endif newGC = Tk_GetGC(tkwin, mask, &gcValues); } if (rectOvalPtr->fillGC != None) { diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index dc017d1..d662c2e 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -12,24 +12,28 @@ * 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.16 2006/06/14 21:18:47 das Exp $ + * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.17 2006/10/16 15:35:28 das Exp $ */ #include "tkMacOSXInt.h" #include "tkMacOSXDebug.h" /* -#ifdef TK_MAC_DEBUG +#ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_DRAWING #endif */ -#ifndef PI -# define PI 3.14159265358979323846 -#endif -#define RGBFLOATRED(c) (float)((float)(c.red) / 65535.0f) -#define RGBFLOATGREEN(c) (float)((float)(c.green) / 65535.0f) -#define RGBFLOATBLUE(c) (float)((float)(c.blue) / 65535.0f) +#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)) + +/* + * 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 regions that can be reused. @@ -37,11 +41,11 @@ static RgnHandle tmpRgn = NULL; static RgnHandle tmpRgn2 = NULL; - static PixPatHandle gPenPat = NULL; static int useCGDrawing = 1; -static int tkMacOSXCGAntiAliasLimit = 1; +static int tkMacOSXCGAntiAliasLimit = 0; +#define notAA(w) ((w) < tkMacOSXCGAntiAliasLimit) static int useThemedToplevel = 0; static int useThemedFrame = 0; @@ -49,55 +53,69 @@ static int useThemedFrame = 0; /* * Prototypes for functions used only in this file. */ -static unsigned char InvertByte _ANSI_ARGS_((unsigned char data)); - -static void TkMacOSXSetUpCGContext(MacDrawable *macWin, - CGrafPtr destPort, GC gc, CGContextRef *contextPtr); -static void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort, +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); -static inline double radians(double degrees) { return degrees * PI / 180.0f; } + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXInitCGDrawing -- + * + * Initializes link vars that control CG drawing. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ -MODULE_SCOPE int +MODULE_SCOPE int TkMacOSXInitCGDrawing(interp, enable, limit) - Tcl_Interp *interp; - int enable; - int limit; + 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 *) &useCGDrawing, TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } - useCGDrawing = enable; - - if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit", - (char *) &tkMacOSXCGAntiAliasLimit, TCL_LINK_INT) != TCL_OK) { - Tcl_ResetResult(interp); - } - tkMacOSXCGAntiAliasLimit = limit; + initialized = TRUE; + + if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) { + Tcl_ResetResult(interp); + } + if (Tcl_LinkVar(interp, "::tk::mac::useCGDrawing", + (char *) &useCGDrawing, TCL_LINK_BOOLEAN) != TCL_OK) { + Tcl_ResetResult(interp); + } + useCGDrawing = enable; + + if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit", + (char *) &tkMacOSXCGAntiAliasLimit, TCL_LINK_INT) != TCL_OK) { + Tcl_ResetResult(interp); + } + tkMacOSXCGAntiAliasLimit = limit; /* * Piggy-back the themed drawing var init here. */ - if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel", + if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel", (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } - if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame", + Tcl_ResetResult(interp); + } + if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame", (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) { - Tcl_ResetResult(interp); - } + Tcl_ResetResult(interp); + } } return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -116,7 +134,7 @@ TkMacOSXInitCGDrawing(interp, enable, limit) *---------------------------------------------------------------------- */ -void +void XCopyArea( Display* display, /* Display. */ Drawable src, /* Source drawable. */ @@ -158,65 +176,65 @@ XCopyArea( blackColor.blue = 0xFFFF; blackColor.green = 0xFFFF; RGBBackColor(&blackColor); - + if (tmpRgn2 == NULL) { - tmpRgn2 = NewRgn(); + tmpRgn2 = NewRgn(); } srcPtr = &srcRect; SetRect(&srcRect, (short) (srcDraw->xOff + src_x), - (short) (srcDraw->yOff + src_y), - (short) (srcDraw->xOff + src_x + width), - (short) (srcDraw->yOff + src_y + height)); + (short) (srcDraw->yOff + src_y), + (short) (srcDraw->xOff + src_x + width), + (short) (srcDraw->yOff + src_y + height)); if (tkPictureIsOpen) { - dstPtr = &srcRect; + dstPtr = &srcRect; } else { - dstPtr = &dstRect; - SetRect(&dstRect, (short) (dstDraw->xOff + dest_x), - (short) (dstDraw->yOff + dest_y), - (short) (dstDraw->xOff + dest_x + width), - (short) (dstDraw->yOff + dest_y + height)); + dstPtr = &dstRect; + SetRect(&dstRect, (short) (dstDraw->xOff + dest_x), + (short) (dstDraw->yOff + dest_y), + (short) (dstDraw->xOff + dest_x + width), + (short) (dstDraw->yOff + dest_y + height)); } TkMacOSXSetUpClippingRgn(dst); /* - * We will change the clip rgn in this routine, so we need to + * We will change the clip rgn in this routine, so we need to * be able to restore it when we exit. */ - + GetClip(tmpRgn2); 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 - * In this case, would have also clipped to the srcRect - * ClipRect(&srcRect); - */ - - GetPortBounds(dstPort,&clpRect); - dstPtr = &srcRect; - ClipRect(&clpRect); + /* + * 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 + * In this case, would have also clipped to the srcRect + * ClipRect(&srcRect); + */ + + GetPortBounds(dstPort,&clpRect); + dstPtr = &srcRect; + ClipRect(&clpRect); } - if (!gc->clip_mask) { + if (!gc->clip_mask) { } else if (((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); - if (!tkPictureIsOpen) { - OffsetRgn(clipRgn, -xOffset, -yOffset); - } + 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); + if (!tkPictureIsOpen) { + OffsetRgn(clipRgn, -xOffset, -yOffset); + } } srcBit = GetPortBitMapForCopyBits(srcPort); dstBit = GetPortBitMapForCopyBits(dstPort); @@ -272,87 +290,86 @@ XCopyPlane( GWorldPtr srcPort, dstPort, mskPort; CGrafPtr saveWorld; GDHandle saveDevice; - RGBColor macColor; + RGBColor macColor; TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; short tmode; srcPort = TkMacOSXGetDrawablePort(src); dstPort = TkMacOSXGetDrawablePort(dst); - + display->request++; GetGWorld(&saveWorld, &saveDevice); SetGWorld(dstPort, NULL); - TkMacOSXSetUpClippingRgn(dst); srcBit = GetPortBitMapForCopyBits(srcPort); dstBit = GetPortBitMapForCopyBits(dstPort); SetRect(&srcRect, (short) (srcDraw->xOff + src_x), - (short) (srcDraw->yOff + src_y), - (short) (srcDraw->xOff + src_x + width), - (short) (srcDraw->yOff + src_y + height)); + (short) (srcDraw->yOff + src_y), + (short) (srcDraw->xOff + src_x + width), + (short) (srcDraw->yOff + src_y + height)); srcPtr = &srcRect; if (tkPictureIsOpen) { - /* - * 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 - */ - - Rect clpRect; - GetPortBounds(dstPort,&clpRect); - ClipRect(&clpRect); - dstPtr = &srcRect; + /* + * 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 + */ + + Rect clpRect; + GetPortBounds(dstPort,&clpRect); + ClipRect(&clpRect); + dstPtr = &srcRect; } else { - dstPtr = &dstRect; - SetRect(&dstRect, (short) (dstDraw->xOff + dest_x), - (short) (dstDraw->yOff + dest_y), - (short) (dstDraw->xOff + dest_x + width), - (short) (dstDraw->yOff + dest_y + height)); + dstPtr = &dstRect; + SetRect(&dstRect, (short) (dstDraw->xOff + dest_x), + (short) (dstDraw->yOff + dest_y), + (short) (dstDraw->xOff + dest_x + width), + (short) (dstDraw->yOff + dest_y + height)); } tmode = srcOr; tmode = srcCopy + transparent; if (TkSetMacColor(gc->foreground, &macColor) == true) { - RGBForeColor(&macColor); + RGBForeColor(&macColor); } if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) { - /* - * Case 1: opaque bitmaps. - */ - - TkSetMacColor(gc->background, &macColor); - RGBBackColor(&macColor); - tmode = srcCopy; - CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); + /* + * Case 1: opaque bitmaps. + */ + + TkSetMacColor(gc->background, &macColor); + RGBBackColor(&macColor); + 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 - * the forecolor. - */ - - pm = GetPortPixMap(srcPort); - if (GetPixDepth(pm) == 1) { - tmode = srcOr; - } else { - tmode = transparent; - } - CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); - } else { - /* - * Case 3: two arbitrary bitmaps. - */ - - tmode = srcCopy; - mskPort = TkMacOSXGetDrawablePort(clipPtr->value.pixmap); - mskBit = GetPortBitMapForCopyBits(mskPort); - CopyDeepMask(srcBit, mskBit, dstBit, - srcPtr, srcPtr, dstPtr, tmode, NULL); - } + if (clipPtr->value.pixmap == src) { + PixMapHandle pm; + /* + * Case 2: transparent bitmaps. If it's color we ignore + * the forecolor. + */ + + pm = GetPortPixMap(srcPort); + if (GetPixDepth(pm) == 1) { + tmode = srcOr; + } else { + tmode = transparent; + } + CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL); + } else { + /* + * Case 3: two arbitrary bitmaps. + */ + + tmode = srcCopy; + mskPort = TkMacOSXGetDrawablePort(clipPtr->value.pixmap); + mskBit = GetPortBitMapForCopyBits(mskPort); + CopyDeepMask(srcBit, mskBit, dstBit, + srcPtr, srcPtr, dstPtr, tmode, NULL); + } } SetGWorld(saveWorld, saveDevice); @@ -375,7 +392,7 @@ XCopyPlane( *---------------------------------------------------------------------- */ -void +void TkPutImage( unsigned long *colors, /* Unused on Macintosh. */ int ncolors, /* Unused on Macintosh. */ @@ -416,7 +433,7 @@ 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; @@ -425,7 +442,7 @@ TkPutImage( destPtr = srcPtr; } else { destPtr = &destRect; - SetRect(destPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, + SetRect(destPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y, dstDraw->xOff + dest_x + width, dstDraw->yOff + dest_y + height); } @@ -470,7 +487,7 @@ TkPutImage( oldPtr = dataPtr; odd = sliceRowBytes % 2; if (!newData) { - newData = (char *) ckalloc(image->height * (sliceRowBytes + odd)); + newData = (char *) ckalloc(image->height * (sliceRowBytes+odd)); } newPtr = newData; for (i = 0; i < image->height; i++) { @@ -545,7 +562,8 @@ TkPutImage( } pixmap.baseAddr = newData; pixmap.rowBytes = sliceRowBytes | 0x8000; - CopyBits((BitMap *) &pixmap, destBits, srcPtr, destPtr, srcCopy, NULL); + CopyBits((BitMap *) &pixmap, destBits, srcPtr, destPtr, + srcCopy, NULL); if (slices) { pixmap.bounds.left = pixmap.bounds.right; dataPtr += sliceRowBytes; @@ -555,78 +573,13 @@ TkPutImage( pixmap.bounds.right = (short) image->width; pixmap.baseAddr = image->data; pixmap.rowBytes = rowBytes | 0x8000; - CopyBits((BitMap *) &pixmap, destBits, srcPtr, destPtr, srcCopy, NULL); + CopyBits((BitMap *) &pixmap, destBits, srcPtr, destPtr, + srcCopy, NULL); } } if (newData != NULL) { ckfree(newData); } - SetGWorld(saveWorld, saveDevice); -} - -/* - *---------------------------------------------------------------------- - * - * XFillRectangles -- - * - * Fill multiple rectangular areas in the given drawable. - * - * Results: - * None. - * - * Side effects: - * 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. */ -{ - MacDrawable *macWin = (MacDrawable *) d; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - Rect theRect; - int i; - - destPort = TkMacOSXGetDrawablePort(d); - - display->request++; - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - - TkMacOSXSetUpClippingRgn(d); - if (useCGDrawing) { - CGContextRef outContext; - CGRect rect; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - - for (i = 0; i < n_rectangles; i++) { - rect = CGRectMake((float)(macWin->xOff + rectangles[i].x), - (float)(macWin->yOff + rectangles[i].y), - (float)rectangles[i].width, - (float)rectangles[i].height); - - CGContextFillRect(outContext, rect); - } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); - } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); - - for (i = 0; i < n_rectangles; i++) { - theRect.left = (short) (macWin->xOff + rectangles[i].x); - theRect.top = (short) (macWin->yOff + rectangles[i].y); - theRect.right = (short) (theRect.left + rectangles[i].width); - theRect.bottom = (short) (theRect.top + rectangles[i].height); - FillCRect(&theRect, gPenPat); - } - } SetGWorld(saveWorld, saveDevice); } @@ -647,7 +600,7 @@ XFillRectangles( *---------------------------------------------------------------------- */ -void +void XDrawLines( Display* display, /* Display. */ Drawable d, /* Draw on this. */ @@ -660,64 +613,63 @@ XDrawLines( CGrafPtr saveWorld; GWorldPtr destPort; GDHandle saveDevice; - int i; + int i, lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); - - display->request++; if (npoints < 2) { - return; /* TODO: generate BadValue error. */ + 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; TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - CGContextBeginPath(outContext); - prevx = (float) (macWin->xOff + points[0].x); - prevy = (float) (macWin->yOff + points[0].y); + prevx = macWin->xOff + points[0].x + o; + prevy = macWin->yOff + points[0].y + o; CGContextMoveToPoint(outContext, prevx, prevy); - for (i = 1; i < npoints; i++) { if (mode == CoordModeOrigin) { CGContextAddLineToPoint(outContext, - (float) (macWin->xOff + points[i].x), - (float) (macWin->yOff + points[i].y)); + macWin->xOff + points[i].x + o, + macWin->yOff + points[i].y + o); } else { - prevx += (float) points[i].x; - prevy += (float) points[i].y; + prevx += points[i].x; + prevy += points[i].y; CGContextAddLineToPoint(outContext, prevx, prevy); } } - CGContextStrokePath(outContext); TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); + int o = - (lw / 2); + TkMacOSXSetUpGraphicsPort(gc, destPort); ShowPen(); - PenPixPat(gPenPat); - MoveTo((short) (macWin->xOff + points[0].x), - (short) (macWin->yOff + points[0].y)); + /* 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), - (short) (macWin->yOff + points[i].y)); + LineTo((short) (macWin->xOff + points[i].x + o), + (short) (macWin->yOff + points[i].y + o)); } else { - Line((short) (macWin->xOff + points[i].x), - (short) (macWin->yOff + points[i].y)); + Line((short) points[i].x, (short) points[i].y); } } HidePen(); - } + SetGWorld(saveWorld, saveDevice); } @@ -748,49 +700,48 @@ void XDrawSegments( CGrafPtr saveWorld; GWorldPtr destPort; GDHandle saveDevice; - int i; + int i, lw = gc->line_width; destPort = TkMacOSXGetDrawablePort(d); - display->request++; - GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); if (useCGDrawing) { - CGContextRef outContext; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); + CGContextRef outContext; + float o = (lw % 2) ? .5 : 0; - for (i = 0; i < nsegments; i++) { + TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); + for (i = 0; i < nsegments; i++) { CGContextBeginPath(outContext); - CGContextMoveToPoint(outContext, - (float)(macWin->xOff + segments[i].x1), - (float)(macWin->yOff + segments[i].y1)); - CGContextAddLineToPoint (outContext, - (float)(macWin->xOff + segments[i].x2), - (float)(macWin->yOff + segments[i].y2)); - CGContextStrokePath(outContext); - - } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + CGContextMoveToPoint(outContext, + macWin->xOff + segments[i].x1 + o, + macWin->yOff + segments[i].y1 + o); + CGContextAddLineToPoint(outContext, + macWin->xOff + segments[i].x2 + o, + macWin->yOff + segments[i].y2 + o); + CGContextStrokePath(outContext); + } + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); - - ShowPen(); - - PenPixPat(gPenPat); - for (i = 0; i < nsegments; i++) { - MoveTo((short) (macWin->xOff + segments[i].x1), - (short) (macWin->yOff + segments[i].y1)); - LineTo((short) (macWin->xOff + segments[i].x2), - (short) (macWin->yOff + segments[i].y2)); - } - HidePen(); + 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); } @@ -810,7 +761,7 @@ void XDrawSegments( *---------------------------------------------------------------------- */ -void +void XFillPolygon( Display* display, /* Display. */ Drawable d, /* Draw on this. */ @@ -821,65 +772,61 @@ XFillPolygon( int mode) /* Drawing mode. */ { MacDrawable *macWin = (MacDrawable *) d; - PolyHandle polygon; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; 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; TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - CGContextBeginPath(outContext); - prevx = (float) (macWin->xOff + points[0].x); - prevy = (float) (macWin->yOff + points[0].y); + prevx = macWin->xOff + points[0].x + o; + prevy = macWin->yOff + points[0].y + o; CGContextMoveToPoint(outContext, prevx, prevy); for (i = 1; i < npoints; i++) { if (mode == CoordModeOrigin) { - CGContextAddLineToPoint(outContext, - (float)(macWin->xOff + points[i].x), - (float)(macWin->yOff + points[i].y)); + CGContextAddLineToPoint(outContext, + macWin->xOff + points[i].x + o, + macWin->yOff + points[i].y + o); } else { - prevx += (float) points[i].x; - prevy += (float) points[i].y; + prevx += points[i].x; + prevy += points[i].y; CGContextAddLineToPoint(outContext, prevx, prevy); } } CGContextEOFillPath(outContext); TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); + PolyHandle polygon; + TkMacOSXSetUpGraphicsPort(gc, destPort); PenNormal(); polygon = OpenPoly(); - MoveTo((short) (macWin->xOff + points[0].x), - (short) (macWin->yOff + points[0].y)); + (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)); + (short) (macWin->yOff + points[i].y)); } else { - Line((short) (macWin->xOff + points[i].x), - (short) (macWin->yOff + points[i].y)); + Line((short) points[i].x, (short) points[i].y); } } - ClosePoly(); FillCPoly(polygon, gPenPat); KillPoly(polygon); } + SetGWorld(saveWorld, saveDevice); } @@ -899,7 +846,7 @@ XFillPolygon( *---------------------------------------------------------------------- */ -void +void XDrawRectangle( Display* display, /* Display. */ Drawable d, /* Draw on this. */ @@ -910,47 +857,52 @@ XDrawRectangle( unsigned int height) { MacDrawable *macWin = (MacDrawable *) d; - Rect theRect; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; + int lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); + if (width == 0 || height == 0) { + return; + } + destPort = TkMacOSXGetDrawablePort(d); display->request++; GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); + if (useCGDrawing) { - CGContextRef outContext; - CGRect rect; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - - rect = CGRectMake((float) ((float) macWin->xOff + (float) x), - (float) ((float) macWin->yOff + (float) y), - (float) width, - (float) height); + CGContextRef outContext; + CGRect rect; + float 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); + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); - - theRect.left = (short) (macWin->xOff + x); - theRect.top = (short) (macWin->yOff + y); - theRect.right = (short) (theRect.left + width); - theRect.bottom = (short) (theRect.top + height); - - ShowPen(); - PenPixPat(gPenPat); - FrameRect(&theRect); - HidePen(); + 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.bottom = (short) (theRect.top + height + lw); + FrameRect(&theRect); + HidePen(); } + SetGWorld(saveWorld, saveDevice); } -#if 0 +#ifdef TK_MACOSXDRAW_UNUSED /* *---------------------------------------------------------------------- * @@ -986,51 +938,52 @@ XDrawRectangles( int nRects) { MacDrawable *macWin = (MacDrawable *) drawable; - Rect theRect; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; XRectangle * rectPtr; - int i; + int i, lw = gc->line_width; destPort = TkMacOSXGetDrawablePort(drawable); - display->request++; GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(drawable); if (useCGDrawing) { - CGContextRef outContext; - CGRect rect; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); + CGContextRef outContext; + CGRect rect; + float o = (lw % 2) ? .5 : 0; - for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) { - rect = CGRectMake((float) ((float) macWin->xOff - + (float) rectPtr->x), - (float) ((float) macWin->yOff + (float) rectPtr->y), - (float) rectPtr->width, - (float) rectPtr->height); + TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); + 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(outContext, rect); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); + Rect theRect; + int o = -lw/2; - ShowPen(); - PenPixPat(gPenPat); - - for (i = 0, rectPtr = rectArr; i < nRects;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); - FrameRect(&theRect); - } - HidePen(); + 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); + theRect.right = (short) (theRect.left + rectPtr->width + lw); + theRect.bottom = (short) (theRect.top + rectPtr->height + lw); + FrameRect(&theRect); + } + HidePen(); } + SetGWorld(saveWorld, saveDevice); } #endif @@ -1038,6 +991,74 @@ XDrawRectangles( /* *---------------------------------------------------------------------- * + * XFillRectangles -- + * + * Fill multiple rectangular areas in the given drawable. + * + * Results: + * None. + * + * Side effects: + * 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. */ +{ + MacDrawable *macWin = (MacDrawable *) d; + CGrafPtr saveWorld; + GDHandle saveDevice; + GWorldPtr destPort; + XRectangle * rectPtr; + int i; + + destPort = TkMacOSXGetDrawablePort(d); + display->request++; + GetGWorld(&saveWorld, &saveDevice); + SetGWorld(destPort, NULL); + TkMacOSXSetUpClippingRgn(d); + + if (useCGDrawing) { + CGContextRef outContext; + 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; + } + rect = CGRectMake( + macWin->xOff + rectPtr->x, + macWin->yOff + rectPtr->y, + rectPtr->width, rectPtr->height); + CGContextFillRect(outContext, 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); + } + } + + SetGWorld(saveWorld, saveDevice); +} + +/* + *---------------------------------------------------------------------- + * * XDrawArc -- * * Draw an arc. @@ -1051,7 +1072,7 @@ XDrawRectangles( *---------------------------------------------------------------------- */ -void +void XDrawArc( Display* display, /* Display. */ Drawable d, /* Draw on this. */ @@ -1061,96 +1082,85 @@ XDrawArc( unsigned int width, /* Width & height. */ unsigned int height, int angle1, /* Staring angle of arc. */ - int angle2) /* Ending angle of arc. */ + int angle2) /* Extent of arc. */ { MacDrawable *macWin = (MacDrawable *) d; - Rect theRect; - short start, extent; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; + int lw = gc->line_width; - if (width == 0 || height == 0) { - return; + if (width == 0 || height == 0 || angle2 == 0) { + return; } - - destPort = TkMacOSXGetDrawablePort(d); + destPort = TkMacOSXGetDrawablePort(d); display->request++; GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); - TkMacOSXSetUpClippingRgn(d); if (useCGDrawing) { - CGContextRef outContext; - CGRect boundingRect; - int clockwise; - float a,b; - CGPoint center; - float arc1, arc2; - - if (angle2 > 0) { - clockwise = 1; - } else { - clockwise = 0; - } - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - - /* - * If we are drawing an oval, we have to squash the coordinate - * system before drawing, since CGContextAddArcToPoint only draws - * circles. - */ - - CGContextSaveGState(outContext); - boundingRect = CGRectMake( (float)(macWin->xOff + x), - (float)(macWin->yOff + y), - (float)(width), - (float)(height)); - - center = CGPointMake(CGRectGetMidX(boundingRect), - CGRectGetMidY(boundingRect)); - a = CGRectGetWidth(boundingRect)/2; - b = CGRectGetHeight(boundingRect)/2; + CGContextRef outContext; + CGRect rect; + float o = (lw % 2) ? .5 : 0; - CGContextTranslateCTM(outContext, center.x, center.y); - CGContextBeginPath(outContext); - CGContextScaleCTM(outContext, a, b); - arc1 = radians(-(angle1/64)); - arc2 = radians(-(angle2/64)) + arc1; - CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise); - - CGContextRestoreGState(outContext); - CGContextStrokePath(outContext); - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + 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); + } else +#endif + { + CGMutablePathRef p = CGPathCreateMutable(); + CGAffineTransform t = CGAffineTransformIdentity; + CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); + float w = CGRectGetWidth(rect); + + if (width != height) { + t = CGAffineTransformMakeScale(1, 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); + CGPathRelease(p); + CGContextStrokePath(outContext); + } + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); + Rect theRect; + short start, extent; + int o = -lw/2; - - theRect.left = (short) (macWin->xOff + x); - theRect.top = (short) (macWin->yOff + y); - theRect.right = (short) (theRect.left + width); - theRect.bottom = (short) (theRect.top + height); - start = (short) (90 - (angle1 / 64)); - extent = (short) (-(angle2 / 64)); - - ShowPen(); - PenPixPat(gPenPat); - FrameArc(&theRect, start, extent); - HidePen(); + 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.bottom = (short) (theRect.top + height + lw); + start = (short) (90 - (angle1/64)); + extent = (short) (-(angle2/64)); + FrameArc(&theRect, start, extent); + HidePen(); } - + SetGWorld(saveWorld, saveDevice); } -#if 0 -/* +#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 @@ -1162,12 +1172,12 @@ XDrawArc( * * Results: * None. - * + * * Side effects: * Draws an arc for each array element on the specified drawable. - * + * *---------------------------------------------------------------------- - */ + */ void XDrawArcs( Display *display, @@ -1178,81 +1188,82 @@ XDrawArcs( { MacDrawable *macWin = (MacDrawable *) d; - Rect rect; - short start, extent; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; - XArc * arcPtr; - int i; + 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; - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); + if (useCGDrawing) { + CGContextRef outContext; + CGRect rect; + float o = (lw % 2) ? .5 : 0; + TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) { - CGRect boundingRect; - int clockwise; - float a,b, arc1, arc2; - CGPoint center; - - if (arcPtr[i].angle2 > 0) { - clockwise = 1; - } else { - clockwise = 0; + if (arcPtr->width == 0 || arcPtr->height == 0 + || arcPtr->angle2 == 0) { + continue; + } + rect = CGRectMake( + macWin->xOff + arcPtr->x + o, + macWin->yOff + arcPtr->y + o, + arcPtr->width, arcPtr->height); + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 && + CGContextStrokeEllipseInRect != NULL) { + CGContextStrokeEllipseInRect(outContext, rect); + } else +#endif + { + CGMutablePathRef p = CGPathCreateMutable(); + CGAffineTransform t = CGAffineTransformIdentity; + CGPoint c = CGPointMake(CGRectGetMidX(rect), + CGRectGetMidY(rect)); + float 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(outContext, p); + CGPathRelease(p); + CGContextStrokePath(outContext); } - - /* - * If we are drawing an oval, we have to squash the coordinate - * system before drawing, since CGContextAddArcToPoint only draws - * circles. - */ - - CGContextSaveGState(outContext); - CGContextBeginPath(outContext); - boundingRect = CGRectMake( (float)(macWin->xOff + arcPtr[i].x), - (float)(macWin->yOff + arcPtr[i].y), - (float)arcPtr[i].width, - (float)arcPtr[i].height); - - center = CGPointMake(CGRectGetMidX(boundingRect), - CGRectGetMidY(boundingRect)); - a = CGRectGetWidth(boundingRect)/2; - b = CGRectGetHeight(boundingRect)/2; - - CGContextTranslateCTM(outContext, center.x, center.y); - CGContextScaleCTM(outContext, a, b); - arc1 = radians(-(arcPtr[i].angle1/64)); - arc2 = radians(-(arcPtr[i].angle2/64)) + arc1; - CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise); - CGContextRestoreGState(outContext); - CGContextStrokePath(outContext); } - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); + Rect theRect; + short start, extent; + int o = -lw/2; - ShowPen(); - PenPixPat(gPenPat); - for (i = 0, arcPtr = arcArr;i < nArcs;i++, arcPtr++) { - rect.left = (short) (macWin->xOff + arcPtr->x); - rect.top = (short) (macWin->yOff + arcPtr->y); - rect.right = (short) (rect.left + arcPtr->width); - rect.bottom = (short) (rect.top + arcPtr->height); - start = (short) (90 - (arcPtr->angle1 / 64)); - extent = (short) (-(arcPtr->angle2 / 64)); - FrameArc(&rect, start, extent); - } - HidePen(); + 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); + 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); + } + HidePen(); } + SetGWorld(saveWorld, saveDevice); } #endif @@ -1283,141 +1294,136 @@ XFillArc( unsigned int width, /* Width & height. */ unsigned int height, int angle1, /* Staring angle of arc. */ - int angle2) /* Ending angle of arc. */ + int angle2) /* Extent of arc. */ { MacDrawable *macWin = (MacDrawable *) d; - Rect theRect; - short start, extent; - PolyHandle polygon; - double sin1, cos1, sin2, cos2, angle; - double boxWidth, boxHeight; - double vertex[2], center1[2], center2[2]; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; + int lw = gc->line_width; - destPort = TkMacOSXGetDrawablePort(d); + 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; - CGRect boundingRect; - int clockwise; - float a,b; - CGPoint center; - - if (angle2 > 0) { - clockwise = 1; - } else { - clockwise = 0; - } - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); - - boundingRect = CGRectMake((float) (macWin->xOff + x), - (float) (macWin->yOff + y), - (float) width, - (float) height); - center = CGPointMake(CGRectGetMidX(boundingRect), - CGRectGetMidY(boundingRect)); - a = CGRectGetWidth(boundingRect)/2; - b = CGRectGetHeight(boundingRect)/2; - - if (gc->arc_mode == ArcChord) { - float arc1, arc2; + CGContextRef outContext; + CGRect rect; + float o = (lw % 2) ? .5 : 0, u = 0; - CGContextBeginPath(outContext); - CGContextTranslateCTM(outContext, center.x, center.y); - CGContextScaleCTM(outContext, a, b); - arc1 = radians(-(angle1/64)); - arc2 = radians(-(angle2/64)) + arc1; - CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise); - CGContextFillPath(outContext); - } else if (gc->arc_mode == ArcPieSlice) { - float arc1, arc2; - - CGContextTranslateCTM(outContext, center.x, center.y); - CGContextScaleCTM(outContext,a,b); - arc1 = radians(-(angle1/64)); - arc2 = radians(-(angle2/64)) + arc1; - CGContextAddArc(outContext, 0.0, 0.0, 1, arc1, arc2, clockwise); - CGContextAddLineToPoint(outContext, 0.0f, 0.0f); - CGContextClosePath(outContext); + 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); + } else +#endif + { + CGMutablePathRef p = CGPathCreateMutable(); + CGAffineTransform t = CGAffineTransformIdentity; + CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); + float 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(outContext, p); + CGPathRelease(p); CGContextFillPath(outContext); } - - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); } else { - TkMacOSXSetUpGraphicsPort(gc, destPort); - - theRect.left = (short) (macWin->xOff + x); - theRect.top = (short) (macWin->yOff + y); - theRect.right = (short) (theRect.left + width); - theRect.bottom = (short) (theRect.top + height); - 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 = -(angle1/64.0)*PI/180.0; - sin1 = sin(angle); - cos1 = cos(angle); - angle -= (angle2/64.0)*PI/180.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] + 0.5), (short) (center1[1] + 0.5)); - LineTo((short) (center2[0] + 0.5), (short) (center2[1] + 0.5)); - ClosePoly(); - - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - FillCPoly(polygon, gPenPat); - HidePen(); - - KillPoly(polygon); - } else { - ShowPen(); - FillCArc(&theRect, start, extent, gPenPat); - HidePen(); - } + 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]; + + 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.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(); + ShowPen(); + FillCArc(&theRect, start, extent, gPenPat); + FillCPoly(polygon, gPenPat); + HidePen(); + KillPoly(polygon); + } else { + ShowPen(); + FillCArc(&theRect, start, extent, gPenPat); + HidePen(); + } } + SetGWorld(saveWorld, saveDevice); } -#if 0 -/* +#ifdef TK_MACOSXDRAW_UNUSED +/* *---------------------------------------------------------------------- - * - * XFillArcs -- + * + * XFillArcs -- * * Draw a filled arc. - * + * * Results: * None. * * Side effects: * Draws a filled arc for each array element on the specified drawable. - * + * *---------------------------------------------------------------------- - */ -void + */ +void XFillArcs( Display *display, Drawable d, @@ -1426,171 +1432,133 @@ XFillArcs( int nArcs) { MacDrawable *macWin = (MacDrawable *) d; - Rect rect; - short start, extent; - PolyHandle polygon; - double sin1, cos1, sin2, cos2, angle; - double boxWidth, boxHeight; - double vertex[2], center1[2], center2[2]; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; - int i; - XArc * arcPtr; + 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; - - TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext); + CGContextRef outContext; + CGRect rect; + float 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++) { - CGRect boundingRect; - int clockwise = arcPtr[i].angle1; - float a,b; - CGPoint center; - - if (arcPtr[i].angle2 > 0) { - clockwise = 1; - } else { - clockwise = 0; - } + if (arcPtr->width == 0 || arcPtr->height == 0 + || arcPtr->angle2 == 0) { + continue; + } + rect = CGRectMake( + macWin->xOff + arcPtr->x + o, + macWin->yOff + arcPtr->y + o, + arcPtr->width - u, arcPtr->height - u); + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 && + CGContextFillEllipseInRect != NULL) { + CGContextFillEllipseInRect(outContext, rect); + } else +#endif + { + CGMutablePathRef p = CGPathCreateMutable(); + CGAffineTransform t = CGAffineTransformIdentity; + CGPoint c = CGPointMake(CGRectGetMidX(rect), + CGRectGetMidY(rect)); + float 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(outContext, p); + CGPathRelease(p); + CGContextFillPath(outContext); + } + } + TkMacOSXReleaseCGContext(macWin, destPort, &outContext); + } 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]; - /* - * If we are drawing an oval, we have to squash the coordinate - * system before drawing, since CGContextAddArcToPoint only draws - * circles. - */ + TkMacOSXSetUpGraphicsPort(gc, destPort); + for (i = 0, arcPtr = arcArr;ixOff + 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) { - - CGContextBeginPath(outContext); - boundingRect = CGRectMake((float)(macWin->xOff + arcPtr[i].x), - (float)(macWin->yOff + arcPtr[i].y), - (float)arcPtr[i].width, - (float)arcPtr[i].height); - center = CGPointMake(CGRectGetMidX(boundingRect), - CGRectGetMidY(boundingRect)); - a = CGRectGetWidth(boundingRect)/2.0; - b = CGRectGetHeight(boundingRect)/2.0; - - angle = -(arcPtr->angle1/64.0)*PI/180.0; + boxWidth = theRect.right - theRect.left; + boxHeight = theRect.bottom - theRect.top; + angle = radians(-arcPtr->angle1/64.0); sin1 = sin(angle); cos1 = cos(angle); - angle -= (arcPtr->angle2/64.0)*PI/180.0; + angle -= radians(arcPtr->angle2/64.0); sin2 = sin(angle); cos2 = cos(angle); - vertex[0] = (CGRectGetMinX(boundingRect) - + CGRectGetMaxX(boundingRect))/2.0; - vertex[1] = (CGRectGetMaxY(boundingRect) - + CGRectGetMinY(boundingRect))/2.0; - center1[0] = vertex[0] + cos1*a; - center1[1] = vertex[1] + sin1*b; - center2[0] = vertex[0] + cos2*a; - center2[1] = vertex[1] + sin2*b; - - CGContextScaleCTM(outContext, a, b); - - CGContextBeginPath(outContext); - CGContextMoveToPoint(outContext, (float) vertex[0], - (float) vertex[1]); - CGContextAddLineToPoint(outContext, - (float) (center1[0] + 0.5), - (float) (center1[1] + 0.5)); - CGContextAddLineToPoint(outContext, - (float) (center2[0] + 0.5), - (float) (center2[1] + 0.5)); - CGContextFillPath(outContext); - } else if (gc->arc_mode == ArcPieSlice) { - float arc1, arc2; - CGContextBeginPath(outContext); - boundingRect = CGRectMake((float)(macWin->xOff + arcPtr[i].x), - (float)(macWin->yOff + arcPtr[i].y), - (float)arcPtr[i].width, - (float)arcPtr[i].height); - center = CGPointMake(CGRectGetMidX(boundingRect), - CGRectGetMidY(boundingRect)); - a = CGRectGetWidth(boundingRect)/2; - b = CGRectGetHeight(boundingRect)/2; - - CGContextTranslateCTM(outContext, center.x, center.y); - CGContextScaleCTM(outContext, a, b); - arc1 = radians(-(arcPtr[i].angle1/64)); - arc2 = radians(-(arcPtr[i].angle2/64)) + arc1; - CGContextAddArc(outContext, 0.0, 0.0, 1, - arc1, arc2, clockwise); - CGContextAddLineToPoint(outContext, 0.0f, 0.0f); - CGContextClosePath(outContext); - CGContextFillPath(outContext); + 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(); + ShowPen(); + FillCArc(&theRect, start, extent, gPenPat); + FillCPoly(polygon, gPenPat); + HidePen(); + KillPoly(polygon); + } else { + ShowPen(); + FillCArc(&theRect, start, extent, gPenPat); + HidePen(); } } - - TkMacOSXReleaseCGContext(macWin, destPort, &outContext); - } else { - - TkMacOSXSetUpGraphicsPort(gc, destPort); - - for (i = 0, arcPtr = arcArr;ixOff + arcPtr->x); - rect.top = (short) (macWin->yOff + arcPtr->y); - rect.right = (short) (rect.left + arcPtr->width); - rect.bottom = (short) (rect.top + arcPtr->height); - start = (short) (90 - (arcPtr->angle1 / 64)); - extent = (short) (- (arcPtr->angle2 / 64)); - - if (gc->arc_mode == ArcChord) { - boxWidth = rect.right - rect.left; - boxHeight = rect.bottom - rect.top; - angle = -(arcPtr->angle1/64.0)*PI/180.0; - sin1 = sin(angle); - cos1 = cos(angle); - angle -= (arcPtr->angle2/64.0)*PI/180.0; - sin2 = sin(angle); - cos2 = cos(angle); - vertex[0] = (rect.left + rect.right)/2.0; - vertex[1] = (rect.top + rect.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) ((rect.left + rect.right)/2), - (short) ((rect.top + rect.bottom)/2)); - - LineTo((short) (center1[0] + 0.5), (short) (center1[1] + 0.5)); - LineTo((short) (center2[0] + 0.5), (short) (center2[1] + 0.5)); - ClosePoly(); - - ShowPen(); - FillCArc(&rect, start, extent, gPenPat); - FillCPoly(polygon, gPenPat); - HidePen(); - - KillPoly(polygon); - } else { - ShowPen(); - FillCArc(&rect, start, extent, gPenPat); - HidePen(); - } - } } + SetGWorld(saveWorld, saveDevice); } #endif -#if 0 -/* +#ifdef TK_MACOSXDRAW_UNUSED +/* *---------------------------------------------------------------------- - * + * * XMaxRequestSize -- - * + * *---------------------------------------------------------------------- */ long @@ -1638,38 +1606,36 @@ TkScrollWindow( GWorldPtr destPort; Rect srcRect, scrollRect; RgnHandle visRgn, clipRgn; - - destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); + destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); - 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 - * scrollRect is the source rect extended by the offset (the union + * 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. */ - + SetRect(&srcRect, (short) (destDraw->xOff + x), - (short) (destDraw->yOff + y), - (short) (destDraw->xOff + x + width), - (short) (destDraw->yOff + y + height)); + (short) (destDraw->yOff + y), + (short) (destDraw->xOff + x + width), + (short) (destDraw->yOff + y + height)); scrollRect = srcRect; if (dx < 0) { - scrollRect.left += dx; + scrollRect.left += dx; } else { - scrollRect.right += dx; + scrollRect.right += dx; } if (dy < 0) { - scrollRect.top += dy; + scrollRect.top += dy; } else { - scrollRect.bottom += dy; + scrollRect.bottom += dy; } /* @@ -1686,7 +1652,7 @@ TkScrollWindow( DiffRgn(clipRgn, rgn, clipRgn); SetPortClipRegion(destPort, clipRgn); 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 @@ -1694,22 +1660,22 @@ TkScrollWindow( */ 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; + 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); /* @@ -1719,9 +1685,9 @@ TkScrollWindow( * created. */ if (EmptyRgn(rgn)) { - return 0; + return 0; } else { - return 1; + return 1; } } @@ -1749,44 +1715,44 @@ TkMacOSXSetUpGraphicsPort( RGBColor macColor; if (gPenPat == NULL) { - gPenPat = NewPixPat(); + gPenPat = NewPixPat(); } - + if (TkSetMacColor(gc->foreground, &macColor) == true) { - /* TODO: cache RGBPats for preformace - measure gains... */ - MakeRGBPat(gPenPat, &macColor); + /* TODO: cache RGBPats for preformace - measure gains... */ + MakeRGBPat(gPenPat, &macColor); } - + PenNormal(); if(gc->function == GXxor) { - PenMode(patXor); + PenMode(patXor); } if (gc->line_width > 1) { - PenSize(gc->line_width, gc->line_width); + 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. - */ + /* + * 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. + */ } } @@ -1819,6 +1785,7 @@ TkMacOSXSetUpCGContext( Rect boundsRect; CGAffineTransform coordsTransform; static RgnHandle clipRgn = NULL; + float w; err = QDBeginCGContext(destPort, contextPtr); outContext = *contextPtr; @@ -1828,7 +1795,7 @@ TkMacOSXSetUpCGContext( * 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. */ @@ -1852,50 +1819,52 @@ TkMacOSXSetUpCGContext( SyncCGContextOriginWithPort(outContext, destPort); - coordsTransform = CGAffineTransformMake(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, - (float) (boundsRect.bottom - boundsRect.top)); + 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), + RGBFLOATRED(macColor), + RGBFLOATGREEN(macColor), RGBFLOATBLUE(macColor), - 1.0f); + 1); CGContextSetRGBStrokeColor(outContext, RGBFLOATRED(macColor), RGBFLOATGREEN(macColor), RGBFLOATBLUE(macColor), - 1.0f); + 1); } - + if(gc->function == GXxor) { } - - CGContextSetLineWidth(outContext, (float) gc->line_width); + w = gc->line_width; /* When should we antialias? */ - if (gc->line_width < tkMacOSXCGAntiAliasLimit) { + 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); } + CGContextSetLineWidth(outContext, w); - if (gc->line_style != LineSolid) { + if (gc->line_style != LineSolid) { int num = 0; char *p = &(gc->dashes); - float dashOffset = (float) gc->dash_offset; + float dashOffset = gc->dash_offset; float lengths[10]; while (p[num] != '\0') { - lengths[num] = (float) (p[num]); + lengths[num] = p[num]; num++; } CGContextSetLineDash(outContext, dashOffset, lengths, num); } - + if (gc->cap_style == CapButt) { /* * What about CapNotLast, CapProjecting? @@ -1907,7 +1876,7 @@ TkMacOSXSetUpCGContext( } else if (gc->cap_style == CapProjecting) { CGContextSetLineCap(outContext, kCGLineCapSquare); } - + if (gc->join_style == JoinMiter) { CGContextSetLineJoin(outContext, kCGLineJoinMiter); } else if (gc->join_style == JoinRound) { @@ -1935,14 +1904,14 @@ TkMacOSXSetUpCGContext( static void TkMacOSXReleaseCGContext( - MacDrawable *macWin, - CGrafPtr destPort, - CGContextRef *outContext) + MacDrawable *macWin, + CGrafPtr destPort, + CGContextRef *outContext) { CGContextSynchronize(*outContext); QDEndCGContext(destPort, outContext); } - + /* *---------------------------------------------------------------------- * @@ -1967,9 +1936,9 @@ TkMacOSXSetUpClippingRgn( MacDrawable *macDraw = (MacDrawable *) drawable; if (macDraw->winPtr != NULL) { - if (macDraw->flags & TK_CLIP_INVALID) { - TkMacOSXUpdateClipRgn(macDraw->winPtr); - } + if (macDraw->flags & TK_CLIP_INVALID) { + TkMacOSXUpdateClipRgn(macDraw->winPtr); + } #if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_DRAWING) TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, @@ -1981,34 +1950,34 @@ TkMacOSXSetUpClippingRgn( } #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 (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); - } - } + /* + * 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 (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); + } + } } } @@ -2045,11 +2014,11 @@ TkMacOSXMakeStippleMap( Rect bounds; destPort = TkMacOSXGetDrawablePort(drawable); - + GetPortBounds (destPort, &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; @@ -2063,15 +2032,15 @@ TkMacOSXMakeStippleMap( 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(GetPortBitMapForCopyBits(destPort), bitmapPtr, - &portRect, &bounds, srcCopy, NULL); - } + for (j = 0; j < width; j += stippleWidth) { + bounds.left = j; + bounds.top = i; + bounds.right = j + stippleWidth; + bounds.bottom = i + stippleHeight; + + CopyBits(GetPortBitMapForCopyBits(destPort), bitmapPtr, + &portRect, &bounds, srcCopy, NULL); + } } return bitmapPtr; } @@ -2098,12 +2067,12 @@ InvertByte( { unsigned char i; unsigned char mask = 1, result = 0; - + for (i = (1 << 7); i != 0; i /= 2) { - if (data & mask) { - result |= i; - } - mask = mask << 1; + if (data & mask) { + result |= i; + } + mask = mask << 1; } return result; } @@ -2117,7 +2086,7 @@ InvertByte( * 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 + * 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. @@ -2132,22 +2101,22 @@ InvertByte( *---------------------------------------------------------------------- */ -void +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); + TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth, drawable, 0); } else { - TkDrawInsetFocusHighlight (tkwin, bgGC, highlightWidth, drawable, 0); - if (fgGC != bgGC) { - TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth - 1, - drawable, 0); - } + TkDrawInsetFocusHighlight (tkwin, bgGC, highlightWidth, drawable, 0); + if (fgGC != bgGC) { + TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth - 1, + drawable, 0); + } } } diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 9024697..cc4f062 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXInit.c,v 1.23 2006/08/18 07:47:10 das Exp $ + * RCS: @(#) $Id: tkMacOSXInit.c,v 1.24 2006/10/16 15:35:28 das Exp $ */ #include "tkMacOSXInt.h" @@ -137,7 +137,7 @@ TkpInit(interp) TkMacOSXInitCarbonEvents(interp); TkMacOSXInitMenus(interp); TkMacOSXUseAntialiasedText(interp, -1); - TkMacOSXInitCGDrawing(interp, TRUE, 3); + TkMacOSXInitCGDrawing(interp, TRUE, 0); TkMacOSXInitKeyboard(interp); encoding = CFStringGetSystemEncoding(); -- cgit v0.12