diff options
Diffstat (limited to 'src/cairo-meta-surface.c')
-rw-r--r-- | src/cairo-meta-surface.c | 144 |
1 files changed, 70 insertions, 74 deletions
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 8a893d661..f218ae240 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -35,15 +35,7 @@ #include "cairoint.h" #include "cairo-meta-surface-private.h" - -/* - * Notes: - * - * Can't use cairo_surface_* calls since we often don't want - * fallbacks. For example, when determining the font subsets or the - * fallback areas. Hmm... but maybe those passes could be integrated - * into the delegation wrappers and the ps output pass, respectively. - */ +#include "cairo-gstate-private.h" static const cairo_surface_backend_t cairo_meta_surface_backend; @@ -106,10 +98,6 @@ _cairo_meta_surface_finish (void *abstract_surface) free (command); break; - case CAIRO_COMMAND_SET_CLIP_REGION: - free (command); - break; - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: if (command->intersect_clip_path.path_pointer) _cairo_path_fixed_fini (&command->intersect_clip_path.path); @@ -229,6 +217,7 @@ static cairo_int_status_t _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_surface, + cairo_antialias_t antialias, int x_src, int y_src, int x_dst, @@ -248,6 +237,7 @@ _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, command->type = CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS; command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); + command->antialias = antialias; command->x_src = x_src; command->y_src = y_src; command->x_dst = x_dst; @@ -276,42 +266,11 @@ _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, } static cairo_int_status_t -_cairo_meta_surface_set_clip_region (void *abstract_surface, - pixman_region16_t *region) -{ - cairo_meta_surface_t *meta = abstract_surface; - cairo_command_set_clip_region_t *command; - - command = malloc (sizeof (cairo_command_set_clip_region_t)); - if (command == NULL) - return CAIRO_STATUS_NO_MEMORY; - - command->type = CAIRO_COMMAND_SET_CLIP_REGION; - - if (region) { - command->region = pixman_region_create (); - pixman_region_copy (command->region, region); - } else { - command->region = NULL; - } - - command->serial = meta->base.current_clip_serial; - - if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { - if (command->region) - pixman_region_destroy (command->region); - free (command); - return CAIRO_STATUS_NO_MEMORY; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t _cairo_meta_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance) + double tolerance, + cairo_antialias_t antialias) { cairo_meta_surface_t *meta = dst; cairo_command_intersect_clip_path_t *command; @@ -335,6 +294,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst, } command->fill_rule = fill_rule; command->tolerance = tolerance; + command->antialias = antialias; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { if (path) @@ -387,8 +347,7 @@ _cairo_meta_surface_show_glyphs (cairo_scaled_font_t *scaled_font, return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_SHOW_GLYPHS; - command->scaled_font = scaled_font; - cairo_scaled_font_reference (scaled_font); + command->scaled_font = cairo_scaled_font_reference (scaled_font); command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); command->source_x = source_x; @@ -469,7 +428,7 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = { _cairo_meta_surface_composite_trapezoids, NULL, /* copy_page */ NULL, /* show_page */ - _cairo_meta_surface_set_clip_region, + NULL, /* set_clip_region */ _cairo_meta_surface_intersect_clip_path, _cairo_meta_surface_get_extents, _cairo_meta_surface_show_glyphs, @@ -484,16 +443,24 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, cairo_command_t *command, **elements; int i, num_elements; cairo_int_status_t status; + cairo_traps_t traps; + cairo_clip_t clip; meta = (cairo_meta_surface_t *) surface; status = CAIRO_STATUS_SUCCESS; + _cairo_clip_init (&clip, target); + num_elements = meta->commands.num_elements; elements = (cairo_command_t **) meta->commands.elements; for (i = 0; i < num_elements; i++) { command = elements[i]; switch (command->type) { case CAIRO_COMMAND_COMPOSITE: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_composite (command->composite.operator, &command->composite.src_pattern.base, @@ -510,6 +477,10 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; case CAIRO_COMMAND_FILL_RECTANGLES: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_fill_rectangles (target, command->fill_rectangles.operator, @@ -519,10 +490,15 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_composite_trapezoids (command->composite_trapezoids.operator, &command->composite_trapezoids.pattern.base, target, + command->composite_trapezoids.antialias, command->composite_trapezoids.x_src, command->composite_trapezoids.y_src, command->composite_trapezoids.x_dst, @@ -533,27 +509,25 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, command->composite_trapezoids.num_traps); break; - case CAIRO_COMMAND_SET_CLIP_REGION: - status = _cairo_surface_set_clip_region - (target, - command->set_clip_region.region, - command->set_clip_region.serial); - break; - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: /* XXX Meta surface clipping is broken and requires some * cairo-gstate.c rewriting. Work around it for now. */ - if (target->backend->intersect_clip_path == NULL) - break; - - status = _cairo_surface_intersect_clip_path - (target, - command->intersect_clip_path.path_pointer, - command->intersect_clip_path.fill_rule, - command->intersect_clip_path.tolerance); + if (command->intersect_clip_path.path_pointer == NULL) + status = _cairo_clip_reset (&clip); + else + status = _cairo_clip_clip (&clip, + command->intersect_clip_path.path_pointer, + command->intersect_clip_path.fill_rule, + command->intersect_clip_path.tolerance, + command->intersect_clip_path.antialias, + target); break; case CAIRO_COMMAND_SHOW_GLYPHS: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_show_glyphs (command->show_glyphs.scaled_font, command->show_glyphs.operator, @@ -570,18 +544,38 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; case CAIRO_COMMAND_FILL_PATH: - /* XXX Meta surface fill_path is broken and requires some - * cairo-gstate.c rewriting. Work around it for now. */ - if (target->backend->fill_path == NULL) + status = _cairo_surface_set_clip (target, &clip); + if (status) break; - status = _cairo_surface_fill_path - (command->fill_path.operator, - &command->fill_path.pattern.base, - target, - &command->fill_path.path, - command->fill_path.fill_rule, - command->fill_path.tolerance); + status = _cairo_surface_fill_path (command->fill_path.operator, + &command->fill_path.pattern.base, + target, + &command->fill_path.path, + command->fill_path.fill_rule, + command->fill_path.tolerance); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + break; + + _cairo_traps_init (&traps); + + status = _cairo_path_fixed_fill_to_traps (&command->fill_path.path, + command->fill_path.fill_rule, + command->fill_path.tolerance, + &traps); + if (status) { + _cairo_traps_fini (&traps); + break; + } + + status = _cairo_surface_clip_and_composite_trapezoids (&command->fill_path.pattern.base, + command->fill_path.operator, + target, + &traps, + &clip, + command->fill_path.antialias); + + _cairo_traps_fini (&traps); break; default: @@ -592,5 +586,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; } + _cairo_clip_fini (&clip); + return status; } |