[cairo] some fixes and improvements to current cvs version of
cairo
Kristian Høgsberg
krh at bitplanet.net
Fri Jan 28 17:15:05 PST 2005
David Reveman wrote:
> I've fixed the issues and attached an updated patch.
>
> It includes a fix for the _cairo_gstate_init bug. This fix adds a
> default_pattern to the cairo_gstate struct and cairo_set_rgb_color can
> use this without allocating and destroying patterns all the time, and
> cairo_gstate_init can no longer fail. What do you think?
I think it's a pretty good idea.
...
> Index: src/cairo_gstate.c
> ===================================================================
> RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
> retrieving revision 1.77
> diff -u -r1.77 cairo_gstate.c
> --- src/cairo_gstate.c 28 Jan 2005 01:21:13 -0000 1.77
> +++ src/cairo_gstate.c 28 Jan 2005 21:06:53 -0000
> @@ -93,8 +93,11 @@
>
> gstate->clip.region = NULL;
> gstate->clip.surface = NULL;
> +
> + _cairo_pattern_init_solid (&gstate->default_pattern, 0.0, 0.0, 0.0);
> + cairo_pattern_reference (&gstate->default_pattern);
> + gstate->pattern = &gstate->default_pattern;
>
> - gstate->pattern = _cairo_pattern_create_solid (0.0, 0.0, 0.0);
> gstate->alpha = 1.0;
>
> gstate->pixels_per_inch = CAIRO_GSTATE_PIXELS_PER_INCH_DEFAULT;
> @@ -146,7 +149,13 @@
> cairo_surface_reference (gstate->surface);
> cairo_surface_reference (gstate->clip.surface);
>
> - cairo_pattern_reference (gstate->pattern);
> + status = _cairo_pattern_init_copy (&gstate->default_pattern,
> + other->pattern);
> + if (status)
> + goto CLEANUP_FONT;
> +
> + cairo_pattern_reference (&gstate->default_pattern);
> + gstate->pattern = &gstate->default_pattern;
This doesn't look right, _cairo_gstate_init_copy shouldn't set the
pattern to the default pattern.
...
(cairo_gstate.c)
> @@ -2006,8 +2035,15 @@
> &device_width, &device_height);
>
> _cairo_pattern_init_for_surface (&pattern, surface);
> - _cairo_gstate_create_pattern (gstate, &pattern);
>
> + if (!_cairo_matrix_is_integer_translation (&device_to_image, &xoff, &yoff))
> + {
> + xoff = yoff = 0;
> + pattern.matrix = device_to_image;
> + }
> +
> + _cairo_pattern_set_alpha (&pattern, gstate->alpha);
> +
> pattern_extents.p1.x = _cairo_fixed_from_double (device_x);
> pattern_extents.p1.y = _cairo_fixed_from_double (device_y);
> pattern_extents.p2.x = _cairo_fixed_from_double (device_x + device_width);
> @@ -2017,27 +2053,41 @@
> if (gstate->clip.surface)
> {
> _cairo_rectangle_intersect (&extents, &gstate->clip.rect);
> -
> - /* Shortcut if empty */
> - if (_cairo_rectangle_empty (&extents)) {
> - status = CAIRO_STATUS_SUCCESS;
> - goto BAIL1;
> + if (!_cairo_rectangle_empty (&extents))
> + {
> + status = _cairo_surface_composite (gstate->operator,
> + &pattern,
> + gstate->clip.surface,
> + gstate->surface,
> + extents.x + xoff,
> + extents.y + yoff,
> + 0, 0,
> + extents.x, extents.y,
> + extents.width, extents.height);
> }
> -
> - status = _cairo_surface_composite (gstate->operator,
> - &pattern,
> - gstate->clip.surface,
> - gstate->surface,
> - extents.x, extents.y,
> - 0, 0,
> - extents.x, extents.y,
> - extents.width, extents.height);
> -
> - BAIL1:
> - ;
> + else
> + status = CAIRO_STATUS_SUCCESS;
> }
> else
> {
> + cairo_surface_t *mask = NULL;
> +
> + /* alpha as mask surface */
> + if (pattern.color.alpha != 1.0)
> + {
> + mask = _cairo_surface_create_similar_solid (gstate->surface,
> + CAIRO_FORMAT_A8, 1, 1,
> + &pattern.color);
> + if (!mask)
> + {
> + _cairo_pattern_fini (&pattern);
> + return CAIRO_STATUS_NO_MEMORY;
> + }
> +
> + pattern.color.alpha = 1.0;
> + cairo_surface_set_repeat (mask, 1);
> + }
> +
This should be removed now that it's done in the backends, right?
> Index: src/cairo_xlib_surface.c
> ===================================================================
> RCS file: /cvs/cairo/cairo/src/cairo_xlib_surface.c,v
> retrieving revision 1.42
> diff -u -r1.42 cairo_xlib_surface.c
> --- src/cairo_xlib_surface.c 28 Jan 2005 03:57:32 -0000 1.42
> +++ src/cairo_xlib_surface.c 28 Jan 2005 21:06:56 -0000
> @@ -495,18 +495,31 @@
> cairo_xlib_surface_t *mask = (cairo_xlib_surface_t *) generic_mask;
> cairo_xlib_surface_t *mask_clone = NULL;
> XGCValues gc_values;
> - int src_x_off, src_y_off, dst_x_off, dst_y_off;
> int x_offset, y_offset;
> + double alpha = pattern->color.alpha;
>
> if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
> return CAIRO_INT_STATUS_UNSUPPORTED;
>
> + if (!mask && alpha != 1.0) {
> + mask = mask_clone = (cairo_xlib_surface_t *)
> + _cairo_surface_create_similar_solid (&dst->base, CAIRO_FORMAT_A8,
> + 1, 1, &pattern->color);
> + if (!mask)
> + return CAIRO_STATUS_NO_MEMORY;
> +
> + cairo_surface_set_repeat (&mask->base, 1);
> + pattern->color.alpha = 1.0;
> + }
I guess we only want to do this for surface patterns.
cheers,
Kristian
More information about the cairo
mailing list