summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXDraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r--macosx/tkMacOSXDraw.c1508
1 files changed, 716 insertions, 792 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 8ecb7d9..d01a669 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -1,18 +1,18 @@
-/*
+/*
* tkMacOSXDraw.c --
*
- * This file contains functions that perform drawing to
- * Xlib windows. Most of the functions simple emulate
- * Xlib functions.
+ * This file contains functions that perform drawing to
+ * Xlib windows. Most of the functions simple emulate
+ * Xlib functions.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright 2001, Apple Computer, Inc.
- * Copyright (c) 2006 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.20 2007/04/21 19:06:37 hobbs Exp $
+ * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.21 2007/04/23 21:24:33 das Exp $
*/
#include "tkMacOSXInt.h"
@@ -24,10 +24,7 @@
#endif
*/
-#define RGBFLOATRED(c) ((c).red / 65535.0)
-#define RGBFLOATGREEN(c) ((c).green / 65535.0)
-#define RGBFLOATBLUE(c) ((c).blue / 65535.0)
-#define radians(d) ((d) * (M_PI/180.0))
+#define radians(d) ((d) * (M_PI/180.0))
/*
* Non-antialiased CG drawing looks better and more like X11 drawing when using
@@ -39,8 +36,9 @@
* Temporary regions that can be reused.
*/
-static RgnHandle tmpRgn = NULL;
-static RgnHandle tmpRgn2 = NULL;
+RgnHandle tkMacOSXtmpRgn1 = NULL;
+RgnHandle tkMacOSXtmpRgn2 = NULL;
+
static PixPatHandle gPenPat = NULL;
static int useCGDrawing = 1;
@@ -54,32 +52,29 @@ static int useThemedFrame = 0;
* Prototypes for functions used only in this file.
*/
static unsigned char InvertByte(unsigned char data);
-static void TkMacOSXSetUpCGContext(MacDrawable *macWin, CGrafPtr destPort,
- GC gc, CGContextRef *contextPtr);
-static void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort,
- CGContextRef *context);
+
/*
*----------------------------------------------------------------------
*
* TkMacOSXInitCGDrawing --
*
- * Initializes link vars that control CG drawing.
+ * Initializes link vars that control CG drawing.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
MODULE_SCOPE int
-TkMacOSXInitCGDrawing(interp, enable, limit)
- Tcl_Interp *interp;
- int enable;
- int limit;
+TkMacOSXInitCGDrawing(
+ Tcl_Interp *interp,
+ int enable,
+ int limit)
{
static Boolean initialized = FALSE;
@@ -104,15 +99,29 @@ TkMacOSXInitCGDrawing(interp, enable, limit)
/*
* Piggy-back the themed drawing var init here.
*/
+
if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel",
- (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
+ (char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
Tcl_ResetResult(interp);
}
if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame",
- (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
+ (char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
Tcl_ResetResult(interp);
}
+
+ if (tkMacOSXtmpRgn1 == NULL) {
+ tkMacOSXtmpRgn1 = NewRgn();
+ }
+ if (tkMacOSXtmpRgn2 == NULL) {
+ tkMacOSXtmpRgn2 = NewRgn();
+ }
}
+#ifdef TK_MAC_DEBUG_DRAWING
+ TkMacOSXInitNamedDebugSymbol(QD, void, QD_DebugPrint, char*);
+ if (QD_DebugPrint) {
+ ; /* gdb: b *QD_DebugPrint */
+ }
+#endif /* TK_MAC_DEBUG_WINDOWS */
return TCL_OK;
}
@@ -121,41 +130,37 @@ TkMacOSXInitCGDrawing(interp, enable, limit)
*
* XCopyArea --
*
- * Copies data from one drawable to another using block transfer
- * routines.
+ * Copies data from one drawable to another using block transfer
+ * routines.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Data is moved from a window or bitmap to a second window or
- * bitmap.
+ * Data is moved from a window or bitmap to a second window or
+ * bitmap.
*
*----------------------------------------------------------------------
*/
void
XCopyArea(
- Display* display, /* Display. */
- Drawable src, /* Source drawable. */
- Drawable dst, /* Destination drawable. */
- GC gc, /* GC to use. */
- int src_x, /* X & Y, width & height */
- int src_y, /* define the source rectangle */
- unsigned int width, /* the will be copied. */
+ Display *display, /* Display. */
+ Drawable src, /* Source drawable. */
+ Drawable dst, /* Destination drawable. */
+ GC gc, /* GC to use. */
+ int src_x, /* X & Y, width & height */
+ int src_y, /* define the source rectangle */
+ unsigned int width, /* the will be copied. */
unsigned int height,
- int dest_x, /* Dest X & Y on dest rect. */
+ int dest_x, /* Dest X & Y on dest rect. */
int dest_y)
{
- Rect srcRect, dstRect;
- Rect * srcPtr, * dstPtr;
- const BitMap * srcBit;
- const BitMap * dstBit;
- MacDrawable *srcDraw = (MacDrawable *) src;
- MacDrawable *dstDraw = (MacDrawable *) dst;
- CGrafPtr srcPort, dstPort;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
+ Rect srcRect, dstRect, *srcPtr, *dstPtr;
+ const BitMap *srcBit, *dstBit;
+ MacDrawable *srcDraw = (MacDrawable *) src, *dstDraw = (MacDrawable *) dst;
+ CGrafPtr srcPort, dstPort, savePort;
+ Boolean portChanged;
short tmode;
RGBColor origForeColor, origBackColor, whiteColor, blackColor;
Rect clpRect;
@@ -164,8 +169,7 @@ XCopyArea(
srcPort = TkMacOSXGetDrawablePort(src);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(dstPort, NULL);
+ portChanged = QDSwapPort(dstPort, &savePort);
GetForeColor(&origForeColor);
GetBackColor(&origBackColor);
whiteColor.red = 0;
@@ -177,9 +181,6 @@ XCopyArea(
blackColor.green = 0xFFFF;
RGBBackColor(&blackColor);
- if (tmpRgn2 == NULL) {
- tmpRgn2 = NewRgn();
- }
srcPtr = &srcRect;
SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
(short) (srcDraw->yOff + src_y),
@@ -195,18 +196,20 @@ XCopyArea(
(short) (dstDraw->yOff + dest_y + height));
}
TkMacOSXSetUpClippingRgn(dst);
+
/*
- * We will change the clip rgn in this routine, so we need to
- * be able to restore it when we exit.
+ * We will change the clip rgn in this routine, so we need to
+ * be able to restore it when we exit.
*/
- GetClip(tmpRgn2);
+ TkMacOSXCheckTmpRgnEmpty(2);
+ GetClip(tkMacOSXtmpRgn2);
if (tkPictureIsOpen) {
/*
* When rendering into a picture, after a call to "OpenCPicture"
* the clipping is seriously WRONG and also INCONSISTENT with the
* clipping for single plane bitmaps.
- * To circumvent this problem, we clip to the whole window
+ * To circumvent this problem, we clip to the whole window
* In this case, would have also clipped to the srcRect
* ClipRect(&srcRect);
*/
@@ -215,23 +218,22 @@ XCopyArea(
dstPtr = &srcRect;
ClipRect(&clpRect);
}
- if (!gc->clip_mask) {
- } else if (((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
+ if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type
+ == TKP_CLIP_REGION) {
RgnHandle clipRgn = (RgnHandle)
((TkpClipMask*)gc->clip_mask)->value.region;
-
int xOffset = 0, yOffset = 0;
- if (tmpRgn == NULL) {
- tmpRgn = NewRgn();
- }
+
if (!tkPictureIsOpen) {
xOffset = dstDraw->xOff + gc->clip_x_origin;
yOffset = dstDraw->yOff + gc->clip_y_origin;
OffsetRgn(clipRgn, xOffset, yOffset);
}
- GetClip(tmpRgn);
- SectRgn(tmpRgn, clipRgn, tmpRgn);
- SetClip(tmpRgn);
+ TkMacOSXCheckTmpRgnEmpty(1);
+ GetClip(tkMacOSXtmpRgn1);
+ SectRgn(tkMacOSXtmpRgn1, clipRgn, tkMacOSXtmpRgn1);
+ SetClip(tkMacOSXtmpRgn1);
+ SetEmptyRgn(tkMacOSXtmpRgn1);
if (!tkPictureIsOpen) {
OffsetRgn(clipRgn, -xOffset, -yOffset);
}
@@ -243,8 +245,11 @@ XCopyArea(
CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
RGBForeColor(&origForeColor);
RGBBackColor(&origBackColor);
- SetClip(tmpRgn2);
- SetGWorld(saveWorld, saveDevice);
+ SetClip(tkMacOSXtmpRgn2);
+ SetEmptyRgn(tkMacOSXtmpRgn2);
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
+ }
}
/*
@@ -252,45 +257,37 @@ XCopyArea(
*
* XCopyPlane --
*
- * Copies a bitmap from a source drawable to a destination
- * drawable. The plane argument specifies which bit plane of
- * the source contains the bitmap. Note that this implementation
- * ignores the gc->function.
+ * Copies a bitmap from a source drawable to a destination
+ * drawable. The plane argument specifies which bit plane of
+ * the source contains the bitmap. Note that this implementation
+ * ignores the gc->function.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Changes the destination drawable.
+ * Changes the destination drawable.
*
*----------------------------------------------------------------------
*/
void
XCopyPlane(
- Display* display, /* Display. */
- Drawable src, /* Source drawable. */
- Drawable dst, /* Destination drawable. */
- GC gc, /* The GC to use. */
- int src_x, /* X, Y, width & height */
- int src_y, /* define the source rect. */
- unsigned int width,
- unsigned int height,
- int dest_x, /* X & Y on dest where we will copy. */
- int dest_y,
- unsigned long plane) /* Which plane to copy. */
+ Display *display, /* Display. */
+ Drawable src, /* Source drawable. */
+ Drawable dst, /* Destination drawable. */
+ GC gc, /* The GC to use. */
+ int src_x, int src_y, /* X, Y, width & height define the source
+ * rect. */
+ unsigned int width, unsigned int height,
+ int dest_x, int dest_y, /* X & Y on dest where we will copy. */
+ unsigned long plane) /* Which plane to copy. */
{
- Rect srcRect, dstRect;
- Rect * srcPtr, * dstPtr;
- const BitMap * srcBit;
- const BitMap * dstBit;
- const BitMap * mskBit;
- MacDrawable *srcDraw = (MacDrawable *) src;
- MacDrawable *dstDraw = (MacDrawable *) dst;
- GWorldPtr srcPort, dstPort, mskPort;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- RGBColor macColor;
+ Rect srcRect, dstRect, *srcPtr, *dstPtr;
+ const BitMap *srcBit, *dstBit, *mskBit;
+ MacDrawable *srcDraw = (MacDrawable *) src, *dstDraw = (MacDrawable *) dst;
+ CGrafPtr srcPort, dstPort, mskPort, savePort;
+ Boolean portChanged;
TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
short tmode;
@@ -298,8 +295,7 @@ XCopyPlane(
dstPort = TkMacOSXGetDrawablePort(dst);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(dstPort, NULL);
+ portChanged = QDSwapPort(dstPort, &savePort);
TkMacOSXSetUpClippingRgn(dst);
srcBit = GetPortBitMapForCopyBits(srcPort);
@@ -314,7 +310,7 @@ XCopyPlane(
* When rendering into a picture, after a call to "OpenCPicture"
* the clipping is seriously WRONG and also INCONSISTENT with the
* clipping for color bitmaps.
- * To circumvent this problem, we clip to the whole window
+ * To circumvent this problem, we clip to the whole window
*/
Rect clpRect;
@@ -331,24 +327,21 @@ XCopyPlane(
tmode = srcOr;
tmode = srcCopy + transparent;
- if (TkSetMacColor(gc->foreground, &macColor) == true) {
- RGBForeColor(&macColor);
- }
+ TkMacOSXSetColorInPort(gc->foreground, 1, NULL);
if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) {
/*
* Case 1: opaque bitmaps.
*/
- TkSetMacColor(gc->background, &macColor);
- RGBBackColor(&macColor);
+ TkMacOSXSetColorInPort(gc->background, 0, NULL);
tmode = srcCopy;
CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
} else if (clipPtr->type == TKP_CLIP_PIXMAP) {
if (clipPtr->value.pixmap == src) {
PixMapHandle pm;
/*
- * Case 2: transparent bitmaps. If it's color we ignore
+ * Case 2: transparent bitmaps. If it's color we ignore
* the forecolor.
*/
@@ -371,8 +364,9 @@ XCopyPlane(
srcPtr, srcPtr, dstPtr, tmode, NULL);
}
}
-
- SetGWorld(saveWorld, saveDevice);
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
+ }
}
/*
@@ -380,14 +374,14 @@ XCopyPlane(
*
* TkPutImage --
*
- * Copies a subimage from an in-memory image to a rectangle of
- * of the specified drawable.
+ * Copies a subimage from an in-memory image to a rectangle of
+ * of the specified drawable.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws the image on the specified drawable.
+ * Draws the image on the specified drawable.
*
*----------------------------------------------------------------------
*/
@@ -407,9 +401,8 @@ TkPutImage(
unsigned int width, /* Same width & height for both */
unsigned int height) /* distination and source. */
{
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ CGrafPtr destPort, savePort;
+ Boolean portChanged;
const BitMap * destBits;
MacDrawable *dstDraw = (MacDrawable *) d;
int i, j;
@@ -420,9 +413,8 @@ TkPutImage(
int slices, sliceRowBytes, lastSliceRowBytes, sliceWidth, lastSliceWidth;
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
destPort = TkMacOSXGetDrawablePort(d);
- SetGWorld(destPort, NULL);
+ portChanged = QDSwapPort(destPort, &savePort);
destBits = GetPortBitMapForCopyBits(destPort);
TkMacOSXSetUpClippingRgn(d);
@@ -433,10 +425,11 @@ TkPutImage(
* When rendering into a picture, after a call to "OpenCPicture"
* the clipping is seriously WRONG and also INCONSISTENT with the
* clipping for single plane bitmaps.
- * To circumvent this problem, we clip to the whole window
+ * To circumvent this problem, we clip to the whole window
*/
Rect clpRect;
+
GetPortBounds(destPort,&clpRect);
ClipRect(&clpRect);
destPtr = srcPtr;
@@ -447,14 +440,17 @@ TkPutImage(
}
if (image->obdata) {
- /* Image from XGetImage, copy from containing GWorld directly */
- GWorldPtr srcPort = TkMacOSXGetDrawablePort((Drawable)image->obdata);
- CopyBits(GetPortBitMapForCopyBits(srcPort),
- destBits, srcPtr, destPtr, srcCopy, NULL);
+ /*
+ * Image from XGetImage, copy from containing GWorld directly.
+ */
+
+ CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort((Drawable)
+ image->obdata)), destBits, srcPtr, destPtr, srcCopy, NULL);
} else if (image->depth == 1) {
/*
* BW image
*/
+
const int maxRowBytes = 0x3ffe;
BitMap bitmap;
int odd;
@@ -487,7 +483,7 @@ TkPutImage(
oldPtr = dataPtr;
odd = sliceRowBytes % 2;
if (!newData) {
- newData = (char *) ckalloc(image->height * (sliceRowBytes+odd));
+ newData = ckalloc(image->height * (sliceRowBytes+odd));
}
newPtr = newData;
for (i = 0; i < image->height; i++) {
@@ -512,6 +508,7 @@ TkPutImage(
/*
* Color image
*/
+
const int maxRowBytes = 0x3ffc;
PixMap pixmap;
@@ -519,7 +516,7 @@ TkPutImage(
pixmap.bounds.top = 0;
pixmap.bounds.bottom = (short) image->height;
pixmap.pixelType = RGBDirect;
- pixmap.pmVersion = baseAddr32; /* 32bit clean */
+ pixmap.pmVersion = baseAddr32; /* 32bit clean */
pixmap.packType = 0;
pixmap.packSize = 0;
pixmap.hRes = 0x00480000;
@@ -580,8 +577,9 @@ TkPutImage(
if (newData != NULL) {
ckfree(newData);
}
-
- SetGWorld(saveWorld, saveDevice);
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
+ }
}
/*
@@ -589,74 +587,62 @@ TkPutImage(
*
* XDrawLines --
*
- * Draw connected lines.
+ * Draw connected lines.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Renders a series of connected lines.
+ * Renders a series of connected lines.
*
*----------------------------------------------------------------------
*/
void
XDrawLines(
- Display* display, /* Display. */
+ Display *display, /* Display. */
Drawable d, /* Draw on this. */
GC gc, /* Use this GC. */
- XPoint* points, /* Array of points. */
+ XPoint *points, /* Array of points. */
int npoints, /* Number of points. */
int mode) /* Line drawing mode. */
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GWorldPtr destPort;
- GDHandle saveDevice;
+ TkMacOSXDrawingContext dc;
int i, lw = gc->line_width;
if (npoints < 2) {
return; /* TODO: generate BadValue error. */
}
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
- float prevx, prevy;
- float o = (lw % 2) ? .5 : 0;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
+ double prevx, prevy;
+ double o = (lw % 2) ? .5 : 0;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- CGContextBeginPath(outContext);
+ CGContextBeginPath(dc.context);
prevx = macWin->xOff + points[0].x + o;
prevy = macWin->yOff + points[0].y + o;
- CGContextMoveToPoint(outContext, prevx, prevy);
+ CGContextMoveToPoint(dc.context, prevx, prevy);
for (i = 1; i < npoints; i++) {
if (mode == CoordModeOrigin) {
- CGContextAddLineToPoint(outContext,
+ CGContextAddLineToPoint(dc.context,
macWin->xOff + points[i].x + o,
macWin->yOff + points[i].y + o);
} else {
prevx += points[i].x;
prevy += points[i].y;
- CGContextAddLineToPoint(outContext, prevx, prevy);
+ CGContextAddLineToPoint(dc.context, prevx, prevy);
}
}
- CGContextStrokePath(outContext);
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ CGContextStrokePath(dc.context);
} else {
int o = -lw/2;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- ShowPen();
- PenPixPat(gPenPat);
/* This is broken for fat lines, it is not possible to correctly
* imitate X11 drawing of oblique fat lines with QD line drawing,
* we should draw a filled polygon instead. */
+
MoveTo((short) (macWin->xOff + points[0].x + o),
(short) (macWin->yOff + points[0].y + o));
for (i = 1; i < npoints; i++) {
@@ -667,10 +653,8 @@ XDrawLines(
Line((short) points[i].x, (short) points[i].y);
}
}
- HidePen();
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
/*
@@ -678,71 +662,58 @@ XDrawLines(
*
* XDrawSegments --
*
- * Draw unconnected lines.
+ * Draw unconnected lines.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Renders a series of unconnected lines.
+ * Renders a series of unconnected lines.
*
*----------------------------------------------------------------------
*/
-void XDrawSegments(
+void
+XDrawSegments(
Display *display,
- Drawable d,
+ Drawable d,
GC gc,
XSegment *segments,
- int nsegments)
+ int nsegments)
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GWorldPtr destPort;
- GDHandle saveDevice;
+ TkMacOSXDrawingContext dc;
int i, lw = gc->line_width;
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
+ double o = (lw % 2) ? .5 : 0;
- if (useCGDrawing) {
- CGContextRef outContext;
- float o = (lw % 2) ? .5 : 0;
-
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
for (i = 0; i < nsegments; i++) {
- CGContextBeginPath(outContext);
- CGContextMoveToPoint(outContext,
+ CGContextBeginPath(dc.context);
+ CGContextMoveToPoint(dc.context,
macWin->xOff + segments[i].x1 + o,
macWin->yOff + segments[i].y1 + o);
- CGContextAddLineToPoint(outContext,
+ CGContextAddLineToPoint(dc.context,
macWin->xOff + segments[i].x2 + o,
macWin->yOff + segments[i].y2 + o);
- CGContextStrokePath(outContext);
+ CGContextStrokePath(dc.context);
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
int o = -lw/2;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- ShowPen();
- PenPixPat(gPenPat);
/* This is broken for fat lines, it is not possible to correctly
* imitate X11 drawing of oblique fat lines with QD line drawing,
* we should draw a filled polygon instead. */
+
for (i = 0; i < nsegments; i++) {
MoveTo((short) (macWin->xOff + segments[i].x1 + o),
(short) (macWin->yOff + segments[i].y1 + o));
LineTo((short) (macWin->xOff + segments[i].x2 + o),
(short) (macWin->yOff + segments[i].y2 + o));
}
- HidePen();
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
/*
@@ -750,13 +721,13 @@ void XDrawSegments(
*
* XFillPolygon --
*
- * Draws a filled polygon.
+ * Draws a filled polygon.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws a filled polygon on the specified drawable.
+ * Draws a filled polygon on the specified drawable.
*
*----------------------------------------------------------------------
*/
@@ -772,45 +743,33 @@ XFillPolygon(
int mode) /* Drawing mode. */
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
int i;
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
- float prevx, prevy;
- float o = (gc->line_width % 2) ? .5 : 0;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
+ double prevx, prevy;
+ double o = (gc->line_width % 2) ? .5 : 0;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- CGContextBeginPath(outContext);
+ CGContextBeginPath(dc.context);
prevx = macWin->xOff + points[0].x + o;
prevy = macWin->yOff + points[0].y + o;
- CGContextMoveToPoint(outContext, prevx, prevy);
+ CGContextMoveToPoint(dc.context, prevx, prevy);
for (i = 1; i < npoints; i++) {
if (mode == CoordModeOrigin) {
- CGContextAddLineToPoint(outContext,
+ CGContextAddLineToPoint(dc.context,
macWin->xOff + points[i].x + o,
macWin->yOff + points[i].y + o);
} else {
prevx += points[i].x;
prevy += points[i].y;
- CGContextAddLineToPoint(outContext, prevx, prevy);
+ CGContextAddLineToPoint(dc.context, prevx, prevy);
}
}
- CGContextEOFillPath(outContext);
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ CGContextEOFillPath(dc.context);
} else {
PolyHandle polygon;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- PenNormal();
polygon = OpenPoly();
MoveTo((short) (macWin->xOff + points[0].x),
(short) (macWin->yOff + points[0].y));
@@ -823,11 +782,10 @@ XFillPolygon(
}
}
ClosePoly();
- FillCPoly(polygon, gPenPat);
+ FillCPoly(polygon, dc.penPat);
KillPoly(polygon);
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
/*
@@ -835,71 +793,55 @@ XFillPolygon(
*
* XDrawRectangle --
*
- * Draws a rectangle.
+ * Draws a rectangle.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws a rectangle on the specified drawable.
+ * Draws a rectangle on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XDrawRectangle(
- Display* display, /* Display. */
- Drawable d, /* Draw on this. */
- GC gc, /* Use this GC. */
- int x, /* Upper left corner. */
- int y,
- unsigned int width, /* Width & height of rect. */
+ Display *display, /* Display. */
+ Drawable d, /* Draw on this. */
+ GC gc, /* Use this GC. */
+ int x, int y, /* Upper left corner. */
+ unsigned int width, /* Width & height of rect. */
unsigned int height)
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
int lw = gc->line_width;
if (width == 0 || height == 0) {
return;
}
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- float o = (lw % 2) ? .5 : 0;
+ double o = (lw % 2) ? .5 : 0;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
rect = CGRectMake(
macWin->xOff + x + o,
macWin->yOff + y + o,
width, height);
- CGContextStrokeRect(outContext, rect);
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ CGContextStrokeRect(dc.context, rect);
} else {
Rect theRect;
int o = -lw/2;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- ShowPen();
- PenPixPat(gPenPat);
- theRect.left = (short) (macWin->xOff + x + o);
- theRect.top = (short) (macWin->yOff + y + o);
- theRect.right = (short) (theRect.left + width + lw);
+ theRect.left = (short) (macWin->xOff + x + o);
+ theRect.top = (short) (macWin->yOff + y + o);
+ theRect.right = (short) (theRect.left + width + lw);
theRect.bottom = (short) (theRect.top + height + lw);
FrameRect(&theRect);
- HidePen();
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
#ifdef TK_MACOSXDRAW_UNUSED
@@ -908,27 +850,27 @@ XDrawRectangle(
*
* XDrawRectangles --
*
- * Draws the outlines of the specified rectangles as if a
- * five-point PolyLine protocol request were specified for each
- * rectangle:
+ * Draws the outlines of the specified rectangles as if a
+ * five-point PolyLine protocol request were specified for each
+ * rectangle:
*
- * [x,y] [x+width,y] [x+width,y+height] [x,y+height]
- * [x,y]
+ * [x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y]
*
- * For the specified rectangles, these functions do not draw a
- * pixel more than once. XDrawRectangles draws the rectangles in
- * the order listed in the array. If rectangles intersect, the
- * intersecting pixels are drawn multiple times. Draws a
- * rectangle.
+ * For the specified rectangles, these functions do not draw a
+ * pixel more than once. XDrawRectangles draws the rectangles in
+ * the order listed in the array. If rectangles intersect, the
+ * intersecting pixels are drawn multiple times. Draws a
+ * rectangle.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws rectangles on the specified drawable.
+ * Draws rectangles on the specified drawable.
*
*----------------------------------------------------------------------
*/
+
void
XDrawRectangles(
Display *display,
@@ -938,24 +880,15 @@ XDrawRectangles(
int nRects)
{
MacDrawable *macWin = (MacDrawable *) drawable;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
XRectangle * rectPtr;
int i, lw = gc->line_width;
- destPort = TkMacOSXGetDrawablePort(drawable);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(drawable);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- float o = (lw % 2) ? .5 : 0;
+ double o = (lw % 2) ? .5 : 0;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) {
if (rectPtr->width == 0 || rectPtr->height == 0) {
continue;
@@ -964,16 +897,12 @@ XDrawRectangles(
macWin->xOff + rectPtr->x + o,
macWin->yOff + rectPtr->y + o,
rectPtr->width, rectPtr->height);
- CGContextStrokeRect(outContext, rect);
+ CGContextStrokeRect(dc.context, rect);
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
Rect theRect;
int o = -lw/2;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- ShowPen();
- PenPixPat(gPenPat);
for (i = 0, rectPtr = rectArr; i < nRects;i++, rectPtr++) {
theRect.left = (short) (macWin->xOff + rectPtr->x + o);
theRect.top = (short) (macWin->yOff + rectPtr->y + o);
@@ -981,10 +910,8 @@ XDrawRectangles(
theRect.bottom = (short) (theRect.top + rectPtr->height + lw);
FrameRect(&theRect);
}
- HidePen();
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
#endif
@@ -993,42 +920,34 @@ XDrawRectangles(
*
* XFillRectangles --
*
- * Fill multiple rectangular areas in the given drawable.
+ * Fill multiple rectangular areas in the given drawable.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws onto the specified drawable.
+ * Draws onto the specified drawable.
*
*----------------------------------------------------------------------
*/
+
void
XFillRectangles(
- Display* display, /* Display. */
- Drawable d, /* Draw on this. */
- GC gc, /* Use this GC. */
- XRectangle *rectangles, /* Rectangle array. */
- int n_rectangles) /* Number of rectangles. */
+ Display* display, /* Display. */
+ Drawable d, /* Draw on this. */
+ GC gc, /* Use this GC. */
+ XRectangle *rectangles, /* Rectangle array. */
+ int n_rectangles) /* Number of rectangles. */
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
XRectangle * rectPtr;
int i;
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
if (rectPtr->width == 0 || rectPtr->height == 0) {
continue;
@@ -1037,23 +956,20 @@ XFillRectangles(
macWin->xOff + rectPtr->x,
macWin->yOff + rectPtr->y,
rectPtr->width, rectPtr->height);
- CGContextFillRect(outContext, rect);
+ CGContextFillRect(dc.context, rect);
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
Rect theRect;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
theRect.left = (short) (macWin->xOff + rectPtr->x);
theRect.top = (short) (macWin->yOff + rectPtr->y);
theRect.right = (short) (theRect.left + rectPtr->width);
theRect.bottom = (short) (theRect.top + rectPtr->height);
- FillCRect(&theRect, gPenPat);
+ FillCRect(&theRect, dc.penPat);
}
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
/*
@@ -1061,98 +977,85 @@ XFillRectangles(
*
* XDrawArc --
*
- * Draw an arc.
+ * Draw an arc.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws an arc on the specified drawable.
+ * Draws an arc on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XDrawArc(
- Display* display, /* Display. */
- Drawable d, /* Draw on this. */
- GC gc, /* Use this GC. */
- int x, /* Upper left of */
- int y, /* bounding rect. */
- unsigned int width, /* Width & height. */
+ Display* display, /* Display. */
+ Drawable d, /* Draw on this. */
+ GC gc, /* Use this GC. */
+ int x, int y, /* Upper left of bounding rect. */
+ unsigned int width, /* Width & height. */
unsigned int height,
- int angle1, /* Staring angle of arc. */
- int angle2) /* Extent of arc. */
+ int angle1, /* Staring angle of arc. */
+ int angle2) /* Extent of arc. */
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
int lw = gc->line_width;
if (width == 0 || height == 0 || angle2 == 0) {
return;
}
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- float o = (lw % 2) ? .5 : 0;
+ double o = (lw % 2) ? .5 : 0;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
rect = CGRectMake(
macWin->xOff + x + o,
macWin->yOff + y + o,
width, height);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
- if (angle1 == 0 && angle2 == 23040 &&
- CGContextStrokeEllipseInRect != NULL) {
- CGContextStrokeEllipseInRect(outContext, rect);
+ if (angle1 == 0 && angle2 == 23040
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+ && CGContextStrokeEllipseInRect != NULL
+#endif
+ ) {
+ CGContextStrokeEllipseInRect(dc.context, rect);
} else
#endif
{
CGMutablePathRef p = CGPathCreateMutable();
CGAffineTransform t = CGAffineTransformIdentity;
CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
- float w = CGRectGetWidth(rect);
+ double w = CGRectGetWidth(rect);
if (width != height) {
- t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w);
+ t = CGAffineTransformMakeScale(1.0, CGRectGetHeight(rect)/w);
c = CGPointApplyAffineTransform(c, CGAffineTransformInvert(t));
}
CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0),
radians(-(angle1 + angle2)/64.0), angle2 > 0);
- CGContextAddPath(outContext, p);
+ CGContextAddPath(dc.context, p);
CGPathRelease(p);
- CGContextStrokePath(outContext);
+ CGContextStrokePath(dc.context);
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
Rect theRect;
short start, extent;
int o = -lw/2;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- ShowPen();
- PenPixPat(gPenPat);
- theRect.left = (short) (macWin->xOff + x + o);
- theRect.top = (short) (macWin->yOff + y + o);
- theRect.right = (short) (theRect.left + width + lw);
+ theRect.left = (short) (macWin->xOff + x + o);
+ theRect.top = (short) (macWin->yOff + y + o);
+ theRect.right = (short) (theRect.left + width + lw);
theRect.bottom = (short) (theRect.top + height + lw);
- start = (short) (90 - (angle1/64));
+ start = (short) (90 - (angle1/64));
extent = (short) (-(angle2/64));
FrameArc(&theRect, start, extent);
- HidePen();
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
#ifdef TK_MACOSXDRAW_UNUSED
@@ -1161,23 +1064,24 @@ XDrawArc(
*
* XDrawArcs --
*
- * Draws multiple circular or elliptical arcs. Each arc is
- * specified by a rectangle and two angles. The center of the
- * circle or ellipse is the center of the rect- angle, and the
- * major and minor axes are specified by the width and height.
- * Positive angles indicate counterclock- wise motion, and
- * negative angles indicate clockwise motion. If the magnitude
- * of angle2 is greater than 360 degrees, XDrawArcs truncates it
- * to 360 degrees.
+ * Draws multiple circular or elliptical arcs. Each arc is
+ * specified by a rectangle and two angles. The center of the
+ * circle or ellipse is the center of the rect- angle, and the
+ * major and minor axes are specified by the width and height.
+ * Positive angles indicate counterclock- wise motion, and
+ * negative angles indicate clockwise motion. If the magnitude
+ * of angle2 is greater than 360 degrees, XDrawArcs truncates it
+ * to 360 degrees.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws an arc for each array element on the specified drawable.
+ * Draws an arc for each array element on the specified drawable.
*
*----------------------------------------------------------------------
*/
+
void
XDrawArcs(
Display *display,
@@ -1188,24 +1092,15 @@ XDrawArcs(
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
- XArc * arcPtr;
+ TkMacOSXDrawingContext dc;
+ XArc *arcPtr;
int i, lw = gc->line_width;
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- float o = (lw % 2) ? .5 : 0;
+ double o = (lw % 2) ? .5 : 0;
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
if (arcPtr->width == 0 || arcPtr->height == 0
|| arcPtr->angle2 == 0) {
@@ -1217,41 +1112,40 @@ XDrawArcs(
arcPtr->width, arcPtr->height);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
- if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 &&
- CGContextStrokeEllipseInRect != NULL) {
- CGContextStrokeEllipseInRect(outContext, rect);
+ if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+ && CGContextStrokeEllipseInRect != NULL
+#endif
+ ) {
+ CGContextStrokeEllipseInRect(dc.context, rect);
} else
#endif
{
CGMutablePathRef p = CGPathCreateMutable();
CGAffineTransform t = CGAffineTransformIdentity;
CGPoint c = CGPointMake(CGRectGetMidX(rect),
- CGRectGetMidY(rect));
- float w = CGRectGetWidth(rect);
+ CGRectGetMidY(rect));
+ double w = CGRectGetWidth(rect);
if (arcPtr->width != arcPtr->height) {
t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w);
c = CGPointApplyAffineTransform(c,
- CGAffineTransformInvert(t));
+ CGAffineTransformInvert(t));
}
CGPathAddArc(p, &t, c.x, c.y, w/2,
radians(-arcPtr->angle1/64.0),
radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0),
arcPtr->angle2 > 0);
- CGContextAddPath(outContext, p);
+ CGContextAddPath(dc.context, p);
CGPathRelease(p);
- CGContextStrokePath(outContext);
+ CGContextStrokePath(dc.context);
}
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
Rect theRect;
short start, extent;
int o = -lw/2;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- ShowPen();
- PenPixPat(gPenPat);
for (i = 0, arcPtr = arcArr;i < nArcs;i++, arcPtr++) {
theRect.left = (short) (macWin->xOff + arcPtr->x + o);
theRect.top = (short) (macWin->yOff + arcPtr->y + o);
@@ -1261,10 +1155,8 @@ XDrawArcs(
extent = (short) (-(arcPtr->angle2/64));
FrameArc(&theRect, start, extent);
}
- HidePen();
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
#endif
@@ -1273,71 +1165,64 @@ XDrawArcs(
*
* XFillArc --
*
- * Draw a filled arc.
+ * Draw a filled arc.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws a filled arc on the specified drawable.
+ * Draws a filled arc on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XFillArc(
- Display* display, /* Display. */
- Drawable d, /* Draw on this. */
- GC gc, /* Use this GC. */
- int x, /* Upper left of */
- int y, /* bounding rect. */
- unsigned int width, /* Width & height. */
+ Display* display, /* Display. */
+ Drawable d, /* Draw on this. */
+ GC gc, /* Use this GC. */
+ int x, int y, /* Upper left of bounding rect. */
+ unsigned int width, /* Width & height. */
unsigned int height,
- int angle1, /* Staring angle of arc. */
- int angle2) /* Extent of arc. */
+ int angle1, /* Staring angle of arc. */
+ int angle2) /* Extent of arc. */
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
int lw = gc->line_width;
if (width == 0 || height == 0 || angle2 == 0) {
return;
}
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- float o = (lw % 2) ? .5 : 0, u = 0;
+ double o = (lw % 2) ? .5 : 0, u = 0;
if (notAA(lw)) {
o += NON_AA_CG_OFFSET/2;
u += NON_AA_CG_OFFSET;
}
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
rect = CGRectMake(
macWin->xOff + x + o,
macWin->yOff + y + o,
width - u, height - u);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
- if (angle1 == 0 && angle2 == 23040 &&
- CGContextFillEllipseInRect != NULL) {
- CGContextFillEllipseInRect(outContext, rect);
+ if (angle1 == 0 && angle2 == 23040
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+ && CGContextFillEllipseInRect != NULL
+#endif
+ ) {
+ CGContextFillEllipseInRect(dc.context, rect);
} else
#endif
{
CGMutablePathRef p = CGPathCreateMutable();
CGAffineTransform t = CGAffineTransformIdentity;
CGPoint c = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
- float w = CGRectGetWidth(rect);
+ double w = CGRectGetWidth(rect);
if (width != height) {
t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w);
@@ -1349,11 +1234,10 @@ XFillArc(
CGPathAddArc(p, &t, c.x, c.y, w/2, radians(-angle1/64.0),
radians(-(angle1 + angle2)/64.0), angle2 > 0);
CGPathCloseSubpath(p);
- CGContextAddPath(outContext, p);
+ CGContextAddPath(dc.context, p);
CGPathRelease(p);
- CGContextFillPath(outContext);
+ CGContextFillPath(dc.context);
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
Rect theRect;
short start, extent;
@@ -1363,10 +1247,9 @@ XFillArc(
double boxWidth, boxHeight;
double vertex[2], center1[2], center2[2];
- TkMacOSXSetUpGraphicsPort(gc, destPort);
- theRect.left = (short) (macWin->xOff + x + o);
- theRect.top = (short) (macWin->yOff + y + o);
- theRect.right = (short) (theRect.left + width + lw);
+ theRect.left = (short) (macWin->xOff + x + o);
+ theRect.top = (short) (macWin->yOff + y + o);
+ theRect.right = (short) (theRect.left + width + lw);
theRect.bottom = (short) (theRect.top + height + lw);
start = (short) (90 - (angle1/64));
extent = (short) (-(angle2/64));
@@ -1392,19 +1275,14 @@ XFillArc(
LineTo((short) (center1[0] + .5), (short) (center1[1] + .5));
LineTo((short) (center2[0] + .5), (short) (center2[1] + .5));
ClosePoly();
- ShowPen();
- FillCArc(&theRect, start, extent, gPenPat);
- FillCPoly(polygon, gPenPat);
- HidePen();
+ FillCArc(&theRect, start, extent, dc.penPat);
+ FillCPoly(polygon, dc.penPat);
KillPoly(polygon);
} else {
- ShowPen();
- FillCArc(&theRect, start, extent, gPenPat);
- HidePen();
+ FillCArc(&theRect, start, extent, dc.penPat);
}
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
#ifdef TK_MACOSXDRAW_UNUSED
@@ -1413,16 +1291,17 @@ XFillArc(
*
* XFillArcs --
*
- * Draw a filled arc.
+ * Draw a filled arc.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Draws a filled arc for each array element on the specified drawable.
+ * Draws a filled arc for each array element on the specified drawable.
*
*----------------------------------------------------------------------
*/
+
void
XFillArcs(
Display *display,
@@ -1432,28 +1311,19 @@ XFillArcs(
int nArcs)
{
MacDrawable *macWin = (MacDrawable *) d;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ TkMacOSXDrawingContext dc;
XArc * arcPtr;
int i, lw = gc->line_width;
- destPort = TkMacOSXGetDrawablePort(d);
display->request++;
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(d);
-
- if (useCGDrawing) {
- CGContextRef outContext;
+ if (TkMacOSXSetupDrawingContext(d, gc, useCGDrawing, &dc)) {
CGRect rect;
- float o = (lw % 2) ? .5 : 0, u = 0;
+ double o = (lw % 2) ? .5 : 0, u = 0;
if (notAA(lw)) {
o += NON_AA_CG_OFFSET/2;
u += NON_AA_CG_OFFSET;
}
- TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
for (i = 0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
if (arcPtr->width == 0 || arcPtr->height == 0
|| arcPtr->angle2 == 0) {
@@ -1465,22 +1335,25 @@ XFillArcs(
arcPtr->width - u, arcPtr->height - u);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
- if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040 &&
- CGContextFillEllipseInRect != NULL) {
- CGContextFillEllipseInRect(outContext, rect);
+ if (arcPtr->angle1 == 0 && arcPtr->angle2 == 23040
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+ && CGContextFillEllipseInRect != NULL
+#endif
+ ) {
+ CGContextFillEllipseInRect(dc.context, rect);
} else
#endif
{
CGMutablePathRef p = CGPathCreateMutable();
CGAffineTransform t = CGAffineTransformIdentity;
CGPoint c = CGPointMake(CGRectGetMidX(rect),
- CGRectGetMidY(rect));
- float w = CGRectGetWidth(rect);
+ CGRectGetMidY(rect));
+ double w = CGRectGetWidth(rect);
if (arcPtr->width != arcPtr->height) {
t = CGAffineTransformMakeScale(1, CGRectGetHeight(rect)/w);
c = CGPointApplyAffineTransform(c,
- CGAffineTransformInvert(t));
+ CGAffineTransformInvert(t));
}
if (gc->arc_mode == ArcPieSlice) {
CGPathMoveToPoint(p, &t, c.x, c.y);
@@ -1490,12 +1363,11 @@ XFillArcs(
radians(-(arcPtr->angle1 + arcPtr->angle2)/64.0),
arcPtr->angle2 > 0);
CGPathCloseSubpath(p);
- CGContextAddPath(outContext, p);
+ CGContextAddPath(dc.context, p);
CGPathRelease(p);
- CGContextFillPath(outContext);
+ CGContextFillPath(dc.context);
}
}
- TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
Rect theRect;
short start, extent;
@@ -1505,7 +1377,6 @@ XFillArcs(
double boxWidth, boxHeight;
double vertex[2], center1[2], center2[2];
- TkMacOSXSetUpGraphicsPort(gc, destPort);
for (i = 0, arcPtr = arcArr;i<nArcs;i++, arcPtr++) {
theRect.left = (short) (macWin->xOff + arcPtr->x + o);
theRect.top = (short) (macWin->yOff + arcPtr->y + o);
@@ -1536,20 +1407,15 @@ XFillArcs(
LineTo((short) (center1[0] + .5), (short) (center1[1] + .5));
LineTo((short) (center2[0] + .5), (short) (center2[1] + .5));
ClosePoly();
- ShowPen();
- FillCArc(&theRect, start, extent, gPenPat);
- FillCPoly(polygon, gPenPat);
- HidePen();
+ FillCArc(&theRect, start, extent, dc.penPat);
+ FillCPoly(polygon, dc.penPat);
KillPoly(polygon);
} else {
- ShowPen();
- FillCArc(&theRect, start, extent, gPenPat);
- HidePen();
+ FillCArc(&theRect, start, extent, dc.penPat);
}
}
}
-
- SetGWorld(saveWorld, saveDevice);
+ TkMacOSXRestoreDrawingContext(&dc);
}
#endif
@@ -1561,8 +1427,10 @@ XFillArcs(
*
*----------------------------------------------------------------------
*/
+
long
-XMaxRequestSize(Display *display)
+XMaxRequestSize(
+ Display *display)
{
return (SHRT_MAX / 4);
}
@@ -1573,51 +1441,45 @@ XMaxRequestSize(Display *display)
*
* TkScrollWindow --
*
- * Scroll a rectangle of the specified window and accumulate
- * a damage region.
+ * Scroll a rectangle of the specified window and accumulate
+ * a damage region.
*
* Results:
- * Returns 0 if the scroll genereated no additional damage.
- * Otherwise, sets the region that needs to be repainted after
- * scrolling and returns 1.
+ * Returns 0 if the scroll genereated no additional damage.
+ * Otherwise, sets the region that needs to be repainted after
+ * scrolling and returns 1.
*
* Side effects:
- * Scrolls the bits in the window.
+ * Scrolls the bits in the window.
*
*----------------------------------------------------------------------
*/
int
TkScrollWindow(
- Tk_Window tkwin, /* The window to be scrolled. */
- GC gc, /* GC for window to be scrolled. */
- int x, /* Position rectangle to be scrolled. */
- int y,
- int width,
- int height,
- int dx, /* Distance rectangle should be moved. */
- int dy,
- TkRegion damageRgn) /* Region to accumulate damage in. */
+ Tk_Window tkwin, /* The window to be scrolled. */
+ GC gc, /* GC for window to be scrolled. */
+ int x, int y, /* Position rectangle to be scrolled. */
+ int width, int height,
+ int dx, int dy, /* Distance rectangle should be moved. */
+ TkRegion damageRgn) /* Region to accumulate damage in. */
{
MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin);
RgnHandle rgn = (RgnHandle) damageRgn;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ CGrafPtr destPort, savePort;
+ Boolean portChanged;
Rect srcRect, scrollRect;
- RgnHandle visRgn, clipRgn;
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
+ portChanged = QDSwapPort(destPort, &savePort);
TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
/*
* Due to the implementation below the behavior may be differnt
- * than X in certain cases that should never occur in Tk. The
+ * than X in certain cases that should never occur in Tk. The
* scrollRect is the source rect extended by the offset (the union
- * of the source rect and the offset rect). Everything
- * in the extended scrollRect is scrolled. On X, it's possible
+ * of the source rect and the offset rect). Everything
+ * in the extended scrollRect is scrolled. On X, it's possible
* to "skip" over an area if the offset makes the source and
* destination rects disjoint and non-aligned.
*/
@@ -1642,45 +1504,27 @@ TkScrollWindow(
* Adjust clip region so that we don't copy any windows
* that may overlap us.
*/
- visRgn = NewRgn();
- clipRgn = NewRgn();
+
+ TkMacOSXCheckTmpRgnEmpty(1);
+ TkMacOSXCheckTmpRgnEmpty(2);
RectRgn(rgn, &srcRect);
- GetPortVisibleRegion(destPort,visRgn);
- DiffRgn(rgn, visRgn, rgn);
+ GetPortVisibleRegion(destPort,tkMacOSXtmpRgn1);
+ DiffRgn(rgn, tkMacOSXtmpRgn1, rgn);
OffsetRgn(rgn, dx, dy);
- GetPortClipRegion(destPort, clipRgn);
- DiffRgn(clipRgn, rgn, clipRgn);
- SetPortClipRegion(destPort, clipRgn);
+ GetPortClipRegion(destPort, tkMacOSXtmpRgn2);
+ DiffRgn(tkMacOSXtmpRgn2, rgn, tkMacOSXtmpRgn2);
+ SetPortClipRegion(destPort, tkMacOSXtmpRgn2);
+ SetEmptyRgn(tkMacOSXtmpRgn1);
+ SetEmptyRgn(tkMacOSXtmpRgn2);
SetEmptyRgn(rgn);
- /*
- * When a menu is up, the Mac does not expect drawing to occur and
- * does not clip out the menu. We have to do it ourselves. This
- * is pretty gross.
- */
-
- if (tkUseMenuCascadeRgn == 1) {
- Point scratch = {0, 0};
- MacDrawable *macDraw = (MacDrawable *) Tk_WindowId(tkwin);
-
- LocalToGlobal(&scratch);
- CopyRgn(tkMenuCascadeRgn, rgn);
- OffsetRgn(rgn, -scratch.h, -scratch.v);
- DiffRgn(clipRgn, rgn, clipRgn);
- SetPortClipRegion(destPort, clipRgn);
- SetEmptyRgn(rgn);
- macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU;
- }
-
ScrollRect(&scrollRect, dx, dy, rgn);
-
- SetGWorld(saveWorld, saveDevice);
-
- DisposeRgn(clipRgn);
- DisposeRgn(visRgn);
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
+ }
/*
- * Fortunantly, the region returned by ScrollRect is symanticlly
- * the same as what we need to return in this function. If the
+ * Fortunately, the region returned by ScrollRect is semantically
+ * the same as what we need to return in this function. If the
* region is empty we return zero to denote that no damage was
* created.
*/
@@ -1696,220 +1540,300 @@ TkScrollWindow(
*
* TkMacOSXSetUpGraphicsPort --
*
- * Set up the graphics port from the given GC.
+ * Set up the graphics port from the given GC.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The current port is adjusted.
+ * The current port is adjusted.
*
*----------------------------------------------------------------------
*/
void
TkMacOSXSetUpGraphicsPort(
- GC gc,
- GWorldPtr destPort) /* GC to apply to current port. */
+ GC gc, /* GC to apply to current port. */
+ GWorldPtr destPort)
{
- RGBColor macColor;
-
- if (gPenPat == NULL) {
- gPenPat = NewPixPat();
- }
-
- if (TkSetMacColor(gc->foreground, &macColor) == true) {
- /* TODO: cache RGBPats for preformace - measure gains... */
- MakeRGBPat(gPenPat, &macColor);
- }
-
PenNormal();
- if(gc->function == GXxor) {
- PenMode(patXor);
- }
- if (gc->line_width > 1) {
- PenSize(gc->line_width, gc->line_width);
- }
- if (gc->line_style != LineSolid) {
- /*
- * Here the dash pattern should be set in the drawing,
- * environment, but I don't know how to do that for the Mac.
- *
- * p[] is an array of unsigned chars containing the dash list.
- * A '\0' indicates the end of this list.
- *
- * Someone knows how to implement this? If you have a more
- * complete implementation of SetUpGraphicsPort() for
- * the Mac (or for Windows), please let me know.
- *
- * Jan Nijtmans
- * CMG Arnhem, B.V.
- * email: j.nijtmans@chello.nl (private)
- * jan.nijtmans@cmg.nl (work)
- * url: http://purl.oclc.org/net/nijtmans/
- *
- * FIXME:
- * This is not possible with QuickDraw line drawing. As of
- * Tk 8.4.7 we have a complete set of drawing routines using
- * CG, so there is no reason to support this here.
- */
+ if (gc) {
+ if (gPenPat == NULL) {
+ gPenPat = NewPixPat();
+ }
+ TkMacOSXSetColorInPort(gc->foreground, 1, gPenPat);
+ PenPixPat(gPenPat);
+ if(gc->function == GXxor) {
+ PenMode(patXor);
+ }
+ if (gc->line_width > 1) {
+ PenSize(gc->line_width, gc->line_width);
+ }
+ if (gc->line_style != LineSolid) {
+ /*
+ * FIXME:
+ * Here the dash pattern should be set in the drawing environment.
+ * This is not possible with QuickDraw line drawing.
+ */
+ }
}
}
/*
*----------------------------------------------------------------------
*
- * TkMacOSXSetUpCGContext --
+ * TkMacOSXSetUpDrawingContext --
*
- * Set up a CGContext for the given graphics port.
+ * Set up a drawing context for the given drawable and GC.
*
* Results:
- * None.
+ * Boolean indicating whether to use CG drawing.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
-static void
-TkMacOSXSetUpCGContext(
- MacDrawable *macWin,
- CGrafPtr destPort,
- GC gc,
- CGContextRef *contextPtr)
+int
+TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG,
+ TkMacOSXDrawingContext *dc)
{
- RGBColor macColor;
- CGContextRef outContext;
- OSStatus err;
- Rect boundsRect;
- CGAffineTransform coordsTransform;
- static RgnHandle clipRgn = NULL;
- float w;
-
- err = QDBeginCGContext(destPort, contextPtr);
- outContext = *contextPtr;
-
- /*
- * Now clip the CG Context to the port. Note, we have already
- * set up the port with our clip region, so we can just get
- * the clip back out of there. If we use the macWin->clipRgn
- * directly at this point, we get some odd drawing effects.
- *
- * We also have to intersect our clip region with the port
- * visible region so we don't overwrite the window decoration.
- */
-
- if (!clipRgn) {
- clipRgn = NewRgn();
+ MacDrawable *macDraw = ((MacDrawable*)d);
+ CGContextRef context = macDraw->context;
+ CGrafPtr port;
+ Rect portBounds;
+
+ port = TkMacOSXGetDrawablePort(d);
+ if (port) {
+ GetPortBounds(port, &portBounds);
}
- GetPortBounds(destPort, &boundsRect);
-
- RectRgn(clipRgn, &boundsRect);
- SectRegionWithPortClipRegion(destPort, clipRgn);
- SectRegionWithPortVisibleRegion(destPort, clipRgn);
- ClipCGContextToRegion(outContext, &boundsRect, clipRgn);
- SetEmptyRgn(clipRgn);
+ dc->saveState = NULL;
+ if (port && !context) {
+ dc->portChanged = QDSwapPort(port, &(dc->savePort));
+ TkMacOSXSetUpClippingRgn(d);
+ TkMacOSXCheckTmpRgnEmpty(1);
+ if (useCG) {
+ if (ChkErr(QDBeginCGContext, port, &context) == noErr) {
+ /*
+ * Now clip the CG Context to the port. Note, we have already
+ * set up the port with our clip region, so we can just get
+ * the clip back out of there. If we use the macWin->clipRgn
+ * directly at this point, we get some odd drawing effects.
+ *
+ * We also have to intersect our clip region with the port
+ * visible region so we don't overwrite the window decoration.
+ */
+
+ RectRgn(tkMacOSXtmpRgn1, &portBounds);
+ SectRegionWithPortClipRegion(port, tkMacOSXtmpRgn1);
+ SectRegionWithPortVisibleRegion(port, tkMacOSXtmpRgn1);
+ if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type
+ == TKP_CLIP_REGION) {
+ RgnHandle clipRgn = (RgnHandle)
+ ((TkpClipMask*)gc->clip_mask)->value.region;
+ int xOffset = macDraw->xOff + gc->clip_x_origin;
+ int yOffset = macDraw->yOff + gc->clip_y_origin;
+
+ OffsetRgn(clipRgn, xOffset, yOffset);
+ SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1);
+ OffsetRgn(clipRgn, -xOffset, -yOffset);
+ }
+ ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpRgn1);
+ SetEmptyRgn(tkMacOSXtmpRgn1);
- /*
- * Note: You have to call SyncCGContextOriginWithPort
- * AFTER all the clip region manipulations.
- */
+ /*
+ * Note: You have to call SyncCGContextOriginWithPort
+ * AFTER all the clip region manipulations.
+ */
- SyncCGContextOriginWithPort(outContext, destPort);
-
- coordsTransform = CGAffineTransformMake(1, 0, 0, -1, 0,
- boundsRect.bottom - boundsRect.top);
- CGContextConcatCTM(outContext, coordsTransform);
-
- /* Now offset the CTM to the subwindow offset */
-
- if (TkSetMacColor(gc->foreground, &macColor) == true) {
- CGContextSetRGBFillColor(outContext,
- RGBFLOATRED(macColor),
- RGBFLOATGREEN(macColor),
- RGBFLOATBLUE(macColor),
- 1);
- CGContextSetRGBStrokeColor(outContext,
- RGBFLOATRED(macColor),
- RGBFLOATGREEN(macColor),
- RGBFLOATBLUE(macColor),
- 1);
- }
+ SyncCGContextOriginWithPort(context, port);
+ } else {
+ context = NULL;
+ useCG = 0;
+ }
+ }
+ } else if (context) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ if (!port
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030
+ && CGContextGetClipBoundingBox != NULL
+#endif
+ ) {
+ CGRect r = CGContextGetClipBoundingBox(context);
- if(gc->function == GXxor) {
- }
+ SetRect(&portBounds, r.origin.x + macDraw->xOff,
+ r.origin.y + macDraw->yOff,
+ r.origin.x + r.size.width + macDraw->xOff,
+ r.origin.y + r.size.height + macDraw->yOff);
+ }
+#endif
+ CGContextSaveGState(context);
+ TkMacOSXCheckTmpRgnEmpty(1);
+ RectRgn(tkMacOSXtmpRgn1, &portBounds);
+ if (port) {
+ TkMacOSXSetUpClippingRgn(d);
+ SectRegionWithPortClipRegion(port, tkMacOSXtmpRgn1);
+ SectRegionWithPortVisibleRegion(port, tkMacOSXtmpRgn1);
+ } else if (macDraw->flags & TK_CLIPPED_DRAW) {
+ OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff);
+ SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpRgn1);
+ OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff);
+ }
+ if (gc && gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type
+ == TKP_CLIP_REGION) {
+ RgnHandle clipRgn = (RgnHandle)
+ ((TkpClipMask*)gc->clip_mask)->value.region;
+ int xOffset = macDraw->xOff + gc->clip_x_origin;
+ int yOffset = macDraw->yOff + gc->clip_y_origin;
- w = gc->line_width;
- /* When should we antialias? */
- if (notAA(gc->line_width)) {
- /* Make non-antialiased CG drawing look more like X11 */
- w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
- CGContextSetShouldAntialias(outContext, 0);
- } else {
- CGContextSetShouldAntialias(outContext, 1);
+ OffsetRgn(clipRgn, xOffset, yOffset);
+ SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1);
+ OffsetRgn(clipRgn, -xOffset, -yOffset);
+ }
+ ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpRgn1);
+ SetEmptyRgn(tkMacOSXtmpRgn1);
+ port = NULL;
+ dc->portChanged = false;
+ dc->saveState = (void*)1;
+ useCG = 1;
}
- CGContextSetLineWidth(outContext, w);
+ if (useCG) {
+ CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, -1.0,
+ 0.0, portBounds.bottom - portBounds.top));
+ if (gc) {
+ double w = gc->line_width;
+
+ TkMacOSXSetColorInContext(gc->foreground, context);
+ if (port) {
+ CGContextSetPatternPhase(context, CGSizeMake(portBounds.right -
+ portBounds.left, portBounds.bottom - portBounds.top));
+ }
+ if(gc->function == GXxor) {
+ TkMacOSXDbgMsg("GXxor mode not supported for CG drawing!");
+ }
+ /* When should we antialias? */
+ if (notAA(gc->line_width)) {
+ /* Make non-antialiased CG drawing look more like X11 */
+ w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
+ CGContextSetShouldAntialias(context, 0);
+ } else {
+ CGContextSetShouldAntialias(context, 1);
+ }
+ CGContextSetLineWidth(context, w);
- if (gc->line_style != LineSolid) {
- int num = 0;
- char *p = &(gc->dashes);
- float dashOffset = gc->dash_offset;
- float lengths[10];
+ if (gc->line_style != LineSolid) {
+ int num = 0;
+ char *p = &(gc->dashes);
+ double dashOffset = gc->dash_offset;
+ float lengths[10];
- while (p[num] != '\0') {
- lengths[num] = p[num];
- num++;
- }
- CGContextSetLineDash(outContext, dashOffset, lengths, num);
- }
+ while (p[num] != '\0' && num < 10) {
+ lengths[num] = p[num];
+ num++;
+ }
+ CGContextSetLineDash(context, dashOffset, lengths, num);
+ }
- if (gc->cap_style == CapButt) {
- /*
- * What about CapNotLast, CapProjecting?
- */
+ if (gc->cap_style == CapButt) {
+ /*
+ * What about CapNotLast, CapProjecting?
+ */
- CGContextSetLineCap(outContext, kCGLineCapButt);
- } else if (gc->cap_style == CapRound) {
- CGContextSetLineCap(outContext, kCGLineCapRound);
- } else if (gc->cap_style == CapProjecting) {
- CGContextSetLineCap(outContext, kCGLineCapSquare);
- }
+ CGContextSetLineCap(context, kCGLineCapButt);
+ } else if (gc->cap_style == CapRound) {
+ CGContextSetLineCap(context, kCGLineCapRound);
+ } else if (gc->cap_style == CapProjecting) {
+ CGContextSetLineCap(context, kCGLineCapSquare);
+ }
- if (gc->join_style == JoinMiter) {
- CGContextSetLineJoin(outContext, kCGLineJoinMiter);
- } else if (gc->join_style == JoinRound) {
- CGContextSetLineJoin(outContext, kCGLineJoinRound);
- } else if (gc->join_style == JoinBevel) {
- CGContextSetLineJoin(outContext, kCGLineJoinBevel);
+ if (gc->join_style == JoinMiter) {
+ CGContextSetLineJoin(context, kCGLineJoinMiter);
+ } else if (gc->join_style == JoinRound) {
+ CGContextSetLineJoin(context, kCGLineJoinRound);
+ } else if (gc->join_style == JoinBevel) {
+ CGContextSetLineJoin(context, kCGLineJoinBevel);
+ }
+ }
+ } else {
+ ChkErr(GetThemeDrawingState, &(dc->saveState));
+ if (gc) {
+ PixPatHandle savePat = gPenPat;
+
+ gPenPat = NULL;
+ TkMacOSXSetUpGraphicsPort(gc, port);
+ dc->penPat = gPenPat;
+ gPenPat = savePat;
+ if (gc->clip_mask && ((TkpClipMask*)gc->clip_mask)->type
+ == TKP_CLIP_REGION) {
+ RgnHandle clipRgn = (RgnHandle)
+ ((TkpClipMask*)gc->clip_mask)->value.region;
+ int xOffset = macDraw->xOff + gc->clip_x_origin;
+ int yOffset = macDraw->yOff + gc->clip_y_origin;
+
+ OffsetRgn(clipRgn, xOffset, yOffset);
+ GetClip(tkMacOSXtmpRgn1);
+ SectRgn(clipRgn, tkMacOSXtmpRgn1, tkMacOSXtmpRgn1);
+ SetClip(tkMacOSXtmpRgn1);
+ SetEmptyRgn(tkMacOSXtmpRgn1);
+ OffsetRgn(clipRgn, -xOffset, -yOffset);
+ }
+ } else {
+ TkMacOSXSetUpGraphicsPort(NULL, port);
+ dc->penPat = NULL;
+ }
+ ShowPen();
}
+ dc->port = port;
+ dc->portBounds = portBounds;
+ dc->context = context;
+ return useCG;
}
/*
*----------------------------------------------------------------------
*
- * TkMacOSXReleaseCGContext --
+ * TkMacOSXRestoreDrawingContext --
*
- * Release the CGContext for the given graphics port.
+ * Restore drawing context.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
-static void
-TkMacOSXReleaseCGContext(
- MacDrawable *macWin,
- CGrafPtr destPort,
- CGContextRef *outContext)
+void
+TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc)
{
- CGContextSynchronize(*outContext);
- QDEndCGContext(destPort, outContext);
+ if (dc->context) {
+ CGContextSynchronize(dc->context);
+ if (dc->saveState) {
+ CGContextRestoreGState(dc->context);
+ }
+ if (dc->port) {
+ ChkErr(QDEndCGContext, dc->port, &(dc->context));
+ }
+ } else {
+ HidePen();
+ PenNormal();
+ if (dc->penPat) {
+ DisposePixPat(dc->penPat);
+ }
+ if (dc->saveState) {
+ ChkErr(SetThemeDrawingState, dc->saveState, true);
+ }
+ }
+ if (dc->portChanged) {
+ QDSwapPort(dc->savePort, NULL);
+ }
+#ifdef TK_MAC_DEBUG
+ bzero(dc, sizeof(dc));
+#endif /* TK_MAC_DEBUG */
}
/*
@@ -1917,21 +1841,21 @@ TkMacOSXReleaseCGContext(
*
* TkMacOSXSetUpClippingRgn --
*
- * Set up the clipping region so that drawing only occurs on the
- * specified X subwindow.
+ * Set up the clipping region so that drawing only occurs on the
+ * specified X subwindow.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The clipping region in the current port is changed.
+ * The clipping region in the current port is changed.
*
*----------------------------------------------------------------------
*/
void
TkMacOSXSetUpClippingRgn(
- Drawable drawable) /* Drawable to update. */
+ Drawable drawable) /* Drawable to update. */
{
MacDrawable *macDraw = (MacDrawable *) drawable;
@@ -1940,43 +1864,72 @@ TkMacOSXSetUpClippingRgn(
TkMacOSXUpdateClipRgn(macDraw->winPtr);
}
-#if defined(TK_MAC_DEBUG) && defined(TK_MAC_DEBUG_DRAWING)
+#ifdef TK_MAC_DEBUG_DRAWING
TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion,
- CGrafPtr port, RgnHandle region);
+ CGrafPtr port, RgnHandle region);
if (QDDebugFlashRegion) {
CGrafPtr grafPtr = TkMacOSXGetDrawablePort(drawable);
- /* Carbon-internal region flashing SPI (c.f. Technote 2124) */
+
+ /*
+ * Carbon-internal region flashing SPI (c.f. Technote 2124)
+ */
+
QDDebugFlashRegion(grafPtr, macDraw->clipRgn);
}
#endif /* TK_MAC_DEBUG_DRAWING */
+ }
- /*
- * When a menu is up, the Mac does not expect drawing to occur and
- * does not clip out the menu. We have to do it ourselves. This
- * is pretty gross.
- */
+ if (macDraw->clipRgn != NULL) {
+ if (macDraw->flags & TK_CLIPPED_DRAW) {
+ TkMacOSXCheckTmpRgnEmpty(1);
+ OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff);
+ SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpRgn1);
+ OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff);
+ SetClip(tkMacOSXtmpRgn1);
+ SetEmptyRgn(tkMacOSXtmpRgn1);
+ } else {
+ SetClip(macDraw->clipRgn);
+ }
+ } else if (macDraw->flags & TK_CLIPPED_DRAW) {
+ OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff);
+ SetClip(macDraw->drawRgn);
+ OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpClipDrawableToRect --
+ *
+ * Clip all drawing into the drawable d to the given rectangle.
+ * If width and height are negative, reset to no clipping.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Subsequent drawing into d is offset and clipped as specified.
+ *
+ *----------------------------------------------------------------------
+ */
- if (macDraw->clipRgn != NULL) {
- if (tkUseMenuCascadeRgn == 1) {
- Point scratch = {0, 0};
- GDHandle saveDevice;
- GWorldPtr saveWorld;
-
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(TkMacOSXGetDrawablePort(drawable), NULL);
- LocalToGlobal(&scratch);
- SetGWorld(saveWorld, saveDevice);
- if (tmpRgn == NULL) {
- tmpRgn = NewRgn();
- }
- CopyRgn(tkMenuCascadeRgn, tmpRgn);
- OffsetRgn(tmpRgn, -scratch.h, -scratch.v);
- DiffRgn(macDraw->clipRgn, tmpRgn, tmpRgn);
- SetClip(tmpRgn);
- macDraw->toplevel->flags |= TK_DRAWN_UNDER_MENU;
- } else {
- SetClip(macDraw->clipRgn);
- }
+void
+TkpClipDrawableToRect(
+ Display *display,
+ Drawable d,
+ int x, int y,
+ int width, int height)
+{
+ MacDrawable *macDraw = (MacDrawable *) d;
+
+ if (macDraw->drawRgn) {
+ if (width < 0 && height < 0) {
+ SetEmptyRgn(macDraw->drawRgn);
+ macDraw->flags &= ~TK_CLIPPED_DRAW;
+ } else {
+ SetRectRgn(macDraw->drawRgn, x, y, x + width, y + height);
+ macDraw->flags |= TK_CLIPPED_DRAW;
}
}
}
@@ -1986,48 +1939,45 @@ TkMacOSXSetUpClippingRgn(
*
* TkMacOSXMakeStippleMap --
*
- * Given a drawable and a stipple pattern this function draws the
- * pattern repeatedly over the drawable. The drawable can then
- * be used as a mask for bit-bliting a stipple pattern over an
- * object.
+ * Given a drawable and a stipple pattern this function draws the
+ * pattern repeatedly over the drawable. The drawable can then
+ * be used as a mask for bit-bliting a stipple pattern over an
+ * object.
*
* Results:
- * A BitMap data structure.
+ * A BitMap data structure.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
BitMapPtr
TkMacOSXMakeStippleMap(
- Drawable drawable, /* Window to apply stipple. */
- Drawable stipple) /* The stipple pattern. */
+ Drawable drawable, /* Window to apply stipple. */
+ Drawable stipple) /* The stipple pattern. */
{
- GWorldPtr destPort;
+ CGrafPtr stipplePort;
BitMapPtr bitmapPtr;
- Rect portRect;
- int width, height, stippleHeight, stippleWidth;
- int i, j;
- char * data;
+ const BitMap *stippleBitmap;
+ Rect portRect;
+ int width, height, stippleHeight, stippleWidth, i, j;
Rect bounds;
- destPort = TkMacOSXGetDrawablePort(drawable);
-
- GetPortBounds (destPort, &portRect);
+ GetPortBounds(TkMacOSXGetDrawablePort(drawable), &portRect);
width = portRect.right - portRect.left;
height = portRect.bottom - portRect.top;
-
bitmapPtr = (BitMap *) ckalloc(sizeof(BitMap));
- data = (char *) ckalloc(height * ((width / 8) + 1));
bitmapPtr->bounds.top = bitmapPtr->bounds.left = 0;
bitmapPtr->bounds.right = (short) width;
bitmapPtr->bounds.bottom = (short) height;
- bitmapPtr->baseAddr = data;
bitmapPtr->rowBytes = (width / 8) + 1;
+ bitmapPtr->baseAddr = ckalloc(height * bitmapPtr->rowBytes);
- destPort = TkMacOSXGetDrawablePort(stipple);
+ stipplePort = TkMacOSXGetDrawablePort(stipple);
+ stippleBitmap = GetPortBitMapForCopyBits(stipplePort);
+ GetPortBounds(stipplePort, &portRect);
stippleWidth = portRect.right - portRect.left;
stippleHeight = portRect.bottom - portRect.top;
@@ -2037,9 +1987,8 @@ TkMacOSXMakeStippleMap(
bounds.top = i;
bounds.right = j + stippleWidth;
bounds.bottom = i + stippleHeight;
-
- CopyBits(GetPortBitMapForCopyBits(destPort), bitmapPtr,
- &portRect, &bounds, srcCopy, NULL);
+ CopyBits(stippleBitmap, bitmapPtr, &portRect, &bounds, srcCopy,
+ NULL);
}
}
return bitmapPtr;
@@ -2050,20 +1999,20 @@ TkMacOSXMakeStippleMap(
*
* InvertByte --
*
- * This function reverses the bits in the passed in Byte of data.
+ * This function reverses the bits in the passed in Byte of data.
*
* Results:
- * The incoming byte in reverse bit order.
+ * The incoming byte in reverse bit order.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
static unsigned char
InvertByte(
- unsigned char data) /* Byte of data. */
+ unsigned char data) /* Byte of data. */
{
unsigned char i;
unsigned char mask = 1, result = 0;
@@ -2082,32 +2031,32 @@ InvertByte(
*
* TkpDrawHighlightBorder --
*
- * This procedure draws a rectangular ring around the outside of
- * a widget to indicate that it has received the input focus.
+ * This procedure draws a rectangular ring around the outside of
+ * a widget to indicate that it has received the input focus.
*
- * On the Macintosh, this puts a 1 pixel border in the bgGC color
- * between the widget and the focus ring, except in the case where
- * highlightWidth is 1, in which case the border is left out.
+ * On the Macintosh, this puts a 1 pixel border in the bgGC color
+ * between the widget and the focus ring, except in the case where
+ * highlightWidth is 1, in which case the border is left out.
*
- * For proper Mac L&F, use highlightWidth of 3.
+ * For proper Mac L&F, use highlightWidth of 3.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * A rectangle "width" pixels wide is drawn in "drawable",
- * corresponding to the outer area of "tkwin".
+ * A rectangle "width" pixels wide is drawn in "drawable",
+ * corresponding to the outer area of "tkwin".
*
*----------------------------------------------------------------------
*/
void
TkpDrawHighlightBorder (
- Tk_Window tkwin,
- GC fgGC,
- GC bgGC,
- int highlightWidth,
- Drawable drawable)
+ Tk_Window tkwin,
+ GC fgGC,
+ GC bgGC,
+ int highlightWidth,
+ Drawable drawable)
{
if (highlightWidth == 1) {
TkDrawInsetFocusHighlight (tkwin, fgGC, highlightWidth, drawable, 0);
@@ -2125,7 +2074,7 @@ TkpDrawHighlightBorder (
*
* TkpDrawFrame --
*
- * This procedure draws the rectangular frame area. If the user
+ * This procedure draws the rectangular frame area. If the user
* has request themeing, it draws with a the background theme.
*
* Results:
@@ -2138,52 +2087,27 @@ TkpDrawHighlightBorder (
*/
void
-TkpDrawFrame (Tk_Window tkwin, Tk_3DBorder border,
- int highlightWidth, int borderWidth, int relief)
+TkpDrawFrame(
+ Tk_Window tkwin,
+ Tk_3DBorder border,
+ int highlightWidth,
+ int borderWidth,
+ int relief)
{
if (useThemedToplevel && Tk_IsTopLevel(tkwin)) {
- /*
- * Currently only support themed toplevels, until we can better
- * factor this to handle individual windows (blanket theming of
- * frames will work for very few UIs).
- */
- Rect bounds;
- Point origin;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- XGCValues gcValues;
- GC gc;
- Pixmap pixmap;
- Display *display = Tk_Display(tkwin);
-
- pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin),
- Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
-
- gc = Tk_GetGC(tkwin, 0, &gcValues);
- TkMacOSXWinBounds((TkWindow *) tkwin, &bounds);
- origin.v = -bounds.top;
- origin.h = -bounds.left;
- bounds.top = bounds.left = 0;
- bounds.right = Tk_Width(tkwin);
- bounds.bottom = Tk_Height(tkwin);
-
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(TkMacOSXGetDrawablePort(pixmap), 0);
- ApplyThemeBackground(kThemeBackgroundWindowHeader, &bounds,
- kThemeStateActive, 32 /* depth */, true /* inColor */);
- QDSetPatternOrigin(origin);
- EraseRect(&bounds);
- SetGWorld(saveWorld, saveDevice);
-
- XCopyArea(display, pixmap, Tk_WindowId(tkwin),
- gc, 0, 0, bounds.right, bounds.bottom, 0, 0);
- Tk_FreePixmap(display, pixmap);
- Tk_FreeGC(display, gc);
- } else {
- Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
- border, highlightWidth, highlightWidth,
- Tk_Width(tkwin) - 2 * highlightWidth,
- Tk_Height(tkwin) - 2 * highlightWidth,
- borderWidth, relief);
+ static Tk_3DBorder themedBorder = NULL;
+
+ if (!themedBorder) {
+ themedBorder = Tk_Get3DBorder(NULL, tkwin,
+ "systemWindowHeaderBackground");
+ }
+ if (themedBorder) {
+ border = themedBorder;
+ }
}
+ Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
+ border, highlightWidth, highlightWidth,
+ Tk_Width(tkwin) - 2 * highlightWidth,
+ Tk_Height(tkwin) - 2 * highlightWidth,
+ borderWidth, relief);
}