From 16fe67ea19bca66ed68c263bb48a5fbd19993e3f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 13 May 2008 16:10:28 -0400 Subject: [PATCH] [cairo-path-fixed] Implement full-matrix _cairo_path_fixed_transform() Based on patch from Peter Clifton. --- src/cairo-clip.c | 2 +- src/cairo-meta-surface.c | 2 +- src/cairo-path-fixed.c | 52 +++++++++++++++++++++++++++------------- src/cairoint.h | 4 ++-- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 9a42fc0c6..c3ed08b47 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -630,7 +630,7 @@ _cairo_clip_translate (cairo_clip_t *clip, _cairo_fixed_to_double (ty)); while (clip_path) { - _cairo_path_fixed_device_transform (&clip_path->path, &matrix); + _cairo_path_fixed_transform (&clip_path->path, &matrix); clip_path = clip_path->prev; } } diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 4cd167613..6abb29ac2 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -773,7 +773,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, status = _cairo_path_fixed_init_copy (&path_copy, dev_path); if (status) break; - _cairo_path_fixed_device_transform (&path_copy, device_transform); + _cairo_path_fixed_transform (&path_copy, device_transform); dev_path = &path_copy; } diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c index fac9e4335..50aee7680 100644 --- a/src/cairo-path-fixed.c +++ b/src/cairo-path-fixed.c @@ -612,29 +612,47 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path, } } - /** - * _cairo_path_fixed_device_transform: + * _cairo_path_fixed_transform: * @path: a #cairo_path_fixed_t to be transformed - * @device_transform: a matrix with only scaling/translation (no rotation or shear) + * @matrix: a #cairo_matrix_t * - * Transform the fixed-point path according to the scaling and - * translation of the given matrix. This function assert()s that the - * given matrix has no rotation or shear elements, (that is, xy and yx - * are 0.0). + * Transform the fixed-point path according to the given matrix. + * There is a fast path for the case where @matrix has no rotation + * or shear. **/ void -_cairo_path_fixed_device_transform (cairo_path_fixed_t *path, - cairo_matrix_t *device_transform) +_cairo_path_fixed_transform (cairo_path_fixed_t *path, + cairo_matrix_t *matrix) { - assert (device_transform->yx == 0.0 && device_transform->xy == 0.0); - /* XXX: Support freeform matrices someday (right now, only translation and scale - * work. */ - _cairo_path_fixed_offset_and_scale (path, - _cairo_fixed_from_double (device_transform->x0), - _cairo_fixed_from_double (device_transform->y0), - _cairo_fixed_from_double (device_transform->xx), - _cairo_fixed_from_double (device_transform->yy)); + cairo_path_buf_t *buf; + int i; + double dx, dy; + + if (matrix->yx == 0.0 && matrix->xy == 0.0) { + /* Fast path for the common case of scale+transform */ + _cairo_path_fixed_offset_and_scale (path, + _cairo_fixed_from_double (matrix->x0), + _cairo_fixed_from_double (matrix->y0), + _cairo_fixed_from_double (matrix->xx), + _cairo_fixed_from_double (matrix->yy)); + return; + } + + buf = &path->buf_head.base; + while (buf) { + for (i = 0; i < buf->num_points; i++) { + dx = _cairo_fixed_to_double (buf->points[i].x); + dy = _cairo_fixed_to_double (buf->points[i].y); + + cairo_matrix_transform_point (matrix, &dx, &dy); + + buf->points[i].x = _cairo_fixed_from_double (dx); + buf->points[i].y = _cairo_fixed_from_double (dy); + } + + buf = buf->next; + } } cairo_bool_t diff --git a/src/cairoint.h b/src/cairoint.h index b1c0ad75c..beca1747b 100755 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1437,8 +1437,8 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path, double tolerance); cairo_private void -_cairo_path_fixed_device_transform (cairo_path_fixed_t *path, - cairo_matrix_t *device_transform); +_cairo_path_fixed_transform (cairo_path_fixed_t *path, + cairo_matrix_t *matrix); cairo_private cairo_bool_t _cairo_path_fixed_is_empty (cairo_path_fixed_t *path);