From fbb8a62797657a98905b92bd01bfa995cc823def Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 6 Jan 2006 14:11:07 +0000 Subject: [PATCH] Reviewed by keithp Implement copy_page for paginated surface. Fix show_page to destroy the meta-surface and create a new one. Change these functions to advertise when they are not supported, so that _cairo_paginated_copy_page can implement things differently depending on whether or not it is personal. Check return values from _cairo_surface_show/copy_page. --- ChangeLog | 21 ++++++++++++++ src/cairo-gstate.c | 20 +++++++++++-- src/cairo-paginated-surface.c | 54 ++++++++++++++++++++++++++++++++++- src/cairo-surface.c | 16 +++++++---- src/cairoint.h | 4 +-- 5 files changed, 104 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e7861adf..beaae8cbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2006-01-06 Carl Worth + + Reviewed by keithp + + * src/cairo-paginated-surface.c: (_cairo_paginated_surface_create), + (_cairo_paginated_surface_copy_page), + (_cairo_paginated_surface_show_page): Implement copy_page for + paginated surface. Fix show_page to destroy the meta-surface and + create a new one. + + * src/cairoint.h: + * src/cairo-surface.c: (_cairo_surface_copy_page), + (_cairo_surface_show_page): Change these functions to advertise + when they are not supported, so that _cairo_paginated_copy_page + can implement things differently depending on whether or not it is + personal. + + * src/cairo-gstate.c: (_cairo_gstate_copy_page), + (_cairo_gstate_show_page): Check return values from + _cairo_surface_show/copy_page. + 2006-01-05 Carl Worth * ROADMAP: Slip 1.2.0 projected data (again) out to diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 2bb5e67e4..10212cc78 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1040,13 +1040,29 @@ BAIL: cairo_status_t _cairo_gstate_copy_page (cairo_gstate_t *gstate) { - return _cairo_surface_copy_page (gstate->target); + cairo_int_status_t status; + + status = _cairo_surface_copy_page (gstate->target); + + /* It's fine if some surfaces just don't support this. */ + if (status == CAIRO_INT_STATUS_UNSUPPORTED) + return CAIRO_STATUS_SUCCESS; + + return status; } cairo_status_t _cairo_gstate_show_page (cairo_gstate_t *gstate) { - return _cairo_surface_show_page (gstate->target); + cairo_int_status_t status; + + status = _cairo_surface_show_page (gstate->target); + + /* It's fine if some surfaces just don't support this. */ + if (status == CAIRO_INT_STATUS_UNSUPPORTED) + return CAIRO_STATUS_SUCCESS; + + return status; } cairo_status_t diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index 5c871febb..b920a12a2 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -72,6 +72,14 @@ typedef struct _cairo_paginated_surface { cairo_surface_t base; + /* XXX: These shouldn't actually exist. We inherit this ugliness + * from _cairo_meta_surface_create. The width/height parameters + * from that function also should not exist. The fix that will + * allow us to remove all of these is to fix acquire_source_image + * to pass an interest rectangle. */ + int width; + int height; + /* The target surface to hold the final result. */ cairo_surface_t *target; @@ -100,6 +108,9 @@ _cairo_paginated_surface_create (cairo_surface_t *target, _cairo_surface_init (&surface->base, &cairo_paginated_surface_backend); + surface->width = width; + surface->height = height; + surface->target = target; surface->meta = _cairo_meta_surface_create (width, height); @@ -157,6 +168,39 @@ _cairo_paginated_surface_release_source_image (void *abstract_surface, cairo_surface_destroy (&image->base); } +static cairo_int_status_t +_cairo_paginated_surface_copy_page (void *abstract_surface) +{ + cairo_paginated_surface_t *surface = abstract_surface; + cairo_int_status_t status; + + _cairo_meta_surface_replay (surface->meta, surface->target); + + status = _cairo_surface_copy_page (surface->target); + + /* If the surface does not support copy_page then we use show_page + * instead, and we leave the meta-surface untouched so that its + * contents will remain for the next page. */ + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + status = _cairo_surface_show_page (surface->target); + /* And if the surface doesn't support show_page either, we + * also fall through and clear the meta-surface. */ + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + } + + /* Otherwise, we clear the meta-surface since the target surface + * has already taken care of any copying in its implementation of + * copy_page. */ + cairo_surface_destroy (surface->meta); + + surface->meta = _cairo_meta_surface_create (surface->width, surface->height); + if (cairo_surface_status (surface->meta)) + return cairo_surface_status (surface->meta); + + return CAIRO_STATUS_SUCCESS; +} + static cairo_int_status_t _cairo_paginated_surface_show_page (void *abstract_surface) { @@ -164,6 +208,14 @@ _cairo_paginated_surface_show_page (void *abstract_surface) _cairo_meta_surface_replay (surface->meta, surface->target); + _cairo_surface_show_page (surface->target); + + cairo_surface_destroy (surface->meta); + + surface->meta = _cairo_meta_surface_create (surface->width, surface->height); + if (cairo_surface_status (surface->meta)) + return cairo_surface_status (surface->meta); + return CAIRO_STATUS_SUCCESS; } @@ -308,7 +360,7 @@ const cairo_surface_backend_t cairo_paginated_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ - NULL, /* copy_page */ + _cairo_paginated_surface_copy_page, _cairo_paginated_surface_show_page, NULL, /* set_clip_region */ _cairo_paginated_surface_intersect_clip_path, diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 4865fc716..29820173e 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1091,7 +1091,10 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, traps, num_traps); } -cairo_status_t +/* _copy_page and _show_page are unique among _cairo_surface functions + * in that they will actually return CAIRO_INT_STATUS_UNSUPPORTED + * rather than performing any fallbacks. */ +cairo_int_status_t _cairo_surface_copy_page (cairo_surface_t *surface) { assert (! surface->is_snapshot); @@ -1102,14 +1105,16 @@ _cairo_surface_copy_page (cairo_surface_t *surface) if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; - /* It's fine if some backends just don't support this. */ if (surface->backend->copy_page == NULL) - return CAIRO_STATUS_SUCCESS; + return CAIRO_INT_STATUS_UNSUPPORTED; return surface->backend->copy_page (surface); } -cairo_status_t +/* _show_page and _copy_page are unique among _cairo_surface functions + * in that they will actually return CAIRO_INT_STATUS_UNSUPPORTED + * rather than performing any fallbacks. */ +cairo_int_status_t _cairo_surface_show_page (cairo_surface_t *surface) { assert (! surface->is_snapshot); @@ -1120,9 +1125,8 @@ _cairo_surface_show_page (cairo_surface_t *surface) if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; - /* It's fine if some backends just don't support this. */ if (surface->backend->show_page == NULL) - return CAIRO_STATUS_SUCCESS; + return CAIRO_INT_STATUS_UNSUPPORTED; return surface->backend->show_page (surface); } diff --git a/src/cairoint.h b/src/cairoint.h index dfcc36cee..2bfcd97be 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1688,10 +1688,10 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, cairo_trapezoid_t *traps, int ntraps); -cairo_private cairo_status_t +cairo_private cairo_int_status_t _cairo_surface_copy_page (cairo_surface_t *surface); -cairo_private cairo_status_t +cairo_private cairo_int_status_t _cairo_surface_show_page (cairo_surface_t *surface); cairo_private cairo_status_t