summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXDraw.c
diff options
context:
space:
mode:
authorculler <culler>2020-06-01 21:34:36 (GMT)
committerculler <culler>2020-06-01 21:34:36 (GMT)
commitaeb89ef62c14b00be0853a7539e807bb3937a6f8 (patch)
tree22be887c989589854a6d45dc311e73c4a395ebd0 /macosx/tkMacOSXDraw.c
parent11b02278eef59eb2b8412727e92256477ea6188b (diff)
downloadtk-aeb89ef62c14b00be0853a7539e807bb3937a6f8.zip
tk-aeb89ef62c14b00be0853a7539e807bb3937a6f8.tar.gz
tk-aeb89ef62c14b00be0853a7539e807bb3937a6f8.tar.bz2
Better control over when drawRect runs. Add check for drawing outside of the drawRect clipping rectangle.
Diffstat (limited to 'macosx/tkMacOSXDraw.c')
-rw-r--r--macosx/tkMacOSXDraw.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index dcc3d79..1ec2cfe 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -1631,30 +1631,47 @@ TkMacOSXSetupDrawingContext(
Tcl_Panic("TkMacOSXSetupDrawingContext(): "
"no NSView to draw into !");
}
+ if (dc.clipRgn) {
+ CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
+ .ty = [view bounds].size.height};
+ HIShapeGetBounds(dc.clipRgn, &clipBounds);
+ clipBounds = CGRectApplyAffineTransform(clipBounds, t);
+ }
+ if (![NSApp isDrawing] || view != [NSView focusView]) {
- /*
- * We can only draw into the view when the current CGContext is valid
- * and belongs to the view. Validity can only be guaranteed inside of
- * a view's drawRect or setFrame methods. The isDrawing attribute
- * tells us whether we are being called from one of those methods.
- *
- * If the CGContext is not valid then we mark our view as needing
- * display. We could try to optimize by computing a smaller dirty rect
- * here.
- */
+ /*
+ * We can only draw into the view when the current CGContext is
+ * valid and belongs to the view. Validity can only be guaranteed
+ * inside of a view's drawRect or setFrame methods. The isDrawing
+ * attribute tells us whether we are being called from one of those
+ * methods. If the CGContext is not valid then we mark our view as
+ * needing display.
+ */
- if (![NSApp isDrawing] || view != [NSView focusView]) {
- NSRect dirtyRect = [view bounds];
if (dc.clipRgn) {
- CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
- .ty = dirtyRect.size.height};
- HIShapeGetBounds(dc.clipRgn, &clipBounds);
- clipBounds = CGRectApplyAffineTransform(clipBounds, t);
- dirtyRect = NSRectFromCGRect(clipBounds);
+ [view addTkDirtyRect:clipBounds];
+ } else {
+ [view addTkDirtyRect:[view bounds]];
}
- [view addTkDirtyRect:dirtyRect];
canDraw = false;
goto end;
+ } else if (dc.clipRgn) {
+
+ /*
+ * Drawing can also fail when we are being called from drawRect but
+ * the clipping region set by drawRect does not contain the clipping
+ * region of our drawing context. See bug [2a61eca3a8].
+ */
+
+ CGRect currentClip = CGContextGetClipBoundingBox(
+ [NSGraphicsContext currentContext].CGContext);
+ if (!NSContainsRect(currentClip, clipBounds)) {
+ [view addTkDirtyRect:clipBounds];
+ // XXXX we should be able to skip drawing but sometimes the clipBounds
+ // are wrong.
+ //canDraw = false;
+ //goto end;
+ }
}
dc.view = view;
@@ -1686,6 +1703,7 @@ TkMacOSXSetupDrawingContext(
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);
@@ -1693,6 +1711,7 @@ TkMacOSXSetupDrawingContext(
CGContextEOFillPath(dc.context);
CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */
+
CGRect r;
if (!HIShapeIsRectangular(dc.clipRgn) || !CGRectContainsRect(