summaryrefslogtreecommitdiff
path: root/src/cairo-image-surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-image-surface.c')
-rw-r--r--src/cairo-image-surface.c318
1 files changed, 130 insertions, 188 deletions
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index fcc832e..6082215 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -524,6 +524,11 @@ slim_hidden_def (cairo_image_surface_create_for_data);
* Get a pointer to the data of the image surface, for direct
* inspection or modification.
*
+ * A call to cairo_surface_flush() is required before accessing the
+ * pixel data to ensure that all pending drawing operations are
+ * finished. A call to cairo_surface_mark_dirty() is required after
+ * the data is modified.
+ *
* Return value: a pointer to the image data of this surface or %NULL
* if @surface is not an image surface, or if cairo_surface_finish()
* has been called.
@@ -856,25 +861,6 @@ _cairo_image_surface_unset_clip_region (cairo_image_surface_t *surface)
pixman_image_set_clip_region32 (surface->pixman_image, NULL);
}
-static double
-_pixman_nearest_sample (double d)
-{
- return ceil (d - .5);
-}
-
-static cairo_bool_t
-_nearest_sample (cairo_filter_t filter, double *tx, double *ty)
-{
- if (filter == CAIRO_FILTER_FAST || filter == CAIRO_FILTER_NEAREST) {
- *tx = _pixman_nearest_sample (*tx);
- *ty = _pixman_nearest_sample (*ty);
- } else {
- if (*tx != floor (*tx) || *ty != floor (*ty))
- return FALSE;
- }
- return fabs (*tx) < PIXMAN_MAX_INT && fabs (*ty) < PIXMAN_MAX_INT;
-}
-
#if HAS_ATOMIC_OPS
static pixman_image_t *__pixman_transparent_image;
static pixman_image_t *__pixman_black_image;
@@ -1093,9 +1079,12 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
pixman_image_t *pixman_image;
pixman_gradient_stop_t pixman_stops_static[2];
pixman_gradient_stop_t *pixman_stops = pixman_stops_static;
- cairo_matrix_t matrix = pattern->base.matrix;
- double tx, ty;
+ pixman_transform_t pixman_transform;
+ cairo_matrix_t matrix;
+ cairo_circle_double_t extremes[2];
+ pixman_point_fixed_t p1, p2;
unsigned int i;
+ cairo_status_t status;
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
pixman_stops = _cairo_malloc_ab (pattern->n_stops,
@@ -1112,66 +1101,24 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short;
}
- if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
- cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
- pixman_point_fixed_t p1, p2;
- cairo_fixed_t xdim, ydim;
-
- xdim = fabs (linear->p2.x - linear->p1.x);
- ydim = fabs (linear->p2.y - linear->p1.y);
-
- /*
- * Transform the matrix to avoid overflow when converting between
- * cairo_fixed_t and pixman_fixed_t (without incurring performance
- * loss when the transformation is unnecessary).
- *
- * XXX: Consider converting out-of-range co-ordinates and transforms.
- * Having a function to compute the required transformation to
- * "normalize" a given bounding box would be generally useful -
- * cf linear patterns, gradient patterns, surface patterns...
- */
- if (_cairo_fixed_integer_ceil (xdim) > PIXMAN_MAX_INT ||
- _cairo_fixed_integer_ceil (ydim) > PIXMAN_MAX_INT)
- {
- double sf;
+ _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes);
- if (xdim > ydim)
- sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (xdim);
- else
- sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim);
-
- p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf);
- p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf);
- p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf);
- p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf);
-
- cairo_matrix_scale (&matrix, sf, sf);
- }
- else
- {
- p1.x = _cairo_fixed_to_16_16 (linear->p1.x);
- p1.y = _cairo_fixed_to_16_16 (linear->p1.y);
- p2.x = _cairo_fixed_to_16_16 (linear->p2.x);
- p2.y = _cairo_fixed_to_16_16 (linear->p2.y);
- }
+ 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);
+ if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
pixman_image = pixman_image_create_linear_gradient (&p1, &p2,
pixman_stops,
pattern->n_stops);
} else {
- cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern;
- pixman_point_fixed_t c1, c2;
pixman_fixed_t r1, r2;
- c1.x = _cairo_fixed_to_16_16 (radial->c1.x);
- c1.y = _cairo_fixed_to_16_16 (radial->c1.y);
- r1 = _cairo_fixed_to_16_16 (radial->r1);
-
- c2.x = _cairo_fixed_to_16_16 (radial->c2.x);
- c2.y = _cairo_fixed_to_16_16 (radial->c2.y);
- r2 = _cairo_fixed_to_16_16 (radial->r2);
+ r1 = _cairo_fixed_16_16_from_double (extremes[0].radius);
+ r2 = _cairo_fixed_16_16_from_double (extremes[1].radius);
- pixman_image = pixman_image_create_radial_gradient (&c1, &c2, r1, r2,
+ pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2,
pixman_stops,
pattern->n_stops);
}
@@ -1182,49 +1129,19 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
if (unlikely (pixman_image == NULL))
return NULL;
- tx = pattern->base.matrix.x0;
- ty = pattern->base.matrix.y0;
- if (! _cairo_matrix_is_translation (&pattern->base.matrix) ||
- ! _nearest_sample (pattern->base.filter, &tx, &ty))
- {
- pixman_transform_t pixman_transform;
-
- if (tx != 0. || ty != 0.) {
- cairo_matrix_t m, inv;
- cairo_status_t status;
- double x, y;
-
- /* pixman also limits the [xy]_offset to 16 bits so evenly
- * spread the bits between the two.
- */
- inv = pattern->base.matrix;
- status = cairo_matrix_invert (&inv);
- assert (status == CAIRO_STATUS_SUCCESS);
-
- x = floor (inv.x0 / 2);
- y = floor (inv.y0 / 2);
- tx = -x;
- ty = -y;
- cairo_matrix_init_translate (&inv, x, y);
- cairo_matrix_multiply (&m, &inv, &pattern->base.matrix);
- _cairo_matrix_to_pixman_matrix (&m, &pixman_transform,
- extents->x + extents->width/2.,
- extents->y + extents->height/2.);
- } else {
- tx = ty = 0;
- _cairo_matrix_to_pixman_matrix (&pattern->base.matrix,
- &pixman_transform,
- extents->x + extents->width/2.,
- extents->y + extents->height/2.);
- }
-
- if (! pixman_image_set_transform (pixman_image, &pixman_transform)) {
+ *ix = *iy = 0;
+ status = _cairo_matrix_to_pixman_matrix_offset (&matrix, pattern->base.filter,
+ extents->x + extents->width/2.,
+ extents->y + extents->height/2.,
+ &pixman_transform, ix, iy);
+ if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
+ if (unlikely (status != CAIRO_STATUS_SUCCESS) ||
+ ! pixman_image_set_transform (pixman_image, &pixman_transform))
+ {
pixman_image_unref (pixman_image);
return NULL;
}
}
- *ix = tx;
- *iy = ty;
{
pixman_repeat_t pixman_repeat;
@@ -1322,13 +1239,15 @@ _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
case CAIRO_FORMAT_A1:
pixel = *(uint8_t *) (image->data + y * image->stride + x/8);
- return pixel & (1 << (x&7)) ? _pixman_white_image () : _pixman_transparent_image ();
+ return pixel & (1 << (x&7)) ? _pixman_black_image () : _pixman_transparent_image ();
case CAIRO_FORMAT_A8:
color.alpha = *(uint8_t *) (image->data + y * image->stride + x);
color.alpha |= color.alpha << 8;
if (color.alpha == 0)
return _pixman_transparent_image ();
+ if (color.alpha == 0xffff)
+ return _pixman_black_image ();
color.red = color.green = color.blue = 0;
return pixman_image_create_solid_fill (&color);
@@ -1368,16 +1287,17 @@ static pixman_image_t *
_pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
cairo_bool_t is_mask,
const cairo_rectangle_int_t *extents,
+ cairo_matrix_t *dst_device_transform,
int *ix, int *iy)
{
+ pixman_transform_t pixman_transform;
pixman_image_t *pixman_image;
+ cairo_matrix_t m;
cairo_rectangle_int_t sample;
cairo_extend_t extend;
cairo_filter_t filter;
- double tx, ty;
-
- tx = pattern->base.matrix.x0;
- ty = pattern->base.matrix.y0;
+ cairo_status_t status;
+ cairo_bool_t undo_src_transform = FALSE;
extend = pattern->base.extend;
filter = sampled_area (pattern, extents, &sample);
@@ -1420,12 +1340,11 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
}
/* avoid allocating a 'pattern' image if we can reuse the original */
+ *ix = *iy = 0;
if (extend == CAIRO_EXTEND_NONE &&
- _cairo_matrix_is_translation (&pattern->base.matrix) &&
- _nearest_sample (filter, &tx, &ty))
+ _cairo_matrix_is_pixman_translation (&pattern->base.matrix,
+ filter, ix, iy))
{
- *ix = tx;
- *iy = ty;
return pixman_image_ref (source->pixman_image);
}
@@ -1462,12 +1381,12 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
}
}
+ *ix = sub->extents.x;
+ *iy = sub->extents.y;
if (is_contained &&
- _cairo_matrix_is_translation (&pattern->base.matrix) &&
- _nearest_sample (filter, &tx, &ty))
+ _cairo_matrix_is_pixman_translation (&pattern->base.matrix,
+ filter, ix, iy))
{
- *ix = tx + sub->extents.x;
- *iy = ty + sub->extents.y;
return pixman_image_ref (source->pixman_image);
}
@@ -1484,13 +1403,15 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
}
}
+ *ix = *iy = 0;
+
if (pixman_image == NULL) {
struct acquire_source_cleanup *cleanup;
cairo_image_surface_t *image;
void *extra;
cairo_status_t status;
- status = _cairo_surface_acquire_source_image (pattern->surface, &image, &extra);
+ status = _cairo_surface_acquire_source_image_transformed (pattern->surface, dst_device_transform, &image, &extra);
if (unlikely (status))
return NULL;
@@ -1536,54 +1457,36 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
cleanup->image_extra = extra;
pixman_image_set_destroy_function (pixman_image,
_acquire_source_cleanup, cleanup);
+ undo_src_transform = TRUE;
}
- if (! _cairo_matrix_is_translation (&pattern->base.matrix) ||
- ! _nearest_sample (filter, &tx, &ty))
- {
- pixman_transform_t pixman_transform;
- cairo_matrix_t m;
-
- m = pattern->base.matrix;
- if (m.x0 != 0. || m.y0 != 0.) {
- cairo_matrix_t inv;
- cairo_status_t status;
- double x, y;
-
- /* pixman also limits the [xy]_offset to 16 bits so evenly
- * spread the bits between the two.
- */
- inv = m;
- status = cairo_matrix_invert (&inv);
- assert (status == CAIRO_STATUS_SUCCESS);
-
- x = floor (inv.x0 / 2);
- y = floor (inv.y0 / 2);
- tx = -x;
- ty = -y;
- cairo_matrix_init_translate (&inv, x, y);
- cairo_matrix_multiply (&m, &inv, &m);
- } else {
- tx = ty = 0;
- }
+ m = pattern->base.matrix;
+ if (undo_src_transform) {
+ cairo_matrix_t sm;
- _cairo_matrix_to_pixman_matrix (&m, &pixman_transform,
- extents->x + extents->width/2.,
- extents->y + extents->height/2.);
- if (! pixman_image_set_transform (pixman_image, &pixman_transform)) {
- pixman_image_unref (pixman_image);
- return NULL;
- }
+ cairo_matrix_init_scale (&sm,
+ dst_device_transform->xx,
+ dst_device_transform->yy);
+ cairo_matrix_multiply (&m, &m, &sm);
}
- *ix = tx;
- *iy = ty;
- if (_cairo_matrix_has_unity_scale (&pattern->base.matrix) &&
- tx == pattern->base.matrix.x0 &&
- ty == pattern->base.matrix.y0)
+ status = _cairo_matrix_to_pixman_matrix_offset (&m, filter,
+ extents->x + extents->width/2.,
+ extents->y + extents->height/2.,
+ &pixman_transform, ix, iy);
+ if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
{
+ /* If the transform is an identity, we don't need to set it
+ * and we can use any filtering, so choose the fastest one. */
pixman_image_set_filter (pixman_image, PIXMAN_FILTER_NEAREST, NULL, 0);
}
+ else if (unlikely (status != CAIRO_STATUS_SUCCESS ||
+ ! pixman_image_set_transform (pixman_image,
+ &pixman_transform)))
+ {
+ pixman_image_unref (pixman_image);
+ return NULL;
+ }
else
{
pixman_filter_t pixman_filter;
@@ -1649,6 +1552,7 @@ static pixman_image_t *
_pixman_image_for_pattern (const cairo_pattern_t *pattern,
cairo_bool_t is_mask,
const cairo_rectangle_int_t *extents,
+ cairo_matrix_t *dst_device_transform,
int *tx, int *ty)
{
*tx = *ty = 0;
@@ -1669,7 +1573,32 @@ _pixman_image_for_pattern (const cairo_pattern_t *pattern,
case CAIRO_PATTERN_TYPE_SURFACE:
return _pixman_image_for_surface ((const cairo_surface_pattern_t *) pattern,
- is_mask, extents, tx, ty);
+ is_mask, extents, dst_device_transform, tx, ty);
+
+ case CAIRO_PATTERN_TYPE_MESH: {
+ cairo_surface_t *image;
+ pixman_image_t *r;
+ void * data;
+ int width, height, stride;
+
+ *tx = -extents->x;
+ *ty = -extents->y;
+ width = extents->width;
+ height = extents->height;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ if (unlikely (image->status))
+ return NULL;
+
+ stride = cairo_image_surface_get_stride (image);
+ data = cairo_image_surface_get_data (image);
+
+ _cairo_mesh_pattern_rasterize ((cairo_mesh_pattern_t *) pattern,
+ data, width, height, stride, *tx, *ty);
+ r = pixman_image_ref (((cairo_image_surface_t *)image)->pixman_image);
+ cairo_surface_destroy (image);
+ return r;
+ }
}
}
@@ -1907,6 +1836,7 @@ typedef cairo_status_t
const cairo_pattern_t *src,
int dst_x,
int dst_y,
+ cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region);
@@ -1958,6 +1888,7 @@ _create_composite_mask_pattern (cairo_clip_t *clip,
mask, PIXMAN_a8,
CAIRO_OPERATOR_ADD, NULL,
extents->x, extents->y,
+ &dst->base.device_transform,
extents, NULL);
if (unlikely (status)) {
pixman_image_unref (mask);
@@ -2034,7 +1965,7 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
pixman_image_t *src;
int src_x, src_y;
- src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
if (unlikely (src == NULL)) {
pixman_image_unref (mask);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2082,6 +2013,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
tmp, dst->pixman_format,
CAIRO_OPERATOR_ADD, NULL,
extents->x, extents->y,
+ &dst->base.device_transform,
extents, NULL);
} else {
/* Initialize the temporary surface from the destination surface */
@@ -2098,6 +2030,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
tmp, dst->pixman_format,
op, src,
extents->x, extents->y,
+ &dst->base.device_transform,
extents, NULL);
}
if (unlikely (status))
@@ -2181,6 +2114,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
dst->pixman_image, dst->pixman_format,
CAIRO_OPERATOR_SOURCE, NULL,
extents->x, extents->y,
+ &dst->base.device_transform,
extents, NULL);
if (unlikely (status))
return status;
@@ -2196,7 +2130,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
if (unlikely (mask == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
if (unlikely (src == NULL)) {
pixman_image_unref (mask);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2317,6 +2251,7 @@ _clip_and_composite (cairo_image_surface_t *dst,
dst->pixman_image, dst->pixman_format,
op, src,
0, 0,
+ &dst->base.device_transform,
&extents->bounded,
clip_region);
}
@@ -2434,6 +2369,7 @@ _composite_traps (void *closure,
const cairo_pattern_t *pattern,
int dst_x,
int dst_y,
+ cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@@ -2459,7 +2395,7 @@ _composite_traps (void *closure,
return CAIRO_STATUS_SUCCESS;
}
- src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2866,7 +2802,7 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
if (unlikely (status))
goto CLEANUP;
- src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
if (unlikely (src == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
@@ -2983,7 +2919,7 @@ _composite_boxes (cairo_image_surface_t *dst,
}
if (pattern != NULL) {
- src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
@@ -3320,6 +3256,7 @@ _composite_mask (void *closure,
const cairo_pattern_t *src_pattern,
int dst_x,
int dst_y,
+ cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@@ -3329,11 +3266,11 @@ _composite_mask (void *closure,
int mask_x = 0, mask_y = 0;
if (src_pattern != NULL) {
- src = _pixman_image_for_pattern (src_pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (src_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, &mask_x, &mask_y);
+ mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, dst_device_transform, &mask_x, &mask_y);
if (unlikely (mask == NULL)) {
pixman_image_unref (src);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3342,7 +3279,7 @@ _composite_mask (void *closure,
if (mask_pattern->has_component_alpha)
pixman_image_set_component_alpha (mask, TRUE);
} else {
- src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -3418,6 +3355,7 @@ _composite_spans (void *closure,
const cairo_pattern_t *pattern,
int dst_x,
int dst_y,
+ cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@@ -3501,7 +3439,7 @@ _composite_spans (void *closure,
pixman_image_t *src;
int src_x, src_y;
- src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
if (unlikely (src == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_RENDERER;
@@ -3635,7 +3573,7 @@ _cairo_image_surface_stroke (void *abstract_surface,
}
status = CAIRO_INT_STATUS_UNSUPPORTED;
- if (path->is_rectilinear) {
+ if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
cairo_boxes_t boxes;
_cairo_boxes_init (&boxes);
@@ -3657,8 +3595,7 @@ _cairo_image_surface_stroke (void *abstract_surface,
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
cairo_polygon_t polygon;
- _cairo_polygon_init (&polygon);
- _cairo_polygon_limit (&polygon, clip_boxes, num_boxes);
+ _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
status = _cairo_path_fixed_stroke_to_polygon (path,
style,
@@ -3735,7 +3672,7 @@ _cairo_image_surface_fill (void *abstract_surface,
return status;
}
- if (_cairo_path_fixed_is_rectilinear_fill (path)) {
+ if (_cairo_path_fixed_fill_is_rectilinear (path)) {
cairo_boxes_t boxes;
_cairo_boxes_init (&boxes);
@@ -3754,10 +3691,9 @@ _cairo_image_surface_fill (void *abstract_surface,
} else {
cairo_polygon_t polygon;
- assert (! path->is_empty_fill);
+ assert (! _cairo_path_fixed_fill_is_empty (path));
- _cairo_polygon_init (&polygon);
- _cairo_polygon_limit (&polygon, clip_boxes, num_boxes);
+ _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
@@ -3792,6 +3728,7 @@ _composite_glyphs_via_mask (void *closure,
const cairo_pattern_t *pattern,
int dst_x,
int dst_y,
+ cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@@ -3807,7 +3744,7 @@ _composite_glyphs_via_mask (void *closure,
int src_x, src_y;
int i;
- src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3928,6 +3865,7 @@ _composite_glyphs (void *closure,
const cairo_pattern_t *pattern,
int dst_x,
int dst_y,
+ cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@@ -3940,7 +3878,7 @@ _composite_glyphs (void *closure,
int i;
if (pattern != NULL) {
- src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+ src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src_x -= dst_x;
src_y -= dst_y;
} else {
@@ -4049,8 +3987,10 @@ _cairo_image_surface_glyphs (void *abstract_surface,
if (clip != NULL && extents.is_bounded) {
clip = _cairo_clip_init_copy (&local_clip, clip);
status = _cairo_clip_rectangle (clip, &extents.bounded);
- if (unlikely (status))
+ if (unlikely (status)) {
+ _cairo_clip_fini (&local_clip);
return status;
+ }
have_clip = TRUE;
}
@@ -4092,6 +4032,7 @@ _cairo_image_surface_get_font_options (void *abstract_surface,
_cairo_font_options_init_default (options);
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
+ _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_ON);
}
/* legacy interface kept for compatibility until surface-fallback is removed */
@@ -4204,7 +4145,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
extents.is_bounded = _cairo_operator_bounded_by_either (op);
- src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &src_offset_x, &src_offset_y);
+ src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &dst->base.device_transform, &src_offset_x, &src_offset_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4213,7 +4154,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
pixman_image_t *mask;
int mask_offset_x, mask_offset_y;
- mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &mask_offset_x, &mask_offset_y);
+ mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &dst->base.device_transform, &mask_offset_x, &mask_offset_y);
if (unlikely (mask == NULL)) {
pixman_image_unref (src);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4378,6 +4319,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
op,
&source_pattern.base,
0, 0,
+ &dst->base.device_transform,
&extents.bounded,
clip_region);
@@ -4482,7 +4424,7 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
return status;
}
- src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &src_x, &src_y);
+ src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &renderer->dst->base.device_transform, &src_x, &src_y);
if (src == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);