summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-09-29 19:40:59 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-09-29 19:40:59 -0400
commit7369c0e305dd56bce9e20d66db529c4ccb38ec77 (patch)
treefd03d5ad03a98034e0ab4c37f90744c059e3a5a2
parent1e37d5f6dba7b723c4b9ef2739d08bfa886e51b1 (diff)
Linear and radial
-rw-r--r--src/cairo-pixman-surface.c91
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;