[PATCH 5/5] xlib: fix server gradients

Thomas Jaeger ThJaeger at gmail.com
Thu Feb 26 00:33:29 PST 2009


---
 src/cairo-xlib-surface.c |   47 +++++++++++++++++++++++++--------------------
 1 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index e24972e..45e7566 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1762,41 +1762,47 @@ _cairo_xlib_pattern_acquire_surface (const cairo_pattern_t	*pattern,
 
 	for (i = 0; i < gradient->n_stops; i++)
 	{
-	    stops[i] = gradient->stops[i].offset;
+	    stops[i] = XDoubleToFixed(gradient->stops[i].offset);
 
-	    colors[i].red   = gradient->stops[i].color.red;
-	    colors[i].green = gradient->stops[i].color.green;
-	    colors[i].blue  = gradient->stops[i].color.blue;
-	    colors[i].alpha = gradient->stops[i].color.alpha;
+	    colors[i].red   = gradient->stops[i].color.red_short;
+	    colors[i].green = gradient->stops[i].color.green_short;
+	    colors[i].blue  = gradient->stops[i].color.blue_short;
+	    colors[i].alpha = gradient->stops[i].color.alpha_short;
 	}
 
-	/* For some weird reason the X server is sometimes getting
-	   CreateGradient requests with bad length. So far I've only seen
-	   XRenderCreateLinearGradient request with 4 stops sometime end up
-	   with length field matching 0 stops at the server side. I've looked
-	   at the libXrender code and I can't see anything that could
-	   cause this behavior. However, for some reason having a XSync call
-	   here seems to avoid the issue so I'll keep it here until it's
-	   solved. */
-	XSync (dst->dpy, False);
+	attributes->matrix   = pattern->matrix;
 
 	if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
 	{
-	    cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
+	    cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
+	    pixman_point_fixed_t p1, p2;
+	    XLinearGradient grad;
+
+	    _cairo_pattern_scale_linear(linear, &attributes->matrix, &p1, &p2);
+	    grad.p1.x = p1.x;
+	    grad.p1.y = p1.y;
+	    grad.p2.x = p2.x;
+	    grad.p2.y = p2.y;
 
 	    picture = XRenderCreateLinearGradient (dst->dpy,
-						   (XLinearGradient *)
-						   &grad->base,
+						   &grad,
 						   stops, colors,
 						   gradient->n_stops);
 	}
 	else
 	{
-	    cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;
+	    cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern;
+	    XRadialGradient grad;
+
+	    grad.inner.x      = _cairo_fixed_to_16_16(radial->c1.x);
+	    grad.inner.y      = _cairo_fixed_to_16_16(radial->c1.y);
+	    grad.inner.radius = _cairo_fixed_to_16_16(radial->r1);
+	    grad.outer.x      = _cairo_fixed_to_16_16(radial->c2.x);
+	    grad.outer.y      = _cairo_fixed_to_16_16(radial->c2.y);
+	    grad.outer.radius = _cairo_fixed_to_16_16(radial->r2);
 
 	    picture = XRenderCreateRadialGradient (dst->dpy,
-						   (XRadialGradient *)
-						   &grad->base,
+						   &grad,
 						   stops, colors,
 						   gradient->n_stops);
 	}
@@ -1822,7 +1828,6 @@ _cairo_xlib_pattern_acquire_surface (const cairo_pattern_t	*pattern,
 
 	surface->src_picture = picture;
 
-	attributes->matrix   = pattern->matrix;
 	attributes->extend   = pattern->extend;
 	attributes->filter   = pattern->filter;
 	attributes->x_offset = 0;
-- 
1.6.3


--------------000209070203020007040404--


More information about the cairo mailing list