[cairo-commit] src/cairo-image-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jun 11 14:04:21 PDT 2010
src/cairo-image-surface.c | 40 ++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 16 deletions(-)
New commits:
commit 9b6617a3b3b31d52e6646400b16ec56c754bfebd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jun 11 21:58:34 2010 +0100
image: Apply component alpha to composite masks.
If we need to pattern requires component alpha, then we must take a
copy of the image and enable component alpha for pixman.
Fixes test/text-antialias-subpixel on xlib-fallback -- i.e. we will
finally render subpixel antialiased text on ancient XServers.
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 4e2388c..06c63c1 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1319,6 +1319,7 @@ _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
static pixman_image_t *
_pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
+ cairo_bool_t is_mask,
const cairo_rectangle_int_t *extents,
int *ix, int *iy)
{
@@ -1335,7 +1336,10 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
filter = sampled_area (pattern, extents, &sample);
pixman_image = NULL;
- if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
+ if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE &&
+ (! is_mask || ! pattern->base.has_component_alpha ||
+ (pattern->surface->content & CAIRO_CONTENT_COLOR) == 0))
+ {
cairo_image_surface_t *source = (cairo_image_surface_t *) pattern->surface;
cairo_surface_type_t type;
@@ -1588,11 +1592,15 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
pixman_image_set_repeat (pixman_image, pixman_repeat);
}
+ if (pattern->base.has_component_alpha)
+ pixman_image_set_component_alpha (pixman_image, TRUE);
+
return pixman_image;
}
static pixman_image_t *
_pixman_image_for_pattern (const cairo_pattern_t *pattern,
+ cairo_bool_t is_mask,
const cairo_rectangle_int_t *extents,
int *tx, int *ty)
{
@@ -1614,7 +1622,7 @@ _pixman_image_for_pattern (const cairo_pattern_t *pattern,
case CAIRO_PATTERN_TYPE_SURFACE:
return _pixman_image_for_surface ((const cairo_surface_pattern_t *) pattern,
- extents, tx, ty);
+ is_mask, extents, tx, ty);
}
}
@@ -1979,7 +1987,7 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
pixman_image_t *src;
int src_x, src_y;
- src = _pixman_image_for_pattern (pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL)) {
pixman_image_unref (mask);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2141,7 +2149,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
if (unlikely (mask == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- src = _pixman_image_for_pattern (pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL)) {
pixman_image_unref (mask);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2404,7 +2412,7 @@ _composite_traps (void *closure,
return CAIRO_STATUS_SUCCESS;
}
- src = _pixman_image_for_pattern (pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2805,7 +2813,7 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
if (unlikely (status))
goto CLEANUP;
- src = _pixman_image_for_pattern (pattern, &extents->bounded, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &src_x, &src_y);
if (unlikely (src == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
@@ -2923,7 +2931,7 @@ _composite_boxes (cairo_image_surface_t *dst,
}
if (pattern != NULL) {
- src = _pixman_image_for_pattern (pattern, &extents->bounded, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
@@ -3249,11 +3257,11 @@ _composite_mask (void *closure,
int mask_x = 0, mask_y = 0;
if (src_pattern != NULL) {
- src = _pixman_image_for_pattern (src_pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (src_pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- mask = _pixman_image_for_pattern (mask_pattern, extents, &mask_x, &mask_y);
+ mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, &mask_x, &mask_y);
if (unlikely (mask == NULL)) {
pixman_image_unref (src);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3262,7 +3270,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, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -3416,7 +3424,7 @@ _composite_spans (void *closure,
pixman_image_t *src;
int src_x, src_y;
- src = _pixman_image_for_pattern (pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_RENDERER;
@@ -3722,7 +3730,7 @@ _composite_glyphs_via_mask (void *closure,
int src_x, src_y;
int i;
- src = _pixman_image_for_pattern (pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3855,7 +3863,7 @@ _composite_glyphs (void *closure,
int i;
if (pattern != NULL) {
- src = _pixman_image_for_pattern (pattern, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
src_x -= dst_x;
src_y -= dst_y;
} else {
@@ -4104,7 +4112,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
extents.is_bounded = _cairo_operator_bounded_by_either (op);
- src = _pixman_image_for_pattern (src_pattern, &extents.source, &src_offset_x, &src_offset_y);
+ src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &src_offset_x, &src_offset_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4113,7 +4121,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
pixman_image_t *mask;
int mask_offset_x, mask_offset_y;
- mask = _pixman_image_for_pattern (mask_pattern, &extents.mask, &mask_offset_x, &mask_offset_y);
+ mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &mask_offset_x, &mask_offset_y);
if (unlikely (mask == NULL)) {
pixman_image_unref (src);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4382,7 +4390,7 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
return status;
}
- src = _pixman_image_for_pattern (renderer->pattern, &rects->bounded, &src_x, &src_y);
+ src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &src_x, &src_y);
if (src == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
More information about the cairo-commit
mailing list