From 83759e7d592c5d7b12b2341574fd584fe5e0fb5a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 4 Sep 2012 14:42:34 +0100 Subject: [PATCH] default-context: Convert the relative path segments into the backend coordinates When transforming the incoming paths, the goal is to transform them from user space onto the target coordinate system. Currently for relative paths we used user_to_device_distance as we presumed that there was no backend scale factor. However, Alex Larsson noticed that these then broke when playing around with such a device transform... Reported-by: Alexander Larsson Signed-off-by: Chris Wilson --- src/cairo-default-context.c | 10 +++++----- src/cairo-gstate-private.h | 10 ++++++++++ src/cairo-gstate.c | 7 +++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c index dc8c359a9..c020fcb1f 100644 --- a/src/cairo-default-context.c +++ b/src/cairo-default-context.c @@ -748,7 +748,7 @@ _cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy) cairo_default_context_t *cr = abstract_cr; cairo_fixed_t dx_fixed, dy_fixed; - _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); + _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy); dx_fixed = _cairo_fixed_from_double (dx); dy_fixed = _cairo_fixed_from_double (dy); @@ -762,7 +762,7 @@ _cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy) cairo_default_context_t *cr = abstract_cr; cairo_fixed_t dx_fixed, dy_fixed; - _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); + _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy); dx_fixed = _cairo_fixed_from_double (dx); dy_fixed = _cairo_fixed_from_double (dy); @@ -782,9 +782,9 @@ _cairo_default_context_rel_curve_to (void *abstract_cr, cairo_fixed_t dx2_fixed, dy2_fixed; cairo_fixed_t dx3_fixed, dy3_fixed; - _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1); - _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2); - _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3); + _cairo_gstate_user_to_backend_distance (cr->gstate, &dx1, &dy1); + _cairo_gstate_user_to_backend_distance (cr->gstate, &dx2, &dy2); + _cairo_gstate_user_to_backend_distance (cr->gstate, &dx3, &dy3); dx1_fixed = _cairo_fixed_from_double (dx1); dy1_fixed = _cairo_fixed_from_double (dy1); diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index 38f11c7ad..c95d94a25 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -208,6 +208,16 @@ _cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y) _do_cairo_gstate_user_to_backend (gstate, x, y); } +cairo_private void +_do_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y); + +static inline void +_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y) +{ + if (! gstate->is_identity) + _do_cairo_gstate_user_to_backend_distance (gstate, x, y); +} + cairo_private void _do_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y); diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 15dc46f6b..d62f0a405 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -813,6 +813,13 @@ _do_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y) cairo_matrix_transform_point (&gstate->target->device_transform, x, y); } +void +_do_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y) +{ + cairo_matrix_transform_distance (&gstate->ctm, x, y); + cairo_matrix_transform_distance (&gstate->target->device_transform, x, y); +} + void _do_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y) {