diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-23 15:13:42 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-23 15:33:14 +0100 |
commit | 7e42276ffc52c417f8119517485b609ef7f7743e (patch) | |
tree | 39d8470693bd34caf03f9e5548072d4ca1661b30 /src/cairo-image-surface.c | |
parent | a30a7402f73485dabdb6a016178247f9844017a1 (diff) |
image: Apply mask-opacity to clip boxes
In the simple condition where the user is applying an opacity mask to a
misaligned rectangle, we can treat it as a series of simpler composites
by combining the opacity with the coverage of the box.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-image-surface.c')
-rw-r--r-- | src/cairo-image-surface.c | 445 |
1 files changed, 299 insertions, 146 deletions
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index f727b84ac..e2e0e18c7 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1882,25 +1882,23 @@ typedef cairo_status_t int dst_x, int dst_y, cairo_matrix_t *dst_device_transform, - const cairo_rectangle_int_t *extents, - cairo_region_t *clip_region); + const cairo_composite_rectangles_t *extents); static pixman_image_t * -_create_composite_mask_pattern (cairo_clip_t *clip, +_create_composite_mask_pattern (cairo_composite_rectangles_t *extents, image_draw_func_t draw_func, void *draw_closure, - cairo_image_surface_t *dst, - const cairo_rectangle_int_t *extents) + cairo_image_surface_t *dst) { - cairo_region_t *clip_region = _cairo_clip_get_region (clip); - cairo_bool_t need_clip_surface = ! _cairo_clip_is_region (clip); + cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip); + cairo_bool_t need_clip_surface = ! _cairo_clip_is_region (extents->clip); pixman_image_t *mask; cairo_status_t status; if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1) clip_region = NULL; - mask = pixman_image_create_bits (PIXMAN_a8, extents->width, extents->height, + mask = pixman_image_create_bits (PIXMAN_a8, extents->bounded.width, extents->bounded.height, NULL, 0); if (unlikely (mask == NULL)) return NULL; @@ -1909,9 +1907,9 @@ _create_composite_mask_pattern (cairo_clip_t *clip, if (clip_region != NULL) { pixman_bool_t ret; - pixman_region32_translate (&clip_region->rgn, -extents->x, -extents->y); + pixman_region32_translate (&clip_region->rgn, -extents->bounded.x, -extents->bounded.y); ret = pixman_image_set_clip_region32 (mask, &clip_region->rgn); - pixman_region32_translate (&clip_region->rgn, extents->x, extents->y); + pixman_region32_translate (&clip_region->rgn, extents->bounded.x, extents->bounded.y); if (! ret) { pixman_image_unref (mask); @@ -1922,9 +1920,9 @@ _create_composite_mask_pattern (cairo_clip_t *clip, status = draw_func (draw_closure, mask, PIXMAN_a8, CAIRO_OPERATOR_ADD, NULL, - extents->x, extents->y, + extents->bounded.x, extents->bounded.y, &dst->base.device_transform, - extents, NULL); + extents); if (unlikely (status)) { pixman_image_unref (mask); return NULL; @@ -1941,8 +1939,9 @@ _create_composite_mask_pattern (cairo_clip_t *clip, pixman_image_ref (mask); - status = _cairo_clip_combine_with_surface (clip, tmp, - extents->x, extents->y); + status = _cairo_clip_combine_with_surface (extents->clip, tmp, + extents->bounded.x, + extents->bounded.y); cairo_surface_destroy (tmp); if (unlikely (status)) { pixman_image_unref (mask); @@ -1960,17 +1959,16 @@ _create_composite_mask_pattern (cairo_clip_t *clip, * us to combine the clip with the mask */ static cairo_status_t -_clip_and_composite_with_mask (cairo_clip_t *clip, +_clip_and_composite_with_mask (cairo_composite_rectangles_t *extents, cairo_operator_t op, const cairo_pattern_t *pattern, image_draw_func_t draw_func, void *draw_closure, - cairo_image_surface_t *dst, - const cairo_rectangle_int_t *extents) + cairo_image_surface_t *dst) { pixman_image_t *mask; - mask = _create_composite_mask_pattern (clip, draw_func, draw_closure, dst, extents); + mask = _create_composite_mask_pattern (extents, draw_func, draw_closure, dst); if (unlikely (mask == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -1979,8 +1977,8 @@ _clip_and_composite_with_mask (cairo_clip_t *clip, pixman_image_composite32 (_pixman_operator (op), mask, NULL, dst->pixman_image, 0, 0, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); } else { pixman_image_t *src; @@ -1993,15 +1991,15 @@ _clip_and_composite_with_mask (cairo_clip_t *clip, pixman_image_composite32 (_pixman_operator (op), src, mask, dst->pixman_image, 0, 0, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); pixman_image_unref (src); } } else { pixman_image_t *src; int src_x, src_y; - src = _pixman_image_for_pattern (pattern, FALSE, extents, + src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y); if (unlikely (src == NULL)) { @@ -2011,10 +2009,10 @@ _clip_and_composite_with_mask (cairo_clip_t *clip, pixman_image_composite32 (_pixman_operator (op), src, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, + extents->bounded.x + src_x, extents->bounded.y + src_y, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); pixman_image_unref (src); } @@ -2027,13 +2025,12 @@ _clip_and_composite_with_mask (cairo_clip_t *clip, * in two pieces and combine them together. */ static cairo_status_t -_clip_and_composite_combine (cairo_clip_t *clip, +_clip_and_composite_combine (cairo_composite_rectangles_t *extents, cairo_operator_t op, const cairo_pattern_t *src, image_draw_func_t draw_func, void *draw_closure, - cairo_image_surface_t *dst, - const cairo_rectangle_int_t *extents) + cairo_image_surface_t *dst) { pixman_image_t *tmp; cairo_surface_t *clip_surface; @@ -2041,7 +2038,8 @@ _clip_and_composite_combine (cairo_clip_t *clip, cairo_status_t status; tmp = pixman_image_create_bits (dst->pixman_format, - extents->width, extents->height, + extents->bounded.width, + extents->bounded.height, NULL, 0); if (unlikely (tmp == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -2050,31 +2048,34 @@ _clip_and_composite_combine (cairo_clip_t *clip, status = (*draw_func) (draw_closure, tmp, dst->pixman_format, CAIRO_OPERATOR_ADD, NULL, - extents->x, extents->y, + extents->bounded.x, extents->bounded.y, &dst->base.device_transform, - extents, NULL); + extents); } else { /* Initialize the temporary surface from the destination surface */ if (! dst->base.is_clear) { pixman_image_composite32 (PIXMAN_OP_SRC, dst->pixman_image, NULL, tmp, - extents->x, extents->y, + extents->bounded.x, + extents->bounded.y, 0, 0, 0, 0, - extents->width, extents->height); + extents->bounded.width, + extents->bounded.height); } status = (*draw_func) (draw_closure, tmp, dst->pixman_format, op, src, - extents->x, extents->y, + extents->bounded.x, extents->bounded.y, &dst->base.device_transform, - extents, NULL); + extents); } if (unlikely (status)) goto CLEANUP_SURFACE; - clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y); + clip_surface = _cairo_clip_get_surface (extents->clip, &dst->base, + &clip_x, &clip_y); if (unlikely (clip_surface->status)) goto CLEANUP_SURFACE; @@ -2085,20 +2086,20 @@ _clip_and_composite_combine (cairo_clip_t *clip, ((cairo_image_surface_t *) clip_surface)->pixman_image, dst->pixman_image, 0, 0, - extents->x - clip_x, - extents->y - clip_y, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x - clip_x, + extents->bounded.y - clip_y, + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); #else /* Punch the clip out of the destination */ pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, ((cairo_image_surface_t *) clip_surface)->pixman_image, NULL, dst->pixman_image, - extents->x - clip_x, - extents->y - clip_y, + extents->bounded.x - clip_x, + extents->bounded.y - clip_y, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); /* Now add the two results together */ pixman_image_composite32 (PIXMAN_OP_ADD, @@ -2106,10 +2107,10 @@ _clip_and_composite_combine (cairo_clip_t *clip, ((cairo_image_surface_t *) clip_surface)->pixman_image, dst->pixman_image, 0, 0, - extents->x - clip_x, - extents->y - clip_y, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x - clip_x, + extents->bounded.y - clip_y, + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); #endif } else { pixman_image_composite32 (PIXMAN_OP_SRC, @@ -2117,10 +2118,10 @@ _clip_and_composite_combine (cairo_clip_t *clip, ((cairo_image_surface_t *) clip_surface)->pixman_image, dst->pixman_image, 0, 0, - extents->x - clip_x, - extents->y - clip_y, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x - clip_x, + extents->bounded.y - clip_y, + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); } CLEANUP_SURFACE: @@ -2133,12 +2134,11 @@ _clip_and_composite_combine (cairo_clip_t *clip, * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip)) */ static cairo_status_t -_clip_and_composite_source (cairo_clip_t *clip, +_clip_and_composite_source (cairo_composite_rectangles_t *extents, const cairo_pattern_t *pattern, image_draw_func_t draw_func, void *draw_closure, - cairo_image_surface_t *dst, - const cairo_rectangle_int_t *extents) + cairo_image_surface_t *dst) { pixman_image_t *mask, *src; int src_x, src_y; @@ -2149,24 +2149,25 @@ _clip_and_composite_source (cairo_clip_t *clip, status = draw_func (draw_closure, dst->pixman_image, dst->pixman_format, CAIRO_OPERATOR_SOURCE, NULL, - extents->x, extents->y, + extents->bounded.x, extents->bounded.y, &dst->base.device_transform, - extents, NULL); + extents); if (unlikely (status)) return status; - if (! _cairo_clip_is_region (clip)) - status = _cairo_clip_combine_with_surface (clip, &dst->base, 0, 0); + if (! _cairo_clip_is_region (extents->clip)) + status = _cairo_clip_combine_with_surface (extents->clip, + &dst->base, 0, 0); return status; } /* Create a surface that is mask IN clip */ - mask = _create_composite_mask_pattern (clip, draw_func, draw_closure, dst, extents); + mask = _create_composite_mask_pattern (extents, draw_func, draw_closure, dst); if (unlikely (mask == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - src = _pixman_image_for_pattern (pattern, FALSE, extents, + src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y); if (unlikely (src == NULL)) { @@ -2178,33 +2179,33 @@ _clip_and_composite_source (cairo_clip_t *clip, #if PIXMAN_HAS_OP_LERP pixman_image_composite32 (PIXMAN_OP_LERP, src, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, + extents->bounded.x + src_x, extents->bounded.y + src_y, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); #else /* Compute dest' = dest OUT (mask IN clip) */ pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, mask, NULL, dst->pixman_image, 0, 0, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); /* Now compute (src IN (mask IN clip)) ADD dest' */ pixman_image_composite32 (PIXMAN_OP_ADD, src, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, + extents->bounded.x + src_x, extents->bounded.y + src_y, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); #endif } else { pixman_image_composite32 (PIXMAN_OP_SRC, src, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, + extents->bounded.x + src_x, extents->bounded.y + src_y, 0, 0, - extents->x, extents->y, - extents->width, extents->height); + extents->bounded.x, extents->bounded.y, + extents->bounded.width, extents->bounded.height); } pixman_image_unref (src); @@ -2274,9 +2275,8 @@ _clip_and_composite (cairo_image_surface_t *dst, } if (op == CAIRO_OPERATOR_SOURCE) { - status = _clip_and_composite_source (extents->clip, src, - draw_func, draw_closure, - dst, &extents->bounded); + status = _clip_and_composite_source (extents, src, + draw_func, draw_closure, dst); } else { if (op == CAIRO_OPERATOR_CLEAR) { src = NULL; @@ -2285,13 +2285,13 @@ _clip_and_composite (cairo_image_surface_t *dst, if (need_clip & NEED_CLIP_SURFACE) { if (extents->is_bounded) { - status = _clip_and_composite_with_mask (extents->clip, op, src, + status = _clip_and_composite_with_mask (extents, op, src, draw_func, draw_closure, - dst, &extents->bounded); + dst); } else { - status = _clip_and_composite_combine (extents->clip, op, src, + status = _clip_and_composite_combine (extents, op, src, draw_func, draw_closure, - dst, &extents->bounded); + dst); } } else { status = draw_func (draw_closure, @@ -2299,8 +2299,7 @@ _clip_and_composite (cairo_image_surface_t *dst, op, src, 0, 0, &dst->base.device_transform, - &extents->bounded, - clip_region); + extents); } } @@ -2416,9 +2415,8 @@ _composite_traps (void *closure, const cairo_pattern_t *pattern, int dst_x, int dst_y, - cairo_matrix_t *dst_device_transform, - const cairo_rectangle_int_t *extents, - cairo_region_t *clip_region) + cairo_matrix_t *dst_device_transform, + const cairo_composite_rectangles_t *extents) { composite_traps_info_t *info = closure; pixman_image_t *src, *mask; @@ -2442,26 +2440,28 @@ _composite_traps (void *closure, return CAIRO_STATUS_SUCCESS; } - src = _pixman_image_for_pattern (pattern, FALSE, extents, + src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, dst_device_transform, &src_x, &src_y); if (unlikely (src == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - mask = pixman_image_create_bits (format, extents->width, extents->height, + mask = pixman_image_create_bits (format, + extents->bounded.width, + extents->bounded.height, NULL, 0); if (unlikely (mask == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_SOURCE; } - _pixman_image_add_traps (mask, extents->x, extents->y, info); + _pixman_image_add_traps (mask, extents->bounded.x, extents->bounded.y, info); pixman_image_composite32 (_pixman_operator (op), src, mask, dst, - extents->x + src_x, extents->y + src_y, + extents->bounded.x + src_x, extents->bounded.y + src_y, 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); + extents->bounded.x - dst_x, extents->bounded.y - dst_y, + extents->bounded.width, extents->bounded.height); pixman_image_unref (mask); @@ -3308,8 +3308,7 @@ _composite_mask (void *closure, int dst_x, int dst_y, cairo_matrix_t *dst_device_transform, - const cairo_rectangle_int_t *extents, - cairo_region_t *clip_region) + const cairo_composite_rectangles_t *extents) { const cairo_pattern_t *mask_pattern = closure; pixman_image_t *src, *mask = NULL; @@ -3317,13 +3316,13 @@ _composite_mask (void *closure, int mask_x = 0, mask_y = 0; if (src_pattern != NULL) { - src = _pixman_image_for_pattern (src_pattern, FALSE, extents, + src = _pixman_image_for_pattern (src_pattern, FALSE, &extents->bounded, dst_device_transform, &src_x, &src_y); if (unlikely (src == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, + mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents->bounded, dst_device_transform, &mask_x, &mask_y); if (unlikely (mask == NULL)) { @@ -3334,7 +3333,7 @@ _composite_mask (void *closure, if (mask_pattern->has_component_alpha) pixman_image_set_component_alpha (mask, TRUE); } else { - src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, + src = _pixman_image_for_pattern (mask_pattern, FALSE, &extents->bounded, dst_device_transform, &src_x, &src_y); if (unlikely (src == NULL)) @@ -3342,10 +3341,10 @@ _composite_mask (void *closure, } pixman_image_composite32 (_pixman_operator (op), src, mask, dst, - extents->x + src_x, extents->y + src_y, - extents->x + mask_x, extents->y + mask_y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); + extents->bounded.x + src_x, extents->bounded.y + src_y, + extents->bounded.x + mask_x, extents->bounded.y + mask_y, + extents->bounded.x - dst_x, extents->bounded.y - dst_y, + extents->bounded.width, extents->bounded.height); if (mask != NULL) pixman_image_unref (mask); @@ -3354,6 +3353,151 @@ _composite_mask (void *closure, return CAIRO_STATUS_SUCCESS; } +static void do_unaligned_row(void (*blt)(void *closure, + int16_t x, int16_t y, + int16_t w, int16_t h, + uint16_t coverage), + void *closure, + const cairo_box_t *b, + int tx, int y, int h, + uint16_t coverage) +{ + int x1 = _cairo_fixed_integer_part (b->p1.x) - tx; + int x2 = _cairo_fixed_integer_part (b->p2.x) - tx; + if (x2 > x1) { + if (! _cairo_fixed_is_integer (b->p1.x)) { + blt(closure, x1, y, 1, h, + coverage * (256 - _cairo_fixed_fractional_part (b->p1.x))); + x1++; + } + + if (x2 > x1) + blt(closure, x1, y, x2-x1, h, (coverage << 8) - (coverage >> 8)); + + if (! _cairo_fixed_is_integer (b->p2.x)) + blt(closure, x2, y, 1, h, + coverage * _cairo_fixed_fractional_part (b->p2.x)); + } else + blt(closure, x1, y, 1, h, + coverage * (b->p2.x - b->p1.x)); +} + +static void do_unaligned_box(void (*blt)(void *closure, + int16_t x, int16_t y, + int16_t w, int16_t h, + uint16_t coverage), + void *closure, + const cairo_box_t *b, int tx, int ty) +{ + int y1 = _cairo_fixed_integer_part (b->p1.y) - ty; + int y2 = _cairo_fixed_integer_part (b->p2.y) - ty; + if (y2 > y1) { + if (! _cairo_fixed_is_integer (b->p1.y)) { + do_unaligned_row(blt, closure, b, tx, y1, 1, + 256 - _cairo_fixed_fractional_part (b->p1.y)); + y1++; + } + + if (y2 > y1) + do_unaligned_row(blt, closure, b, tx, y1, y2-y1, 256); + + if (! _cairo_fixed_is_integer (b->p2.y)) + do_unaligned_row(blt, closure, b, tx, y2, 1, + _cairo_fixed_fractional_part (b->p2.y)); + } else + do_unaligned_row(blt, closure, b, tx, y1, 1, + b->p2.y - b->p1.y); +} + +struct composite_opacity_info { + uint8_t op; + pixman_image_t *dst; + pixman_image_t *src; + int src_x, src_y; + double opacity; +}; + +static void composite_opacity(void *closure, + int16_t x, int16_t y, + int16_t w, int16_t h, + uint16_t coverage) +{ + struct composite_opacity_info *info = closure; + pixman_color_t color; + pixman_image_t *mask; + + color.red = 0; + color.green = 0; + color.blue = 0; + color.alpha = coverage * info->opacity; + + mask = pixman_image_create_solid_fill (&color); + if (mask == NULL) + return; + + if (info->src) { + pixman_image_composite32 (info->op, + info->src, + mask, + info->dst, + x + info->src_x, y + info->src_y, + 0, 0, + x, y, + w, h); + } else { + pixman_image_composite32 (info->op, + mask, + NULL, + info->dst, + 0, 0, + 0, 0, + x, y, + w, h); + } + + pixman_image_unref (mask); +} + +static cairo_status_t +_composite_opacity_boxes (void *closure, + pixman_image_t *dst, + pixman_format_code_t dst_format, + cairo_operator_t op, + const cairo_pattern_t *src_pattern, + int dst_x, + int dst_y, + cairo_matrix_t *dst_device_transform, + const cairo_composite_rectangles_t *extents) +{ + const cairo_solid_pattern_t *mask_pattern = closure; + struct composite_opacity_info info; + int i; + + info.op = _pixman_operator (op); + info.dst = dst; + + if (src_pattern != NULL) { + info.src = _pixman_image_for_pattern (src_pattern, TRUE, &extents->bounded, + dst_device_transform, + &info.src_x, &info.src_y); + if (unlikely (info.src == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } else + info.src = NULL; + + info.opacity = mask_pattern->color.alpha; + + /* XXX for lots of boxes create a clip region for the fully opaque areas */ + for (i = 0; i < extents->clip->num_boxes; i++) + do_unaligned_box(composite_opacity, &info, + &extents->clip->boxes[i], dst_x, dst_y); + if (info.src) + pixman_image_unref (info.src); + + return CAIRO_STATUS_SUCCESS; +} + + static cairo_int_status_t _cairo_image_surface_mask (void *abstract_surface, cairo_operator_t op, @@ -3371,9 +3515,18 @@ _cairo_image_surface_mask (void *abstract_surface, if (unlikely (status)) return status; - status = _clip_and_composite (surface, op, source, - _composite_mask, (void *) mask, - &extents, need_bounded_clip (&extents)); + if (mask->type == CAIRO_PATTERN_TYPE_SOLID && + extents.clip->path == NULL && + ! _cairo_clip_is_region (extents.clip)) + { + status = _clip_and_composite (surface, op, source, + _composite_opacity_boxes, (void *) mask, + &extents, need_bounded_clip (&extents)); + } else { + status = _clip_and_composite (surface, op, source, + _composite_mask, (void *) mask, + &extents, need_bounded_clip (&extents)); + } _cairo_composite_rectangles_fini (&extents); @@ -3396,8 +3549,7 @@ _composite_spans (void *closure, int dst_x, int dst_y, cairo_matrix_t *dst_device_transform, - const cairo_rectangle_int_t *extents, - cairo_region_t *clip_region) + const cairo_composite_rectangles_t *extents) { uint8_t mask_buf[CAIRO_STACK_BUFFER_SIZE]; composite_spans_info_t *info = closure; @@ -3409,19 +3561,20 @@ _composite_spans (void *closure, cairo_scan_converter_t *converter; #endif pixman_image_t *mask; + const cairo_rectangle_int_t *r = &extents->bounded; cairo_status_t status; #if USE_BOTOR_SCAN_CONVERTER - box.p1.x = _cairo_fixed_from_int (extents->x); - box.p1.y = _cairo_fixed_from_int (extents->y); - box.p2.x = _cairo_fixed_from_int (extents->x + extents->width); - box.p2.y = _cairo_fixed_from_int (extents->y + extents->height); + box.p1.x = _cairo_fixed_from_int (r->x); + box.p1.y = _cairo_fixed_from_int (r->y); + box.p2.x = _cairo_fixed_from_int (r->x + r->width); + box.p2.y = _cairo_fixed_from_int (r->y + r->height); _cairo_botor_scan_converter_init (&converter, &box, info->fill_rule); status = converter.base.add_polygon (&converter.base, info->polygon); #else - converter = _cairo_tor_scan_converter_create (extents->x, extents->y, - extents->x + extents->width, - extents->y + extents->height, + converter = _cairo_tor_scan_converter_create (r->x, r->y, + r->x + r->width, + r->y + r->height, info->fill_rule); status = converter->add_polygon (converter, info->polygon); #endif @@ -3440,17 +3593,17 @@ _composite_spans (void *closure, } else { - int stride = CAIRO_STRIDE_FOR_WIDTH_BPP (extents->width, 8); + int stride = CAIRO_STRIDE_FOR_WIDTH_BPP (r->width, 8); uint8_t *data = mask_buf; - if (extents->height * stride <= (int) sizeof (mask_buf)) - memset (data, 0, extents->height * stride); + if (r->height * stride <= (int) sizeof (mask_buf)) + memset (data, 0, r->height * stride); else data = NULL, stride = 0; mask = pixman_image_create_bits (PIXMAN_a8, - extents->width, - extents->height, + r->width, + r->height, (uint32_t *) data, stride); if (unlikely (mask == NULL)) { @@ -3463,7 +3616,7 @@ _composite_spans (void *closure, renderer.mask_stride = pixman_image_get_stride (mask); renderer.mask_data = (uint8_t *) pixman_image_get_data (mask); if (dst != NULL) - renderer.mask_data -= extents->y * renderer.mask_stride + extents->x; + renderer.mask_data -= r->y * renderer.mask_stride + r->x; else renderer.mask_data -= dst_y * renderer.mask_stride + dst_x; @@ -3479,7 +3632,7 @@ _composite_spans (void *closure, pixman_image_t *src; int src_x, src_y; - src = _pixman_image_for_pattern (pattern, FALSE, extents, + src = _pixman_image_for_pattern (pattern, FALSE, r, dst_device_transform, &src_x, &src_y); if (unlikely (src == NULL)) { @@ -3488,10 +3641,10 @@ _composite_spans (void *closure, } pixman_image_composite32 (_pixman_operator (op), src, mask, dst, - extents->x + src_x, extents->y + src_y, + r->x + src_x, r->y + src_y, 0, 0, /* mask.x, mask.y */ - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); + r->x - dst_x, r->y - dst_y, + r->width, r->height); pixman_image_unref (src); } @@ -3703,8 +3856,7 @@ _composite_glyphs_via_mask (void *closure, int dst_x, int dst_y, cairo_matrix_t *dst_device_transform, - const cairo_rectangle_int_t *extents, - cairo_region_t *clip_region) + const cairo_composite_rectangles_t *extents) { composite_glyphs_info_t *info = closure; cairo_scaled_font_t *font = info->font; @@ -3718,7 +3870,7 @@ _composite_glyphs_via_mask (void *closure, int src_x, src_y; int i; - src = _pixman_image_for_pattern (pattern, FALSE, extents, + src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, dst_device_transform, &src_x, &src_y); if (unlikely (src == NULL)) @@ -3754,7 +3906,8 @@ _composite_glyphs_via_mask (void *closure, if (mask == NULL) { mask_format = glyph_surface->pixman_format; mask = pixman_image_create_bits (mask_format, - extents->width, extents->height, + extents->bounded.width, + extents->bounded.height, NULL, 0); if (unlikely (mask == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -3775,7 +3928,8 @@ _composite_glyphs_via_mask (void *closure, mask_format = glyph_surface->pixman_format; new_mask = pixman_image_create_bits (mask_format, - extents->width, extents->height, + extents->bounded.width, + extents->bounded.height, NULL, 0); if (unlikely (new_mask == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -3785,7 +3939,8 @@ _composite_glyphs_via_mask (void *closure, pixman_image_composite32 (PIXMAN_OP_SRC, white, mask, new_mask, 0, 0, 0, 0, 0, 0, - extents->width, extents->height); + extents->bounded.width, + extents->bounded.height); pixman_image_unref (mask); mask = new_mask; @@ -3803,14 +3958,14 @@ _composite_glyphs_via_mask (void *closure, pixman_image_composite32 (PIXMAN_OP_ADD, glyph_surface->pixman_image, NULL, mask, 0, 0, 0, 0, - x - extents->x, y - extents->y, + x - extents->bounded.x, y - extents->bounded.y, glyph_surface->width, glyph_surface->height); } else { pixman_image_composite32 (PIXMAN_OP_ADD, white, glyph_surface->pixman_image, mask, 0, 0, 0, 0, - x - extents->x, y - extents->y, + x - extents->bounded.x, y - extents->bounded.y, glyph_surface->width, glyph_surface->height); } @@ -3818,10 +3973,10 @@ _composite_glyphs_via_mask (void *closure, pixman_image_composite32 (_pixman_operator (op), src, mask, dst, - extents->x + src_x, extents->y + src_y, + extents->bounded.x + src_x, extents->bounded.y + src_y, 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); + extents->bounded.x - dst_x, extents->bounded.y - dst_y, + extents->bounded.width, extents->bounded.height); CLEANUP: _cairo_scaled_font_thaw_cache (font); @@ -3842,8 +3997,7 @@ _composite_glyphs (void *closure, int dst_x, int dst_y, cairo_matrix_t *dst_device_transform, - const cairo_rectangle_int_t *extents, - cairo_region_t *clip_region) + const cairo_composite_rectangles_t *extents) { composite_glyphs_info_t *info = closure; cairo_scaled_glyph_t *glyph_cache[64]; @@ -3854,7 +4008,7 @@ _composite_glyphs (void *closure, int i; if (pattern != NULL) { - src = _pixman_image_for_pattern (pattern, FALSE, extents, + src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, dst_device_transform, &src_x, &src_y); src_x -= dst_x; @@ -3902,18 +4056,18 @@ _composite_glyphs (void *closure, glyph_surface->base.device_transform.y0); x1 = x; - if (x1 < extents->x) - x1 = extents->x; + if (x1 < extents->bounded.x) + x1 = extents->bounded.x; x2 = x + glyph_surface->width; - if (x2 > extents->x + extents->width) - x2 = extents->x + extents->width; + if (x2 > extents->bounded.x + extents->bounded.width) + x2 = extents->bounded.x + extents->bounded.width; y1 = y; - if (y1 < extents->y) - y1 = extents->y; + if (y1 < extents->bounded.y) + y1 = extents->bounded.y; y2 = y + glyph_surface->height; - if (y2 > extents->y + extents->height) - y2 = extents->y + extents->height; + if (y2 > extents->bounded.y + extents->bounded.height) + y2 = extents->bounded.y + extents->bounded.height; pixman_image_composite32 (pixman_op, src, glyph_surface->pixman_image, dst, @@ -4295,8 +4449,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, &source_pattern.base, 0, 0, &dst->base.device_transform, - &extents.bounded, - clip_region); + &extents); if (status == CAIRO_STATUS_SUCCESS && ! extents.is_bounded) status = _cairo_image_surface_fixup_unbounded (dst, &extents, NULL); |