Have mark_dirty always invalidate the last clip set on the surface

mark_dirty will force cairo to set its own clip the next time the cairo clip
is applied after mark_dirty; otherwise we run the risk of cairo's cached
clip and the device clip getting out of sync if any clip-related functions
are used on the native device back-end.
(cherry picked from 1935a28949da8569f924e37714ec19571fa95987 commit)
(cherry picked from ef8b472f0ffab7b8b828d7297c7e454bb22bd5ec commit)
This commit is contained in:
Vladimir Vukicevic 2006-02-15 13:14:52 -08:00 committed by Vladimir Vukicevic
parent e0f4eecb91
commit f4b34df6b6

View file

@ -502,6 +502,10 @@ cairo_surface_mark_dirty (cairo_surface_t *surface)
* Like cairo_surface_mark_dirty(), but drawing has been done only to
* the specified rectangle, so that cairo can retain cached contents
* for other parts of the surface.
*
* Any cached clip set on the surface will be reset by this function,
* to make sure that future cairo calls have the clip set that they
* expect.
*/
void
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
@ -520,6 +524,13 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
return;
}
/* Always reset the clip here, to avoid having external calls to
* clip manipulation functions of the underlying device clip result
* in a desync between the cairo clip and the backend clip, due to
* the clip caching.
*/
surface->current_clip_serial = -1;
if (surface->backend->mark_dirty_rectangle) {
cairo_status_t status;
@ -1329,6 +1340,12 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
if (!surface)
return CAIRO_STATUS_NULL_POINTER;
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
if (clip) {
serial = clip->serial;
if (serial == 0)
@ -1336,7 +1353,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
}
surface->clip = clip;
if (serial == _cairo_surface_get_current_clip_serial (surface))
return CAIRO_STATUS_SUCCESS;