[cairo-commit] cairo/src cairo_pattern.c, 1.21, 1.22 cairoint.h,
1.97, 1.98
Carl Worth
commit at pdx.freedesktop.org
Fri Feb 25 12:52:51 PST 2005
Committed by: cworth
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv6785/src
Modified Files:
cairo_pattern.c cairoint.h
Log Message:
* src/cairo_pattern.c (_cairo_pattern_shader_init): Don't put an
off-by-one n_stops into cairo_shader_op_t.
(_cairo_shader_op_find_color_stops): Put search for two color
stops containing a given offset into its own function. Handle the
case of before first and after last stop by returning the nearest
stop twice.
(_cairo_pattern_calc_color_at_pixel): Handle case of no color
stops by returning a transparent pixel.
Index: cairo_pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pattern.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- cairo_pattern.c 24 Feb 2005 22:06:03 -0000 1.21
+++ cairo_pattern.c 25 Feb 2005 20:52:47 -0000 1.22
@@ -428,9 +428,7 @@
cairo_shader_op_t *op)
{
op->stops = pattern->stops;
- op->n_stops = pattern->n_stops - 1;
- op->min_offset = pattern->stops[0].offset;
- op->max_offset = pattern->stops[op->n_stops].offset;
+ op->n_stops = pattern->n_stops;
op->extend = pattern->extend;
switch (pattern->filter) {
@@ -449,12 +447,52 @@
}
}
+/* Find two color stops bounding the given offset. If the given offset
+ * is before the first or after the last stop offset, the nearest
+ * offset is returned twice.
+ */
+static void
+_cairo_shader_op_find_color_stops (cairo_shader_op_t *op,
+ cairo_fixed_t offset,
+ cairo_color_stop_t *stops[2])
+{
+ int i;
+
+ /* Before first stop. */
+ if (offset <= op->stops[0].offset) {
+ stops[0] = &op->stops[0];
+ stops[1] = &op->stops[0];
+ return;
+ }
+
+ /* Between two stops. */
+ for (i = 0; i < op->n_stops - 1; i++) {
+ if (offset <= op->stops[i + 1].offset) {
+ stops[0] = &op->stops[i];
+ stops[1] = &op->stops[i + 1];
+ return;
+ }
+ }
+
+ /* After last stop. */
+ stops[0] = &op->stops[op->n_stops - 1];
+ stops[1] = &op->stops[op->n_stops - 1];
+}
+
void
_cairo_pattern_calc_color_at_pixel (cairo_shader_op_t *op,
cairo_fixed_t factor,
int *pixel)
{
- int i;
+ cairo_color_stop_t *stops[2];
+
+ /* A gradient with no color stops is just transparent. (It'd be
+ smart to catch this no-op much higher in the stack too.)
+ */
+ if (op->n_stops == 0) {
+ *pixel = 0;
+ return;
+ }
switch (op->extend) {
case CAIRO_EXTEND_REPEAT:
@@ -472,35 +510,26 @@
break;
}
- if (factor < op->min_offset)
- factor = op->min_offset;
- else if (factor > op->max_offset)
- factor = op->max_offset;
-
- for (i = 0; i < op->n_stops; i++) {
- if (factor <= op->stops[i + 1].offset) {
-
- /* take offset as new 0 of coordinate system */
- factor -= op->stops[i].offset;
-
- /* difference between two offsets == 0, abrubt change */
- if (op->stops[i + 1].scale)
- factor = ((cairo_fixed_48_16_t) factor << 16) /
- op->stops[i + 1].scale;
+ _cairo_shader_op_find_color_stops (op, factor, stops);
+
+ /* take offset as new 0 of coordinate system */
+ factor -= stops[0]->offset;
- op->shader_function (op->stops[i].color_char,
- op->stops[i + 1].color_char,
- factor, pixel);
+ /* difference between two offsets == 0, abrubt change */
+ if (stops[1]->scale)
+ factor = ((cairo_fixed_48_16_t) factor << 16) /
+ stops[1]->scale;
+
+ op->shader_function (stops[0]->color_char,
+ stops[1]->color_char,
+ factor, pixel);
- /* multiply alpha */
- if (((unsigned char) (*pixel >> 24)) != 0xff) {
- *pixel = (*pixel & 0xff000000) |
- (MULTIPLY_COLORCOMP (*pixel >> 16, *pixel >> 24) << 16) |
- (MULTIPLY_COLORCOMP (*pixel >> 8, *pixel >> 24) << 8) |
- (MULTIPLY_COLORCOMP (*pixel >> 0, *pixel >> 24) << 0);
- }
- break;
- }
+ /* multiply alpha */
+ if (((unsigned char) (*pixel >> 24)) != 0xff) {
+ *pixel = (*pixel & 0xff000000) |
+ (MULTIPLY_COLORCOMP (*pixel >> 16, *pixel >> 24) << 16) |
+ (MULTIPLY_COLORCOMP (*pixel >> 8, *pixel >> 24) << 8) |
+ (MULTIPLY_COLORCOMP (*pixel >> 0, *pixel >> 24) << 0);
}
}
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- cairoint.h 24 Feb 2005 20:28:51 -0000 1.97
+++ cairoint.h 25 Feb 2005 20:52:47 -0000 1.98
@@ -743,8 +743,6 @@
typedef struct _cairo_shader_op {
cairo_color_stop_t *stops;
int n_stops;
- cairo_fixed_t min_offset;
- cairo_fixed_t max_offset;
cairo_extend_t extend;
cairo_shader_function_t shader_function;
} cairo_shader_op_t;
More information about the cairo-commit
mailing list