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.
This commit is contained in:
Adrian Johnson 2008-01-07 21:05:36 +10:30
parent d2a5d1ace6
commit e195cb551c
4 changed files with 19 additions and 12 deletions

View file

@ -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

View file

@ -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,

View file

@ -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;

View file

@ -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