summaryrefslogtreecommitdiff
path: root/src/cairo-default-context.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2013-05-31 16:44:29 +0200
committerChris Wilson <chris@chris-wilson.co.uk>2013-09-05 16:08:19 +0100
commitf0e2cd4494b1ac9a351d095fbeb53d702342d35c (patch)
treeec2f33d8745e42f1fce0e51e065bacc91edcd4cf /src/cairo-default-context.c
parent900fc4a890026e46a3b0a00967632f57074b8b93 (diff)
downloadcairo-f0e2cd4494b1ac9a351d095fbeb53d702342d35c.tar.gz
gstate: Handle device scale on surface as source
When creating a transformed pattern we must apply the device transform *before* the transform set on the pattern itself, otherwise e.g. its translation will not be affected by the device scale. We also fix up the device_transform related handling in _cairo_default_context_pop_group(). With a device scale we can no longer just use the device_transform_inverse to unset the device offset for the extents, so we make that a simple translate instead. We also remove some weird code that tries to handle the device transform but seems unnecessary (maybe a workaround for applying the device transform in the wrong order?). With that code removed things work fine, but with it things get translated wrongly when there is a scale.
Diffstat (limited to 'src/cairo-default-context.c')
-rw-r--r--src/cairo-default-context.c23
1 files changed, 8 insertions, 15 deletions
diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c
index 77b6eef9f..078135b2c 100644
--- a/src/cairo-default-context.c
+++ b/src/cairo-default-context.c
@@ -218,7 +218,8 @@ _cairo_default_context_pop_group (void *abstract_cr)
cairo_default_context_t *cr = abstract_cr;
cairo_surface_t *group_surface;
cairo_pattern_t *group_pattern;
- cairo_matrix_t group_matrix, device_transform_matrix;
+ cairo_surface_t *parent_surface;
+ cairo_matrix_t group_matrix;
cairo_status_t status;
/* Verify that we are at the right nesting level */
@@ -232,29 +233,21 @@ _cairo_default_context_pop_group (void *abstract_cr)
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
assert (status == CAIRO_STATUS_SUCCESS);
+ parent_surface = _cairo_gstate_get_target (cr->gstate);
+
group_pattern = cairo_pattern_create_for_surface (group_surface);
status = group_pattern->status;
if (unlikely (status))
goto done;
_cairo_gstate_get_matrix (cr->gstate, &group_matrix);
- /* Transform by group_matrix centered around device_transform so that when
- * we call _cairo_gstate_copy_transformed_pattern the result is a pattern
- * with a matrix equivalent to the device_transform of group_surface. */
- if (_cairo_surface_has_device_transform (group_surface)) {
- cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform);
- _cairo_pattern_transform (group_pattern, &group_matrix);
- _cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse);
- } else {
- cairo_pattern_set_matrix (group_pattern, &group_matrix);
- }
+ cairo_pattern_set_matrix (group_pattern, &group_matrix);
/* If we have a current path, we need to adjust it to compensate for
* the device offset just removed. */
- cairo_matrix_multiply (&device_transform_matrix,
- &_cairo_gstate_get_target (cr->gstate)->device_transform,
- &group_surface->device_transform_inverse);
- _cairo_path_fixed_transform (cr->path, &device_transform_matrix);
+ _cairo_path_fixed_translate (cr->path,
+ _cairo_fixed_from_int (parent_surface->device_transform.x0 - group_surface->device_transform.x0),
+ _cairo_fixed_from_int (parent_surface->device_transform.y0 - group_surface->device_transform.y0));
done:
cairo_surface_destroy (group_surface);