[cairo-commit] 2 commits - src/cairo-gl-gradient.c
Chris Wilson
ickle at kemper.freedesktop.org
Sat Aug 11 10:26:33 PDT 2012
src/cairo-gl-gradient.c | 36 +++++++++++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)
New commits:
commit adfe9b7eb67f642cda93f80cf9c97f1eaded0317
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Aug 11 17:55:49 2012 +0100
gl: Fudge gradient color generation to handle multiple stops at 0
In order to generate the correct left-hand border color, we need to
fudge the offsets of the color stops if multiple stops are defined at 0.
The reason is that pixman will generate our color ramp by using the
right-most color stop for the pixel centre, but in order to provide the
sample colour outside of the gradient we need pixel 0 to be have the
left-most color.
Reported by Henry Song.
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index 1a6f290..1c1f972 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -83,6 +83,27 @@ _cairo_gl_gradient_sample_width (unsigned int n_stops,
return (width + 7) & -8;
}
+static uint8_t premultiply(double c, double a)
+{
+ int v = c * a * 256;
+ return v - (v >> 8);
+}
+
+static uint32_t color_stop_to_pixel(const cairo_gradient_stop_t *stop)
+{
+ uint8_t a, r, g, b;
+
+ a = stop->color.alpha_short >> 8;
+ r = premultiply(stop->color.red, stop->color.alpha);
+ g = premultiply(stop->color.green, stop->color.alpha);
+ b = premultiply(stop->color.blue, stop->color.alpha);
+
+ if (_cairo_is_little_endian ())
+ return a << 24 | r << 16 | g << 8 | b << 0;
+ else
+ return a << 0 | r << 8 | g << 16 | b << 24;
+}
+
static cairo_status_t
_cairo_gl_gradient_render (const cairo_gl_context_t *ctx,
unsigned int n_stops,
@@ -156,6 +177,14 @@ _cairo_gl_gradient_render (const cairo_gl_context_t *ctx,
pixman_image_unref (gradient);
pixman_image_unref (image);
+
+ /* We need to fudge pixel 0 to hold the left-most color stop and not
+ * the neareset stop to the zeroth pixel centre in order to correctly
+ * populate the border color. For completeness, do both edges.
+ */
+ ((uint32_t*)bytes)[0] = color_stop_to_pixel(&stops[0]);
+ ((uint32_t*)bytes)[width-1] = color_stop_to_pixel(&stops[n_stops-1]);
+
return CAIRO_STATUS_SUCCESS;
}
commit b0336e9aadbbface0a059887ac62b1398bc81e7b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Aug 11 18:23:51 2012 +0100
gl: Use a wide texture ramp to emulate a linear step function
If the gradient contains a step function, we need an infinitely sharp
texture to emulate the correct output. Failing that, lets just use as
large a texture as can be reasonably handled by the hardware
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index 76920da..1a6f290 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -59,7 +59,7 @@ _cairo_gl_gradient_sample_width (unsigned int n_stops,
int ramp;
if (dx == 0)
- continue;
+ return 1024; /* we need to emulate an infinitely sharp step */
max = fabs (stops[n].color.red - stops[n-1].color.red);
@@ -80,8 +80,7 @@ _cairo_gl_gradient_sample_width (unsigned int n_stops,
width = ramp;
}
- width = (width + 7) & -8;
- return MIN (width, 1024);
+ return (width + 7) & -8;
}
static cairo_status_t
@@ -225,6 +224,8 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
tex_width = _cairo_gl_gradient_sample_width (n_stops, stops);
+ if (tex_width > ctx->max_texture_size)
+ tex_width = ctx->max_texture_size;
CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 2);
gradient->cache_entry.hash = hash;
More information about the cairo-commit
mailing list