[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