summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXDraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r--macosx/tkMacOSXDraw.c660
1 files changed, 396 insertions, 264 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 8960567..5d1157c 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.29 2007/07/09 08:30:31 das Exp $
+ * RCS: @(#) $Id: tkMacOSXDraw.c,v 1.2.2.30 2007/11/09 06:26:55 das Exp $
*/
#include "tkMacOSXPrivate.h"
@@ -43,6 +43,8 @@ RgnHandle tkMacOSXtmpQdRgn = NULL;
int tkMacOSXUseCGDrawing = 1;
+int tkPictureIsOpen;
+
static PixPatHandle penPat = NULL;
static int cgAntiAliasLimit = 0;
@@ -55,7 +57,7 @@ static int useThemedFrame = 0;
* Prototypes for functions used only in this file.
*/
-static void ClipToGC(Drawable d, GC gc, CGrafPtr port, RgnHandle clipRgn);
+static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr);
static void NoQDClip(CGrafPtr port);
@@ -153,7 +155,7 @@ XCopyArea(
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 width, /* that will be copied. */
unsigned int height,
int dest_x, /* Dest X & Y on dest rect. */
int dest_y)
@@ -163,32 +165,50 @@ XCopyArea(
display->request++;
if (!width || !height) {
- TkMacOSXDbgMsg("Drawing of emtpy area requested");
+ /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */
return;
}
- if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) {
- Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect;
+ {
CGrafPtr srcPort;
- const BitMap *srcBit, *dstBit;
- RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff};
srcPort = TkMacOSXGetDrawablePort(src);
- srcBit = GetPortBitMapForCopyBits(srcPort);
- dstBit = GetPortBitMapForCopyBits(dc.port);
- SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y,
- srcDraw->xOff + src_x + width, srcDraw->yOff + src_y + height);
- if (tkPictureIsOpen) {
- dstPtr = srcPtr;
+ if (srcPort) {
+ Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect;
+ const BitMap *srcBit, *dstBit;
+ RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff};
+
+ if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) {
+ return;
+ }
+ if (dc.context) {
+ TkMacOSXDbgMsg("Ignored CG drawing of QD drawable");
+ goto end;
+ }
+ if (!dc.port) {
+ TkMacOSXDbgMsg("Invalid destination drawable");
+ goto end;
+ }
+ srcBit = GetPortBitMapForCopyBits(srcPort);
+ dstBit = GetPortBitMapForCopyBits(dc.port);
+ SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y,
+ srcDraw->xOff + src_x + width,
+ srcDraw->yOff + src_y + height);
+ if (tkPictureIsOpen) {
+ dstPtr = srcPtr;
+ } else {
+ SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y,
+ dstDraw->xOff + dest_x + width,
+ dstDraw->yOff + dest_y + height);
+ }
+ RGBForeColor(&black);
+ RGBBackColor(&white);
+ CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL);
+end:
+ TkMacOSXRestoreDrawingContext(&dc);
} else {
- SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y,
- dstDraw->xOff + dest_x + width,
- dstDraw->yOff + dest_y + height);
+ TkMacOSXDbgMsg("Invalid source drawable");
}
- RGBForeColor(&black);
- RGBBackColor(&white);
- CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL);
}
- TkMacOSXRestoreDrawingContext(&dc);
}
/*
@@ -218,7 +238,7 @@ XCopyPlane(
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 width, /* that will be copied. */
unsigned int height,
int dest_x, /* Dest X & Y on dest rect. */
int dest_y,
@@ -229,61 +249,80 @@ XCopyPlane(
display->request++;
if (!width || !height) {
- TkMacOSXDbgMsg("Drawing of emtpy area requested");
+ /* TkMacOSXDbgMsg("Drawing of emtpy area requested"); */
return;
}
if (plane != 1) {
Tcl_Panic("Unexpected plane specified for XCopyPlane");
}
- if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) {
- Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect;
+ {
CGrafPtr srcPort;
- const BitMap *srcBit, *dstBit;
- TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
srcPort = TkMacOSXGetDrawablePort(src);
- srcBit = GetPortBitMapForCopyBits(srcPort);
- dstBit = GetPortBitMapForCopyBits(dc.port);
- SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y,
- srcDraw->xOff + src_x + width, srcDraw->yOff + src_y + height);
- if (tkPictureIsOpen) {
- dstPtr = srcPtr;
- } else {
- SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y,
- dstDraw->xOff + dest_x + width,
- dstDraw->yOff + dest_y + height);
- }
- TkMacOSXSetColorInPort(gc->foreground, 1, NULL, dc.port);
- if (!clipPtr || clipPtr->type == TKP_CLIP_REGION) {
- /*
- * Opaque bitmaps.
- */
+ if (srcPort) {
+ Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect;
+ const BitMap *srcBit, *dstBit;
+ TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
- TkMacOSXSetColorInPort(gc->background, 0, NULL, dc.port);
- CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL);
- } else if (clipPtr->type == TKP_CLIP_PIXMAP) {
- if (clipPtr->value.pixmap == src) {
- /*
- * Transparent bitmaps. If it's color we ignore the forecolor.
- */
- short tmode = GetPixDepth(GetPortPixMap(srcPort)) == 1 ?
- srcOr : transparent;
-
- CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
+ if (!TkMacOSXSetupDrawingContext(dst, gc, 0, &dc)) {
+ return;
+ }
+ if (dc.context) {
+ TkMacOSXDbgMsg("Ignored CG drawing of QD drawable");
+ goto end;
+ }
+ if (!dc.port) {
+ TkMacOSXDbgMsg("Invalid destination drawable");
+ goto end;
+ }
+ srcBit = GetPortBitMapForCopyBits(srcPort);
+ dstBit = GetPortBitMapForCopyBits(dc.port);
+ SetRect(srcPtr, srcDraw->xOff + src_x, srcDraw->yOff + src_y,
+ srcDraw->xOff + src_x + width,
+ srcDraw->yOff + src_y + height);
+ if (tkPictureIsOpen) {
+ dstPtr = srcPtr;
} else {
+ SetRect(dstPtr, dstDraw->xOff + dest_x, dstDraw->yOff + dest_y,
+ dstDraw->xOff + dest_x + width,
+ dstDraw->yOff + dest_y + height);
+ }
+ TkMacOSXSetColorInPort(gc->foreground, 1, NULL, dc.port);
+ if (!clipPtr || clipPtr->type == TKP_CLIP_REGION) {
/*
- * Two arbitrary bitmaps.
+ * Opaque bitmaps.
*/
- CGrafPtr mskPort = TkMacOSXGetDrawablePort(clipPtr->value.pixmap);
- const BitMap *mskBit = GetPortBitMapForCopyBits(mskPort);
+ TkMacOSXSetColorInPort(gc->background, 0, NULL, dc.port);
+ CopyBits(srcBit, dstBit, srcPtr, dstPtr, srcCopy, NULL);
+ } else if (clipPtr->type == TKP_CLIP_PIXMAP) {
+ if (clipPtr->value.pixmap == src) {
+ /*
+ * Transparent bitmaps. If it's color ignore the forecolor.
+ */
+ short tmode = GetPixDepth(GetPortPixMap(srcPort)) == 1 ?
+ srcOr : transparent;
+
+ CopyBits(srcBit, dstBit, srcPtr, dstPtr, tmode, NULL);
+ } else {
+ /*
+ * Two arbitrary bitmaps.
+ */
+
+ CGrafPtr mskPort = TkMacOSXGetDrawablePort(
+ clipPtr->value.pixmap);
+ const BitMap *mskBit = GetPortBitMapForCopyBits(mskPort);
- CopyDeepMask(srcBit, mskBit, dstBit, srcPtr, srcPtr, dstPtr,
- srcCopy, NULL);
+ CopyDeepMask(srcBit, mskBit, dstBit, srcPtr, srcPtr,
+ dstPtr, srcCopy, NULL);
+ }
}
+end:
+ TkMacOSXRestoreDrawingContext(&dc);
+ } else {
+ TkMacOSXDbgMsg("Invalid source drawable");
}
}
- TkMacOSXRestoreDrawingContext(&dc);
}
/*
@@ -323,14 +362,19 @@ TkPutImage(
display->request++;
if (!TkMacOSXSetupDrawingContext(d, gc, 0, &dc)) {
+ return;
+ }
+ if (dc.context) {
+ TkMacOSXDbgMsg("Ignored CG drawing of XImage");
+ } else {
Rect srcRect, dstRect, *srcPtr = &srcRect, *dstPtr = &dstRect;
const BitMap *dstBit;
RGBColor black = {0, 0, 0}, white = {0xffff, 0xffff, 0xffff};
int i, j;
char *newData = NULL;
char *dataPtr, *newPtr, *oldPtr;
- int rowBytes = image->bytes_per_line;
- int slices, sliceRowBytes, lastSliceRowBytes, sliceWidth, lastSliceWidth;
+ int rowBytes = image->bytes_per_line, sliceRowBytes, lastSliceRowBytes;
+ int slices, sliceWidth, lastSliceWidth;
dstBit = GetPortBitMapForCopyBits(dc.port);
SetRect(srcPtr, src_x, src_y, src_x + width, src_y + height);
@@ -348,8 +392,9 @@ TkPutImage(
* Image from XGetImage, copy from containing GWorld directly.
*/
- CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort((Drawable)
- image->obdata)), dstBit, srcPtr, dstPtr, srcCopy, NULL);
+ CopyBits(GetPortBitMapForCopyBits(TkMacOSXGetDrawablePort(
+ (Drawable)image->obdata)), dstBit,
+ srcPtr, dstPtr, srcCopy, NULL);
} else if (image->depth == 1) {
/*
* BW image
@@ -529,7 +574,10 @@ XDrawLines(
}
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
double prevx, prevy;
double o = (lw % 2) ? .5 : 0;
@@ -599,7 +647,10 @@ XDrawSegments(
int i, lw = gc->line_width;
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
double o = (lw % 2) ? .5 : 0;
for (i = 0; i < nsegments; i++) {
@@ -660,7 +711,10 @@ XFillPolygon(
int i;
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
double prevx, prevy;
double o = (gc->line_width % 2) ? .5 : 0;
@@ -735,7 +789,10 @@ XDrawRectangle(
}
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
double o = (lw % 2) ? .5 : 0;
@@ -798,7 +855,10 @@ XDrawRectangles(
int i, lw = gc->line_width;
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
double o = (lw % 2) ? .5 : 0;
@@ -858,7 +918,10 @@ XFillRectangles(
int i;
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
@@ -921,7 +984,10 @@ XDrawArc(
}
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
double o = (lw % 2) ? .5 : 0;
@@ -1003,7 +1069,10 @@ XDrawArcs(
int i, lw = gc->line_width;
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
double o = (lw % 2) ? .5 : 0;
@@ -1096,7 +1165,10 @@ XFillArc(
}
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
double o = (lw % 2) ? .5 : 0, u = 0;
@@ -1210,7 +1282,10 @@ XFillArcs(
int i, lw = gc->line_width;
display->request++;
- if (TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ if (!TkMacOSXSetupDrawingContext(d, gc, tkMacOSXUseCGDrawing, &dc)) {
+ return;
+ }
+ if (dc.context) {
CGRect rect;
double o = (lw % 2) ? .5 : 0, u = 0;
@@ -1356,7 +1431,7 @@ TkScrollWindow(
Boolean portChanged;
Rect scrollRect;
int result;
- RgnHandle rgn = (RgnHandle) damageRgn;
+ HIShapeRef dmgRgn;
/*
* Due to the implementation below the behavior may be differnt
@@ -1385,8 +1460,9 @@ TkScrollWindow(
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
+ TkMacOSXCheckTmpQdRgnEmpty();
portChanged = QDSwapPort(destPort, &savePort);
- ScrollRect(&scrollRect, dx, dy, rgn);
+ ScrollRect(&scrollRect, dx, dy, tkMacOSXtmpQdRgn);
if (portChanged) {
QDSwapPort(savePort, NULL);
}
@@ -1398,7 +1474,11 @@ TkScrollWindow(
* created.
*/
- result = EmptyRgn(rgn) ? 0 : 1;
+ dmgRgn = HIShapeCreateWithQDRgn(tkMacOSXtmpQdRgn);
+ SetEmptyRgn(tkMacOSXtmpQdRgn);
+ TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
+ result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;
+ CFRelease(dmgRgn);
return result;
}
@@ -1456,7 +1536,9 @@ TkMacOSXSetUpGraphicsPort(
* Set up a drawing context for the given drawable and GC.
*
* Results:
- * Boolean indicating whether to use CG drawing.
+ * Boolean indicating whether it is ok to draw; if false, drawing
+ * context was not setup, so do not attempt to draw and do not call
+ * TkMacOSXRestoreDrawingContext().
*
* Side effects:
* None.
@@ -1469,149 +1551,160 @@ TkMacOSXSetupDrawingContext(
Drawable d,
GC gc,
int useCG, /* advisory only ! */
- TkMacOSXDrawingContext *dc)
+ TkMacOSXDrawingContext *dcPtr)
{
MacDrawable *macDraw = ((MacDrawable*)d);
- CGContextRef context = macDraw->context;
- CGrafPtr port;
- Rect portBounds;
-
- dc->saveState = NULL;
- dc->saveClip = NULL;
- dc->penPat = NULL;
- dc->portChanged = false;
- port = TkMacOSXGetDrawablePort(d);
- if (port) {
- GetPortBounds(port, &portBounds);
- dc->saveClip = NewRgn();
- GetPortClipRegion(port, dc->saveClip);
- if (tkPictureIsOpen) {
- NoQDClip(port);
- } else {
- TkMacOSXSetUpClippingRgn(d);
+ int dontDraw = 0;
+ TkMacOSXDrawingContext dc = {NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ {SHRT_MIN, SHRT_MIN, SHRT_MAX, SHRT_MAX}, false};
+
+ if (tkPictureIsOpen) {
+ if (useCG) {
+ TkMacOSXDbgMsg("Ignored CG Drawing with QD Picture open");
+ dontDraw = 1;
}
+ } else {
+ dc.clipRgn = TkMacOSXGetClipRgn(d);
}
- if (context && useCG) {
- if (!port) {
- TK_IF_MAC_OS_X_API (3, CGContextGetClipBoundingBox,
- CGRect r = CGContextGetClipBoundingBox(context);
+ if (!dontDraw) {
+ ClipToGC(d, gc, &dc.clipRgn);
+ dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0;
+ }
+ if (dontDraw) {
+ if (dc.clipRgn) {
+ CFRelease(dc.clipRgn);
+ dc.clipRgn = NULL;
+ }
+ goto end;
+ }
+ if (useCG) {
+ dc.context = macDraw->context;;
+ }
+ if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
+ dc.port = TkMacOSXGetDrawablePort(d);
+ if (dc.port) {
+ GetPortBounds(dc.port, &dc.portBounds);
+ }
+ }
+ if (dc.context) {
+ if (!dc.port) {
+ CGRect r;
- 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);
+ TK_IF_MAC_OS_X_API (3, CGContextGetClipBoundingBox,
+ r = CGContextGetClipBoundingBox(dc.context);
+ ) TK_ELSE_MAC_OS_X (3,
+ r.origin = CGPointZero;
+ r.size = macDraw->size;
) TK_ENDIF
+ SetRect(&dc.portBounds, r.origin.x + macDraw->xOff,
+ r.origin.y + macDraw->yOff,
+ r.origin.x + r.size.width + macDraw->xOff,
+ r.origin.y + r.size.height + macDraw->yOff);
}
- CGContextSaveGState(context);
- dc->saveState = (void*)1;
- port = NULL;
- } else if (port) {
- dc->portChanged = QDSwapPort(port, &(dc->savePort));
- if (useCG && ChkErr(QDBeginCGContext, port, &context) == noErr) {
- SyncCGContextOriginWithPort(context, port);
+ CGContextSaveGState(dc.context);
+ dc.saveState = (void*)1;
+ dc.port = NULL;
+ } else if (dc.port) {
+ dc.portChanged = QDSwapPort(dc.port, &dc.savePort);
+ if (useCG && ChkErr(QDBeginCGContext, dc.port, &dc.context) == noErr) {
+ SyncCGContextOriginWithPort(dc.context, dc.port);
} else {
- context = NULL;
- useCG = 0;
+ dc.context = NULL;
}
} else {
Tcl_Panic("TkMacOSXSetupDrawingContext(): "
"no port or context to draw into !");
}
- if (useCG) {
- if (tkPictureIsOpen) {
- TkMacOSXDbgMsg("Ignored CG Drawing with QD Picture open");
- } else if (context) {
- TkMacOSXCheckTmpQdRgnEmpty();
- RectRgn(tkMacOSXtmpQdRgn, &portBounds);
- if (port) {
- SectRegionWithPortClipRegion(port, tkMacOSXtmpQdRgn);
- SectRegionWithPortVisibleRegion(port, tkMacOSXtmpQdRgn);
- } else if (macDraw->flags & TK_CLIPPED_DRAW) {
- OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff);
- SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpQdRgn);
- OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff);
+ if (dc.context) {
+ CGContextConcatCTM(dc.context, CGAffineTransformMake(1.0, 0.0, 0.0,
+ -1.0, 0.0, dc.portBounds.bottom - dc.portBounds.top));
+ if (dc.clipRgn) {
+#ifdef TK_MAC_DEBUG_DRAWING
+ CGContextSaveGState(dc.context);
+ ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
+ CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.2);
+ CGContextEOFillPath(dc.context);
+ CGContextRestoreGState(dc.context);
+#endif /* TK_MAC_DEBUG_DRAWING */
+ ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
+ CGContextEOClip(dc.context);
+ }
+ if (gc) {
+ static const CGLineCap cgCap[] = {
+ [CapNotLast] = kCGLineCapButt,
+ [CapButt] = kCGLineCapButt,
+ [CapRound] = kCGLineCapRound,
+ [CapProjecting] = kCGLineCapSquare,
+ };
+ static const CGLineJoin cgJoin[] = {
+ [JoinMiter] = kCGLineJoinMiter,
+ [JoinRound] = kCGLineJoinRound,
+ [JoinBevel] = kCGLineJoinBevel,
+ };
+ bool shouldAntialias;
+ double w = gc->line_width;
+
+ TkMacOSXSetColorInContext(gc->foreground, dc.context);
+ if (dc.port) {
+ CGContextSetPatternPhase(dc.context, CGSizeMake(
+ dc.portBounds.right - dc.portBounds.left,
+ dc.portBounds.bottom - dc.portBounds.top));
}
- ClipToGC(d, gc, NULL, tkMacOSXtmpQdRgn);
- ClipCGContextToRegion(context, &portBounds, tkMacOSXtmpQdRgn);
- SetEmptyRgn(tkMacOSXtmpQdRgn);
- 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 != GXcopy) {
- TkMacOSXDbgMsg("Logical functions other than GXcopy are "
- "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);
- double dashOffset = gc->dash_offset;
- float lengths[10];
-
- 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?
- */
-
- 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(context, kCGLineJoinMiter);
- } else if (gc->join_style == JoinRound) {
- CGContextSetLineJoin(context, kCGLineJoinRound);
- } else if (gc->join_style == JoinBevel) {
- CGContextSetLineJoin(context, kCGLineJoinBevel);
+ if(gc->function != GXcopy) {
+ TkMacOSXDbgMsg("Logical functions other than GXcopy are "
+ "not supported for CG drawing!");
+ }
+ /* When should we antialias? */
+ shouldAntialias = !notAA(gc->line_width);
+ if (!shouldAntialias) {
+ /* Make non-antialiased CG drawing look more like X11 */
+ w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
+ }
+ CGContextSetShouldAntialias(dc.context, shouldAntialias);
+ CGContextSetLineWidth(dc.context, w);
+ if (gc->line_style != LineSolid) {
+ int num = 0;
+ char *p = &(gc->dashes);
+ double dashOffset = gc->dash_offset;
+ float lengths[10];
+
+ while (p[num] != '\0' && num < 10) {
+ lengths[num] = p[num];
+ num++;
}
+ CGContextSetLineDash(dc.context, dashOffset, lengths, num);
}
- }
- } else {
- if (port) {
- PixPatHandle savePat = penPat;
-
- ChkErr(GetThemeDrawingState, &(dc->saveState));
- penPat = NULL;
- TkMacOSXSetUpGraphicsPort(gc, port);
- dc->penPat = penPat;
- penPat = savePat;
- if (gc) {
- TkMacOSXCheckTmpQdRgnEmpty();
- ClipToGC(d, gc, port, tkMacOSXtmpQdRgn);
+ if ((unsigned)gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) {
+ CGContextSetLineCap(dc.context,
+ cgCap[(unsigned)gc->cap_style]);
}
- if (!tkPictureIsOpen) {
- ShowPen();
+ if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
+ CGContextSetLineJoin(dc.context,
+ cgJoin[(unsigned)gc->join_style]);
}
}
+ } else if (dc.port) {
+ PixPatHandle savePat = penPat;
+
+ ChkErr(GetThemeDrawingState, &dc.saveState);
+ penPat = NULL;
+ TkMacOSXSetUpGraphicsPort(gc, dc.port);
+ dc.penPat = penPat;
+ penPat = savePat;
+ dc.saveClip = NewRgn();
+ GetPortClipRegion(dc.port, dc.saveClip);
+ if (dc.clipRgn) {
+ ChkErr(HIShapeSetQDClip, dc.clipRgn, dc.port);
+ } else {
+ NoQDClip(dc.port);
+ }
+ if (!tkPictureIsOpen) {
+ ShowPen();
+ }
}
- dc->portBounds = portBounds;
- dc->port = port;
- dc->context = context;
- return useCG;
+end:
+ *dcPtr = dc;
+ return !dontDraw;
}
/*
@@ -1631,87 +1724,130 @@ TkMacOSXSetupDrawingContext(
*/
void
-TkMacOSXRestoreDrawingContext(TkMacOSXDrawingContext *dc)
+TkMacOSXRestoreDrawingContext(
+ TkMacOSXDrawingContext *dcPtr)
{
- if (dc->context) {
- CGContextSynchronize(dc->context);
- if (dc->saveState) {
- CGContextRestoreGState(dc->context);
+ if (dcPtr->context) {
+ CGContextSynchronize(dcPtr->context);
+ if (dcPtr->saveState) {
+ CGContextRestoreGState(dcPtr->context);
}
- if (dc->port) {
- ChkErr(QDEndCGContext, dc->port, &(dc->context));
+ if (dcPtr->port) {
+ ChkErr(QDEndCGContext, dcPtr->port, &(dcPtr->context));
}
- } else if (dc->port) {
+ } else if (dcPtr->port) {
if (!tkPictureIsOpen) {
HidePen();
}
PenNormal();
- if (dc->saveClip) {
- SetPortClipRegion(dc->port, dc->saveClip);
- DisposeRgn(dc->saveClip);
+ if (dcPtr->saveClip) {
+ SetPortClipRegion(dcPtr->port, dcPtr->saveClip);
+ DisposeRgn(dcPtr->saveClip);
}
- if (dc->penPat) {
- DisposePixPat(dc->penPat);
+ if (dcPtr->penPat) {
+ DisposePixPat(dcPtr->penPat);
}
- if (dc->saveState) {
- ChkErr(SetThemeDrawingState, dc->saveState, true);
+ if (dcPtr->saveState) {
+ ChkErr(SetThemeDrawingState, dcPtr->saveState, true);
}
}
- if (dc->portChanged) {
- QDSwapPort(dc->savePort, NULL);
+ if (dcPtr->clipRgn) {
+ CFRelease(dcPtr->clipRgn);
+ }
+ if (dcPtr->portChanged) {
+ QDSwapPort(dcPtr->savePort, NULL);
}
#ifdef TK_MAC_DEBUG
- bzero(dc, sizeof(dc));
+ bzero(dcPtr, sizeof(dcPtr));
#endif /* TK_MAC_DEBUG */
}
/*
*----------------------------------------------------------------------
*
- * TkMacOSXSetUpClippingRgn --
+ * TkMacOSXGetClipRgn --
*
- * Set up the clipping region so that drawing only occurs on the
- * specified X subwindow.
+ * Get the clipping region needed to restrict drawing to the given
+ * drawable.
*
* Results:
- * None.
+ * Clipping region. If non-NULL, CFRelease it when done.
*
* Side effects:
- * The clipping region in the current port is changed.
+ * None.
*
*----------------------------------------------------------------------
*/
-void
-TkMacOSXSetUpClippingRgn(
- Drawable drawable) /* Drawable to update. */
+HIShapeRef
+TkMacOSXGetClipRgn(
+ Drawable drawable) /* Drawable. */
{
MacDrawable *macDraw = (MacDrawable *) drawable;
- CGrafPtr port = TkMacOSXGetDrawablePort(drawable);
+ HIShapeRef clipRgn = NULL;
+ CGRect r;
if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
- TkMacOSXDbgMsg("%s clipRgn ", macDraw->winPtr->pathName);
- TkMacOSXDebugFlashRegion(drawable, macDraw->clipRgn);
+ TkMacOSXDbgMsg("%s visRgn ", macDraw->winPtr->pathName);
+ TkMacOSXDebugFlashRegion(drawable, macDraw->visRgn);
#endif /* TK_MAC_DEBUG_DRAWING */
}
- if (macDraw->clipRgn) {
+ if (macDraw->flags & TK_CLIPPED_DRAW) {
+ r = CGRectOffset(macDraw->drawRect, macDraw->xOff, macDraw->yOff);
+ }
+ if (macDraw->visRgn) {
if (macDraw->flags & TK_CLIPPED_DRAW) {
- TkMacOSXCheckTmpQdRgnEmpty();
- OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff);
- SectRgn(macDraw->clipRgn, macDraw->drawRgn, tkMacOSXtmpQdRgn);
- OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff);
- SetPortClipRegion(port, tkMacOSXtmpQdRgn);
- SetEmptyRgn(tkMacOSXtmpQdRgn);
+ HIShapeRef rgn = HIShapeCreateWithRect(&r);
+
+ clipRgn = HIShapeCreateIntersection(macDraw->visRgn, rgn);
+ CFRelease(rgn);
} else {
- SetPortClipRegion(port, macDraw->clipRgn);
+ clipRgn = HIShapeCreateCopy(macDraw->visRgn);
}
} else if (macDraw->flags & TK_CLIPPED_DRAW) {
- OffsetRgn(macDraw->drawRgn, macDraw->xOff, macDraw->yOff);
- SetPortClipRegion(port, macDraw->drawRgn);
- OffsetRgn(macDraw->drawRgn, -macDraw->xOff, -macDraw->yOff);
+ clipRgn = HIShapeCreateWithRect(&r);
+ }
+#ifdef TK_MAC_DEBUG_DRAWING
+ TkMacOSXDbgMsg("%s clipRgn ", macDraw->winPtr->pathName);
+ TkMacOSXDebugFlashRegion(drawable, clipRgn);
+#endif /* TK_MAC_DEBUG_DRAWING */
+
+ return clipRgn;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetUpClippingRgn --
+ *
+ * Set up the clipping region so that drawing only occurs on the
+ * specified X subwindow.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The clipping region in the current port is changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetUpClippingRgn(
+ Drawable drawable) /* Drawable to update. */
+{
+ CGrafPtr port = TkMacOSXGetDrawablePort(drawable);
+
+ if (port) {
+ HIShapeRef clipRgn = TkMacOSXGetClipRgn(drawable);
+
+ if (clipRgn) {
+ ChkErr(HIShapeSetQDClip, clipRgn, port);
+ CFRelease(clipRgn);
+ }
}
}
@@ -1741,14 +1877,12 @@ TkpClipDrawableToRect(
{
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;
- }
+ if (width < 0 && height < 0) {
+ macDraw->drawRect = CGRectNull;
+ macDraw->flags &= ~TK_CLIPPED_DRAW;
+ } else {
+ macDraw->drawRect = CGRectMake(x, y, width, height);
+ macDraw->flags |= TK_CLIPPED_DRAW;
}
}
@@ -1757,8 +1891,7 @@ TkpClipDrawableToRect(
*
* ClipToGC --
*
- * Helper function to intersect the given port's clip region (or if
- * port is NULL, the given clipRgn) with gc clip region.
+ * Helper function to intersect given region with gc clip region.
*
* Results:
* None.
@@ -1773,29 +1906,28 @@ static void
ClipToGC(
Drawable d,
GC gc,
- CGrafPtr port, /* can be NULL */
- RgnHandle clipRgn) /* tmp region or if port == NULL, region to intersect */
+ HIShapeRef *clipRgnPtr) /* must point to initialized variable */
{
if (gc && gc->clip_mask &&
((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) {
- RgnHandle gcClipRgn = (RgnHandle)
- ((TkpClipMask*)gc->clip_mask)->value.region;
+ TkRegion gcClip = ((TkpClipMask*)gc->clip_mask)->value.region;
int xOffset = ((MacDrawable *) d)->xOff + gc->clip_x_origin;
int yOffset = ((MacDrawable *) d)->yOff + gc->clip_y_origin;
+ HIShapeRef clipRgn = *clipRgnPtr, gcClipRgn;
if (!tkPictureIsOpen) {
- OffsetRgn(gcClipRgn, xOffset, yOffset);
+ TkMacOSXOffsetRegion(gcClip, xOffset, yOffset);
}
- if (port) {
- GetPortClipRegion(port, clipRgn);
- }
- SectRgn(clipRgn, gcClipRgn, clipRgn);
- if (port) {
- SetPortClipRegion(port, clipRgn);
- SetEmptyRgn(clipRgn);
+ gcClipRgn = TkMacOSXGetNativeRegion(gcClip);
+ if (clipRgn) {
+ *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn);
+ CFRelease(clipRgn);
+ } else {
+ *clipRgnPtr = HIShapeCreateCopy(gcClipRgn);
}
+ CFRelease(gcClipRgn);
if (!tkPictureIsOpen) {
- OffsetRgn(gcClipRgn, -xOffset, -yOffset);
+ TkMacOSXOffsetRegion(gcClip, -xOffset, -yOffset);
}
}
}