-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Keep clipping inside containers. #639
Conversation
I realised shortly after I posted this yesterday that |
Store the overall clip, and calculate it when modifying the clip. GdipIsVisiblePoint() and GdipIsVisibleRect() need to use the visible clip, not just its bounds.
Sorry it is taking me so long to review this. I'm still going through the ASAN reports (after applying @akoeplinger's test patches). There are some leaks reported and I have to figure out whether they are false positives, pre-existing leaks, or something introduced by this PR (likely mix of all of this). |
gdip_cairo_matrix_copy (graphics->clip_matrix, &pos_state->clip_matrix); | ||
|
||
gdip_calculate_overall_clipping (graphics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
graphics->overall_clip
is leaked at this point. Couple of lines above you set graphics->previous_clip
to NULL
(and pos_state->previous_clip
can be NULL
too). This causes gdip_calculate_overall_clipping
to enter this code path:
if (!graphics->previous_clip) {
graphics->overall_clip = graphics->clip;
}
and never free the original overall_clip
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found one memory leak in the PR and one other preexisting one (#649). I wrote down a suggestion on how to fix it, otherwise LGTM.
Co-Authored-By: Filip Navara <[email protected]>
Thanks for picking that up. Your suggested fix looks good to me, so I've committed it. |
Containers need to maintain the clipping that exists outside them.
I have implemented this by storing the overall clip region outside the current container (
graphics->previous_clip
,NULL
if not in a container or if no clipping outside) in addition to any clip region set (graphics->clip
), and then intersecting them incairo_SetGraphicsClip()
,GdipBeginContainer2()
andGdipGetVisibleClipBounds()
(the three places that need the overall clip).previous_clip
goes on the save stack on saving, in addition toclip
.Alternatively the intersection could be done when modifying the clip and when restoring it off the save stack (four places), but that would mean storing the resulting region as well as the other two, although the overall clip wouldn't need to be stored on the save stack. (
GdipTranslateClip()
,GdipGetClip()
andGdipGetClipBounds()
need the clip that was set.)Also, I modified
GdipResetClip()
to callcairo_SetGraphicsClip()
rather thancairo_ResetClip()
whenprevious_clip
exists, as it needs to keep that. Alternatively, it would be possible to modifycairo_ResetClip()
to set the clip toprevious_clip
itself.I have implemented this into
GdipGetVisibleClipBounds()
, as that should provide the overall clip bounds. And I changedGdipIsVisiblePoint()
andGdipIsVisibleRect()
to use that instead of thegraphics->bounds
(they should take clipping into account). I won't mention the insane check previously used in the latter of those two methods, but the replacement was taken from region.c – ideally I'd have added a declaration for it to region-private.h, but I didn't thinkgdip_intersects()
was a descriptive enough name for that, and I didn't want to do a rename.I guess I should write some tests too, so I'll try to get around to that some time soon. But I'll put this out there now for any comments.