summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXDraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r--macosx/tkMacOSXDraw.c120
1 files changed, 78 insertions, 42 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index ac5c721..d5396eb 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -27,6 +27,7 @@
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
+#define TK_MAC_DEBUG_CG
#endif
*/
@@ -513,7 +514,7 @@ XDrawSegments(
*
* XFillPolygon --
*
- * Draws a filled polygon.
+ * Draws a filled polygon using the even-odd fill algorithm,
*
* Results:
* None.
@@ -531,7 +532,7 @@ XFillPolygon(
GC gc, /* Use this GC. */
XPoint *points, /* Array of points. */
int npoints, /* Number of points. */
- TCL_UNUSED(int), /* Shape to draw. */
+ TCL_UNUSED(int), /* Shape to draw. */
int mode) /* Drawing mode. */
{
MacDrawable *macWin = (MacDrawable *)d;
@@ -1265,6 +1266,12 @@ TkMacOSXSetupDrawingContext(
Bool canDraw = true;
TKContentView *view = nil;
TkMacOSXDrawingContext dc = {};
+ CGFloat drawingHeight;
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "TkMacOSXSetupDrawingContext: %s\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
+#endif
/*
* If the drawable is not a pixmap, get the associated NSView.
@@ -1296,14 +1303,10 @@ TkMacOSXSetupDrawingContext(
*/
dc.context = TkMacOSXGetCGContextForDrawable(d);
- if (dc.context) {
- dc.portBounds = CGContextGetClipBoundingBox(dc.context);
- } else {
+ if (!dc.context) {
NSRect drawingBounds, currentBounds;
-
dc.view = view;
dc.context = GET_CGCONTEXT;
- dc.portBounds = NSRectToCGRect([view bounds]);
if (dc.clipRgn) {
CGRect clipBounds;
CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
@@ -1355,37 +1358,66 @@ TkMacOSXSetupDrawingContext(
* Finish configuring the drawing context.
*/
- {
- CGAffineTransform t = {
- .a = 1, .b = 0,
- .c = 0, .d = -1,
- .tx = 0,
- .ty = dc.portBounds.size.height
- };
+ drawingHeight = view ? [view bounds].size.height :
+ CGContextGetClipBoundingBox(dc.context).size.height;
+ CGAffineTransform t = {
+ .a = 1, .b = 0,
+ .c = 0, .d = -1,
+ .tx = 0,
+ .ty = drawingHeight
+ };
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "TkMacOSXSetupDrawingContext: pushing GState for %s\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
+#endif
- dc.portBounds.origin.x += macDraw->xOff;
- dc.portBounds.origin.y += macDraw->yOff;
- CGContextSaveGState(dc.context);
- CGContextSetTextDrawingMode(dc.context, kCGTextFill);
- CGContextConcatCTM(dc.context, t);
- if (dc.clipRgn) {
+ CGContextSaveGState(dc.context);
+ CGContextSetTextDrawingMode(dc.context, kCGTextFill);
+ CGContextConcatCTM(dc.context, t);
+ 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.1);
- CGContextEOFillPath(dc.context);
- CGContextRestoreGState(dc.context);
+ CGContextSaveGState(dc.context);
+ ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
+ CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
+ CGContextEOFillPath(dc.context);
+ CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */
+ if (!HIShapeIsRectangular(dc.clipRgn)) {
+
+ /*
+ * We expect the clipping path dc.clipRgn to consist of the
+ * bounding rectangle of the drawable window, together with
+ * disjoint smaller rectangles inside of it which bound its
+ * geometric children. In that case the even-odd rule will
+ * clip to the region inside the large rectangle and outside
+ * of the smaller rectangles.
+ */
+
+ ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "Setting complex clip for %s to:\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
+ TkMacOSXPrintRectsInRegion(dc.clipRgn);
+#endif
+
+ CGContextEOClip(dc.context);
+ } else {
CGRect r;
- CGRect b = CGRectApplyAffineTransform(
- CGContextGetClipBoundingBox(dc.context), t);
- if (!HIShapeIsRectangular(dc.clipRgn) ||
- !CGRectContainsRect(*HIShapeGetBounds(dc.clipRgn, &r), b)) {
- ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
- CGContextEOClip(dc.context);
- }
+ HIShapeGetBounds(dc.clipRgn, &r);
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "Current clip BBox is %s\n",
+ NSStringFromRect(CGContextGetClipBoundingBox(GET_CGCONTEXT)).UTF8String);
+ fprintf(stderr, "Setting clip for %s to rect %s:\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None",
+ NSStringFromRect(r).UTF8String);
+#endif
+
+ CGContextClipToRect(dc.context, r);
}
}
if (gc) {
@@ -1405,8 +1437,8 @@ TkMacOSXSetupDrawingContext(
TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
if (view) {
- CGContextSetPatternPhase(dc.context, CGSizeMake(
- dc.portBounds.size.width, dc.portBounds.size.height));
+ CGSize size = NSSizeToCGSize([view bounds].size);
+ CGContextSetPatternPhase(dc.context, size);
}
if (gc->function != GXcopy) {
TkMacOSXDbgMsg("Logical functions other than GXcopy are "
@@ -1446,13 +1478,9 @@ TkMacOSXSetupDrawingContext(
end:
#ifdef TK_MAC_DEBUG_DRAWING
- if (!canDraw && win != NULL) {
- TkWindow *winPtr = TkMacOSXGetTkWindow(win);
-
- if (winPtr) {
- fprintf(stderr, "Cannot draw in %s - postponing.\n",
- Tk_PathName(winPtr));
- }
+ if (!canDraw && macDraw->winPtr != NULL) {
+ fprintf(stderr, "Cannot draw in %s - postponing.\n",
+ Tk_PathName(macDraw->winPtr));
}
#endif
@@ -1487,13 +1515,21 @@ TkMacOSXRestoreDrawingContext(
if (dcPtr->context) {
CGContextSynchronize(dcPtr->context);
CGContextRestoreGState(dcPtr->context);
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "TkMacOSXRestoreDrawingContext: popped GState\n");
+#endif
+
}
if (dcPtr->clipRgn) {
CFRelease(dcPtr->clipRgn);
+ dcPtr->clipRgn = NULL;
}
+
#ifdef TK_MAC_DEBUG
bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
-#endif /* TK_MAC_DEBUG */
+#endif
+
}
/*