diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-09-29 19:40:59 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-09-29 19:40:59 -0400 |
commit | 7369c0e305dd56bce9e20d66db529c4ccb38ec77 (patch) | |
tree | fd03d5ad03a98034e0ab4c37f90744c059e3a5a2 | |
parent | 1e37d5f6dba7b723c4b9ef2739d08bfa886e51b1 (diff) |
Linear and radial
-rw-r--r-- | src/cairo-pixman-surface.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/cairo-pixman-surface.c b/src/cairo-pixman-surface.c index 60f3d62b..993459e2 100644 --- a/src/cairo-pixman-surface.c +++ b/src/cairo-pixman-surface.c @@ -538,6 +538,93 @@ out: return status; } +#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ + +static cairo_int_status_t +pimage_from_gradient_pattern (const cairo_gradient_pattern_t *pattern, pixman_image_t **image) +{ + pixman_gradient_stop_t *pstops; + cairo_circle_double_t extremes[2]; + pixman_point_fixed_t p1, p2; + cairo_int_status_t status; + cairo_matrix_t matrix; + unsigned int i; + + if (!(pstops = malloc (pattern->n_stops * sizeof (pixman_gradient_stop_t)))) + return CAIRO_INT_STATUS_NO_MEMORY; + + for (i = 0; i < pattern->n_stops; i++) + { + pstops[i].x = _cairo_fixed_16_16_from_double (pattern->stops[i].offset); + pstops[i].color.red = pattern->stops[i].color.red_short; + pstops[i].color.green = pattern->stops[i].color.green_short; + pstops[i].color.blue = pattern->stops[i].color.blue_short; + pstops[i].color.alpha = pattern->stops[i].color.alpha_short; + } + + _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes); + + p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); + + status = CAIRO_INT_STATUS_SUCCESS; + + if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) + { + if (!(*image = pixman_image_create_linear_gradient ( + &p1, &p2, pstops, pattern->n_stops))) + { + status = CAIRO_INT_STATUS_NO_MEMORY; + } + } + else /* CAIRO_PATTERN_TYPE_RADIAL */ + { + pixman_fixed_t r1, r2; + + r1 = _cairo_fixed_16_16_from_double (extremes[0].radius); + r2 = _cairo_fixed_16_16_from_double (extremes[1].radius); + + if (!(*image = pixman_image_create_radial_gradient ( + &p1, &p2, r1, r2, pstops, pattern->n_stops))) + { + status = CAIRO_INT_STATUS_NO_MEMORY; + } + } + + free (pstops); + + return status; +} + +static cairo_int_status_t +_pixman_image_for_mesh (const cairo_mesh_pattern_t *pattern, + pixman_image_t **image) +{ + /* FIXME: This needs width and height */ +#if 0 + pixman_image_t *image; + int width, height; + + TRACE ((stderr, "%s\n", __FUNCTION__)); + + width = extents->width; + height = extents->height; + + image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0); + if (unlikely (image == NULL)) + return NULL; + + _cairo_mesh_pattern_rasterize (pattern, + pixman_image_get_data (image), + width, height, + pixman_image_get_stride (image), + *tx, *ty); + return image; +#endif +} + static cairo_int_status_t pimage_from_pattern (const cairo_pattern_t *pattern, pixman_image_t **image) { @@ -555,6 +642,10 @@ pimage_from_pattern (const cairo_pattern_t *pattern, pixman_image_t **image) case CAIRO_PATTERN_TYPE_LINEAR: case CAIRO_PATTERN_TYPE_RADIAL: + return pimage_from_gradient_pattern ( + (cairo_gradient_pattern_t *)pattern, image); + break; + case CAIRO_PATTERN_TYPE_MESH: case CAIRO_PATTERN_TYPE_RASTER_SOURCE: break; |