From e195cb551caa40f309127ac7a39e4a17653966c8 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Mon, 7 Jan 2008 21:05:36 +1030 Subject: [PATCH] Add FALLBACK mode to paginated surface The PDF surface needs to know when the fallback images start so it can close off the content stream and create a knockout transparency group for the fallback images. Currently it does this by looking for operations with CAIRO_OPERATOR_SOURCE. PDF returns unsupported for _SOURCE during the analysis phase so _SOURCE will never appear during native operations. However this prevents the PDF surface from supporting _SOURCE operations that can be natively supported. For example a _SOURCE operation with nothing painting under it can be converted to _OVER and natively supported. A third mode, CAIRO_PAGINATED_MODE_FALLBACK, has been added. The paginated surface will set this mode before it paints finer-grained fallback images. --- src/cairo-paginated-private.h | 22 +++++++++++++--------- src/cairo-paginated-surface.c | 4 +++- src/cairo-pdf-surface.c | 2 +- src/cairo-types-private.h | 3 ++- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h index 1ecb01420..7b411915e 100644 --- a/src/cairo-paginated-private.h +++ b/src/cairo-paginated-private.h @@ -110,18 +110,22 @@ struct _cairo_paginated_surface_backend { * * 6. Replays a subset of the meta-surface operations to the target surface * - * 7. Replays the remaining operations to an image surface, sets an + * 7. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_FALLBACK + * + * 8. Replays the remaining operations to an image surface, sets an * appropriate clip on the target, then paints the resulting image * surface to the target. * - * So, the target will see drawing operations during two separate - * stages, (ANALYZE and RENDER). During the ANALYZE phase the target - * should not actually perform any rendering, (for example, if - * performing output to a file, no output should be generated during - * this stage). Instead the drawing functions simply need to return - * CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate - * whether rendering would be supported. And it should do this as - * quickly as possible. + * So, the target will see drawing operations during three separate + * stages, (ANALYZE, RENDER and FALLBACK). During the ANALYZE phase + * the target should not actually perform any rendering, (for example, + * if performing output to a file, no output should be generated + * during this stage). Instead the drawing functions simply need to + * return CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to + * indicate whether rendering would be supported. And it should do + * this as quickly as possible. The FALLBACK phase allows the surface + * to distinguish fallback images from native rendering in case they + * need to be handled as a special case. * * NOTE: The paginated surface layer assumes that the target surface * is "blank" by default at the beginning of each page, without any diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index 068a60c1e..d644d8740 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -365,7 +365,9 @@ _paint_page (cairo_paginated_surface_t *surface) cairo_box_int_t *boxes; int num_boxes, i; - /* Reset clip region before drawing the fall back images */ + surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_FALLBACK); + + /* Reset clip region before drawing the fall back images */ status = _cairo_surface_intersect_clip_path (surface->target, NULL, CAIRO_FILL_RULE_WINDING, diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index dae9e94ea..c437ce4c4 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -4168,7 +4168,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface, /* The SOURCE operator is only supported for the fallback images. */ if (op == CAIRO_OPERATOR_SOURCE && - surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) + surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) return CAIRO_STATUS_SUCCESS; return CAIRO_INT_STATUS_UNSUPPORTED; diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index a7af7126e..3954f13b2 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -123,7 +123,8 @@ struct _cairo_cache { typedef enum _cairo_paginated_mode { CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */ - CAIRO_PAGINATED_MODE_RENDER /* render page contents */ + CAIRO_PAGINATED_MODE_RENDER, /* render page contents */ + CAIRO_PAGINATED_MODE_FALLBACK /* paint fallback images */ } cairo_paginated_mode_t; /* Sure wish C had a real enum type so that this would be distinct