[cairo-commit] src/cairoint.h src/cairo-matrix.c src/cairo-path-stroke-boxes.c test/reference

Chris Wilson ickle at kemper.freedesktop.org
Mon Mar 19 13:06:07 PDT 2012


 dev/null                           |binary
 src/cairo-matrix.c                 |   15 ----
 src/cairo-path-stroke-boxes.c      |  125 +++++++++++++++++++------------------
 src/cairoint.h                     |   23 +++++-
 test/reference/text-rotate.ref.png |binary
 5 files changed, 84 insertions(+), 79 deletions(-)

New commits:
commit 0a778d974f2dca2555711ef79e738cb0614b2a3f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 19 19:42:01 2012 +0000

    stroke: Adapt rectilinear stroker to handle separable non-unity scaling
    
    Reported-by: Christos Sotiriou <csotiriou at gmail.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 8da0ca7..59f0b86 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -701,21 +701,6 @@ _cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
 }
 
 cairo_bool_t
-_cairo_matrix_is_identity (const cairo_matrix_t *matrix)
-{
-    return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
-	    matrix->xy == 0.0 && matrix->yy == 1.0 &&
-	    matrix->x0 == 0.0 && matrix->y0 == 0.0);
-}
-
-cairo_bool_t
-_cairo_matrix_is_translation (const cairo_matrix_t *matrix)
-{
-    return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
-	    matrix->xy == 0.0 && matrix->yy == 1.0);
-}
-
-cairo_bool_t
 _cairo_matrix_is_integer_translation (const cairo_matrix_t *matrix,
 				      int *itx, int *ity)
 {
diff --git a/src/cairo-path-stroke-boxes.c b/src/cairo-path-stroke-boxes.c
index 12e4dd1..3e8c5a4 100644
--- a/src/cairo-path-stroke-boxes.c
+++ b/src/cairo-path-stroke-boxes.c
@@ -57,7 +57,7 @@ typedef struct _cairo_rectilinear_stroker {
     const cairo_matrix_t *ctm;
     cairo_antialias_t antialias;
 
-    cairo_fixed_t half_line_width;
+    cairo_fixed_t half_line_x, half_line_y;
     cairo_boxes_t *boxes;
     cairo_point_t current_point;
     cairo_point_t first_point;
@@ -82,11 +82,11 @@ _cairo_rectilinear_stroker_limit (cairo_rectilinear_stroker_t *stroker,
     stroker->has_bounds = TRUE;
     _cairo_boxes_get_extents (boxes, num_boxes, &stroker->bounds);
 
-    stroker->bounds.p1.x -= stroker->half_line_width;
-    stroker->bounds.p2.x += stroker->half_line_width;
+    stroker->bounds.p1.x -= stroker->half_line_x;
+    stroker->bounds.p2.x += stroker->half_line_x;
 
-    stroker->bounds.p1.y -= stroker->half_line_width;
-    stroker->bounds.p2.y += stroker->half_line_width;
+    stroker->bounds.p1.y -= stroker->half_line_y;
+    stroker->bounds.p2.y += stroker->half_line_y;
 }
 
 static cairo_bool_t
@@ -122,15 +122,18 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t	*stroker,
 	return FALSE;
     }
 
-    if (! _cairo_matrix_has_unity_scale (ctm))
+    if (! _cairo_matrix_is_scale (ctm))
 	return FALSE;
 
     stroker->stroke_style = stroke_style;
     stroker->ctm = ctm;
     stroker->antialias = antialias;
 
-    stroker->half_line_width =
-	_cairo_fixed_from_double (stroke_style->line_width / 2.0);
+    stroker->half_line_x =
+	_cairo_fixed_from_double (fabs(ctm->xx) * stroke_style->line_width / 2.0);
+    stroker->half_line_y =
+	_cairo_fixed_from_double (fabs(ctm->yy) * stroke_style->line_width / 2.0);
+
     stroker->open_sub_path = FALSE;
     stroker->segments = stroker->segments_embedded;
     stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded);
@@ -197,7 +200,8 @@ static cairo_status_t
 _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
 {
     cairo_line_cap_t line_cap = stroker->stroke_style->line_cap;
-    cairo_fixed_t half_line_width = stroker->half_line_width;
+    cairo_fixed_t half_line_x = stroker->half_line_x;
+    cairo_fixed_t half_line_y = stroker->half_line_y;
     cairo_status_t status;
     int i;
 
@@ -238,26 +242,26 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
 	    if (a->y == b->y) {
 		if (a->x < b->x) {
 		    if (lengthen_initial)
-			a->x -= half_line_width;
+			a->x -= half_line_x;
 		    if (lengthen_final)
-			b->x += half_line_width;
+			b->x += half_line_x;
 		} else {
 		    if (lengthen_initial)
-			a->x += half_line_width;
+			a->x += half_line_x;
 		    if (lengthen_final)
-			b->x -= half_line_width;
+			b->x -= half_line_x;
 		}
 	    } else {
 		if (a->y < b->y) {
 		    if (lengthen_initial)
-			a->y -= half_line_width;
+			a->y -= half_line_y;
 		    if (lengthen_final)
-			b->y += half_line_width;
+			b->y += half_line_y;
 		} else {
 		    if (lengthen_initial)
-			a->y += half_line_width;
+			a->y += half_line_y;
 		    if (lengthen_final)
-			b->y -= half_line_width;
+			b->y -= half_line_y;
 		}
 	    }
 	}
@@ -265,11 +269,11 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
 	/* Form the rectangle by expanding by half the line width in
 	 * either perpendicular direction. */
 	if (a->y == b->y) {
-	    a->y -= half_line_width;
-	    b->y += half_line_width;
+	    a->y -= half_line_y;
+	    b->y += half_line_y;
 	} else {
-	    a->x -= half_line_width;
-	    b->x += half_line_width;
+	    a->x -= half_line_x;
+	    b->x += half_line_x;
 	}
 
 	if (a->x < b->x) {
@@ -301,7 +305,8 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 {
     cairo_status_t status;
     cairo_line_cap_t line_cap = stroker->stroke_style->line_cap;
-    cairo_fixed_t half_line_width = stroker->half_line_width;
+    cairo_fixed_t half_line_x = stroker->half_line_x;
+    cairo_fixed_t half_line_y = stroker->half_line_y;
     int i;
 
     for (i = 0; i < stroker->num_segments; i++) {
@@ -332,25 +337,25 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 	    if (is_horizontal) {
 		if (box.p1.x <= box.p2.x) {
 		    box.p1.x = box.p2.x;
-		    box.p2.x += half_line_width;
+		    box.p2.x += half_line_x;
 		} else {
-		    box.p1.x = box.p2.x - half_line_width;
+		    box.p1.x = box.p2.x - half_line_x;
 		}
 		if (out_slope.dy >= 0)
-		    box.p1.y -= half_line_width;
+		    box.p1.y -= half_line_x;
 		if (out_slope.dy <= 0)
-		    box.p2.y += half_line_width;
+		    box.p2.y += half_line_x;
 	    } else {
 		if (box.p1.y <= box.p2.y) {
 		    box.p1.y = box.p2.y;
-		    box.p2.y += half_line_width;
+		    box.p2.y += half_line_x;
 		} else {
-		    box.p1.y = box.p2.y - half_line_width;
+		    box.p1.y = box.p2.y - half_line_x;
 		}
 		if (out_slope.dx >= 0)
-		    box.p1.x -= half_line_width;
+		    box.p1.x -= half_line_x;
 		if (out_slope.dx <= 0)
-		    box.p2.x += half_line_width;
+		    box.p2.x += half_line_x;
 	    }
 
 	    status = _cairo_boxes_add (stroker->boxes, stroker->antialias, &box);
@@ -362,29 +367,29 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 	if (is_horizontal) {
 	    if (line_cap == CAIRO_LINE_CAP_SQUARE) {
 		if (a->x <= b->x) {
-		    a->x -= half_line_width;
-		    b->x += half_line_width;
+		    a->x -= half_line_x;
+		    b->x += half_line_x;
 		} else {
-		    a->x += half_line_width;
-		    b->x -= half_line_width;
+		    a->x += half_line_x;
+		    b->x -= half_line_x;
 		}
 	    }
 
-	    a->y += half_line_width;
-	    b->y -= half_line_width;
+	    a->y += half_line_y;
+	    b->y -= half_line_y;
 	} else {
 	    if (line_cap == CAIRO_LINE_CAP_SQUARE) {
 		if (a->y <= b->y) {
-		    a->y -= half_line_width;
-		    b->y += half_line_width;
+		    a->y -= half_line_y;
+		    b->y += half_line_y;
 		} else {
-		    a->y += half_line_width;
-		    b->y -= half_line_width;
+		    a->y += half_line_y;
+		    b->y -= half_line_y;
 		}
 	    }
 
-	    a->x += half_line_width;
-	    b->x -= half_line_width;
+	    a->x += half_line_x;
+	    b->x -= half_line_x;
 	}
 
 	if (a->x == b->x && a->y == b->y)
@@ -621,40 +626,40 @@ _cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t	*path,
     if (! rectilinear_stroker.dash.dashed &&
 	_cairo_path_fixed_is_stroke_box (path, &box) &&
 	/* if the segments overlap we need to feed them into the tessellator */
-	box.p2.x - box.p1.x > 2* rectilinear_stroker.half_line_width &&
-	box.p2.y - box.p1.y > 2* rectilinear_stroker.half_line_width)
+	box.p2.x - box.p1.x > 2* rectilinear_stroker.half_line_x &&
+	box.p2.y - box.p1.y > 2* rectilinear_stroker.half_line_y)
     {
 	cairo_box_t b;
 
 	/* top */
-	b.p1.x = box.p1.x - rectilinear_stroker.half_line_width;
-	b.p2.x = box.p2.x + rectilinear_stroker.half_line_width;
-	b.p1.y = box.p1.y - rectilinear_stroker.half_line_width;
-	b.p2.y = box.p1.y + rectilinear_stroker.half_line_width;
+	b.p1.x = box.p1.x - rectilinear_stroker.half_line_x;
+	b.p2.x = box.p2.x + rectilinear_stroker.half_line_x;
+	b.p1.y = box.p1.y - rectilinear_stroker.half_line_y;
+	b.p2.y = box.p1.y + rectilinear_stroker.half_line_y;
 	status = _cairo_boxes_add (boxes, antialias, &b);
 	assert (status == CAIRO_INT_STATUS_SUCCESS);
 
 	/* left  (excluding top/bottom) */
-	b.p1.x = box.p1.x - rectilinear_stroker.half_line_width;
-	b.p2.x = box.p1.x + rectilinear_stroker.half_line_width;
-	b.p1.y = box.p1.y + rectilinear_stroker.half_line_width;
-	b.p2.y = box.p2.y - rectilinear_stroker.half_line_width;
+	b.p1.x = box.p1.x - rectilinear_stroker.half_line_x;
+	b.p2.x = box.p1.x + rectilinear_stroker.half_line_x;
+	b.p1.y = box.p1.y + rectilinear_stroker.half_line_y;
+	b.p2.y = box.p2.y - rectilinear_stroker.half_line_y;
 	status = _cairo_boxes_add (boxes, antialias, &b);
 	assert (status == CAIRO_INT_STATUS_SUCCESS);
 
 	/* right  (excluding top/bottom) */
-	b.p1.x = box.p2.x - rectilinear_stroker.half_line_width;
-	b.p2.x = box.p2.x + rectilinear_stroker.half_line_width;
-	b.p1.y = box.p1.y + rectilinear_stroker.half_line_width;
-	b.p2.y = box.p2.y - rectilinear_stroker.half_line_width;
+	b.p1.x = box.p2.x - rectilinear_stroker.half_line_x;
+	b.p2.x = box.p2.x + rectilinear_stroker.half_line_x;
+	b.p1.y = box.p1.y + rectilinear_stroker.half_line_y;
+	b.p2.y = box.p2.y - rectilinear_stroker.half_line_y;
 	status = _cairo_boxes_add (boxes, antialias, &b);
 	assert (status == CAIRO_INT_STATUS_SUCCESS);
 
 	/* bottom */
-	b.p1.x = box.p1.x - rectilinear_stroker.half_line_width;
-	b.p2.x = box.p2.x + rectilinear_stroker.half_line_width;
-	b.p1.y = box.p2.y - rectilinear_stroker.half_line_width;
-	b.p2.y = box.p2.y + rectilinear_stroker.half_line_width;
+	b.p1.x = box.p1.x - rectilinear_stroker.half_line_x;
+	b.p2.x = box.p2.x + rectilinear_stroker.half_line_x;
+	b.p1.y = box.p2.y - rectilinear_stroker.half_line_y;
+	b.p2.y = box.p2.y + rectilinear_stroker.half_line_y;
 	status = _cairo_boxes_add (boxes, antialias, &b);
 	assert (status == CAIRO_INT_STATUS_SUCCESS);
 
diff --git a/src/cairoint.h b/src/cairoint.h
index 855e544..9a8003e 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1657,11 +1657,26 @@ cairo_private cairo_status_t
 _cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
 					   double *sx, double *sy, int x_major);
 
-cairo_private cairo_bool_t
-_cairo_matrix_is_identity (const cairo_matrix_t *matrix) cairo_pure;
+static inline cairo_bool_t
+_cairo_matrix_is_identity (const cairo_matrix_t *matrix)
+{
+    return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
+	    matrix->xy == 0.0 && matrix->yy == 1.0 &&
+	    matrix->x0 == 0.0 && matrix->y0 == 0.0);
+}
 
-cairo_private cairo_bool_t
-_cairo_matrix_is_translation (const cairo_matrix_t *matrix) cairo_pure;
+static inline cairo_bool_t
+_cairo_matrix_is_translation (const cairo_matrix_t *matrix)
+{
+    return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
+	    matrix->xy == 0.0 && matrix->yy == 1.0);
+}
+
+static inline cairo_bool_t
+_cairo_matrix_is_scale (const cairo_matrix_t *matrix)
+{
+    return matrix->yx == 0.0 && matrix->xy == 0.0;
+}
 
 cairo_private cairo_bool_t
 _cairo_matrix_is_integer_translation(const cairo_matrix_t *matrix,
diff --git a/test/reference/text-rotate.argb32.ref.png b/test/reference/text-rotate.argb32.ref.png
deleted file mode 100644
index b455aab..0000000
Binary files a/test/reference/text-rotate.argb32.ref.png and /dev/null differ
diff --git a/test/reference/text-rotate.ref.png b/test/reference/text-rotate.ref.png
index 59a0d0a..00c59e7 100644
Binary files a/test/reference/text-rotate.ref.png and b/test/reference/text-rotate.ref.png differ
diff --git a/test/reference/text-rotate.rgb24.ref.png b/test/reference/text-rotate.rgb24.ref.png
deleted file mode 100644
index b455aab..0000000
Binary files a/test/reference/text-rotate.rgb24.ref.png and /dev/null differ


More information about the cairo-commit mailing list