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 <alexl@redhat.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-09-04 14:42:34 +01:00
parent c0b1b17818
commit 83759e7d59
3 changed files with 22 additions and 5 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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)
{