[Commit] cairo/src cairo_hull.c, NONE, 1.1 Makefile.am, 1.9, 1.10 cairo_path_stroke.c, 1.9, 1.10 cairo_pen.c, 1.9, 1.10 cairo_slope.c, 1.1, 1.2 cairoint.h, 1.27, 1.28

Carl Worth commit at keithp.com
Sat Oct 4 15:34:45 PDT 2003


Committed by: cworth

Update of /local/src/CVS/cairo/src
In directory home.keithp.com:/tmp/cvs-serv27288/src

Modified Files:
	Makefile.am cairo_path_stroke.c cairo_pen.c cairo_slope.c 
	cairoint.h 
Added Files:
	cairo_hull.c 
Log Message:
Generate convex hull of pen before stroking.

--- NEW FILE: cairo_hull.c ---
(This appears to be a binary file; contents omitted.)

Index: Makefile.am
===================================================================
RCS file: /local/src/CVS/cairo/src/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Makefile.am	1 Oct 2003 01:56:22 -0000	1.9
+++ Makefile.am	4 Oct 2003 21:34:42 -0000	1.10
@@ -8,6 +8,7 @@
 	cairo_fixed.c \
 	cairo_font.c \
 	cairo_gstate.c \
+	cairo_hull.c \
 	cairo_matrix.c \
 	cairo_path.c \
 	cairo_path_bounds.c \

Index: cairo_path_stroke.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo_path_stroke.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- cairo_path_stroke.c	4 Oct 2003 16:06:16 -0000	1.9
+++ cairo_path_stroke.c	4 Oct 2003 21:34:42 -0000	1.10
@@ -189,7 +189,7 @@
 	tri[1] = *inpt;
 	while (i != stop) {
 	    tri[2] = in->point;
-	    _translate_point (&tri[2], &pen->vertex[i].point);
+	    _translate_point (&tri[2], &pen->vertices[i].point);
 	    _cairo_traps_tessellate_triangle (stroker->traps, tri);
 	    tri[1] = tri[2];
 	    i += step;
@@ -337,7 +337,7 @@
 	tri[1] = f->cw;
 	for (i=start; i != stop; i = (i+1) % pen->num_vertices) {
 	    tri[2] = f->point;
-	    _translate_point (&tri[2], &pen->vertex[i].point);
+	    _translate_point (&tri[2], &pen->vertices[i].point);
 	    _cairo_traps_tessellate_triangle (stroker->traps, tri);
 	    tri[1] = tri[2];
 	}

Index: cairo_pen.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo_pen.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- cairo_pen.c	4 Oct 2003 16:06:16 -0000	1.9
+++ cairo_pen.c	4 Oct 2003 21:34:42 -0000	1.10
@@ -33,9 +33,6 @@
 static void
 _cairo_pen_compute_slopes (cairo_pen_t *pen);
 
-static int
-_pen_vertex_compare (const void *av, const void *bv);
-
 static cairo_status_t
 _cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_direction_t dir, cairo_polygon_t *polygon);
 
@@ -44,7 +41,7 @@
 {
     pen->radius = 0;
     pen->tolerance = 0;
-    pen->vertex = NULL;
+    pen->vertices = NULL;
     pen->num_vertices = 0;
 
     return CAIRO_STATUS_SUCCESS;
@@ -88,8 +85,8 @@
     if (pen->num_vertices % 2)
 	pen->num_vertices++;
 
-    pen->vertex = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
-    if (pen->vertex == NULL) {
+    pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
+    if (pen->vertices == NULL) {
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
@@ -103,7 +100,7 @@
 	double theta = 2 * M_PI * i / (double) pen->num_vertices;
 	double dx = radius * cos (reflect ? -theta : theta);
 	double dy = radius * sin (reflect ? -theta : theta);
-	cairo_pen_vertex_t *v = &pen->vertex[i];
+	cairo_pen_vertex_t *v = &pen->vertices[i];
 	cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
 	v->point.x = _cairo_fixed_from_double (dx);
 	v->point.y = _cairo_fixed_from_double (dy);
@@ -117,7 +114,7 @@
 void
 _cairo_pen_fini (cairo_pen_t *pen)
 {
-    free (pen->vertex);
+    free (pen->vertices);
     _cairo_pen_init_empty (pen);
 }
 
@@ -127,11 +124,11 @@
     *pen = *other;
 
     if (pen->num_vertices) {
-	pen->vertex = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
-	if (pen->vertex == NULL) {
+	pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
+	if (pen->vertices == NULL) {
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
-	memcpy (pen->vertex, other->vertex, pen->num_vertices * sizeof (cairo_pen_vertex_t));
+	memcpy (pen->vertices, other->vertices, pen->num_vertices * sizeof (cairo_pen_vertex_t));
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -140,37 +137,23 @@
 cairo_status_t
 _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
 {
+    cairo_pen_vertex_t *vertices;
+    int num_vertices;
     int i;
-    cairo_pen_vertex_t *v, *v_next, *new_vertex;
 
-    pen->num_vertices += num_points;
-    new_vertex = realloc (pen->vertex, pen->num_vertices * sizeof (cairo_pen_vertex_t));
-    if (new_vertex == NULL) {
-	pen->num_vertices -= num_points;
+    num_vertices = pen->num_vertices + num_points;
+    vertices = realloc (pen->vertices, num_vertices * sizeof (cairo_pen_vertex_t));
+    if (vertices == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
-    }
-    pen->vertex = new_vertex;
 
-    /* initialize new vertices */
-    for (i=0; i < num_points; i++) {
-	v = &pen->vertex[pen->num_vertices-(i+1)];
-	v->point = point[i];
-    }
+    pen->vertices = vertices;
+    pen->num_vertices = num_vertices;
 
-    qsort (pen->vertex, pen->num_vertices, sizeof (cairo_pen_vertex_t), _pen_vertex_compare);
+    /* initialize new vertices */
+    for (i=0; i < num_points; i++)
+	pen->vertices[pen->num_vertices-num_points+i].point = point[i];
 
-    /* eliminate any duplicate vertices */
-    for (i=0; i < pen->num_vertices; i++ ) {
-	v = &pen->vertex[i];
-	v_next = (i < pen->num_vertices - 1) ? &pen->vertex[i+1] : &pen->vertex[0];
-	if (_pen_vertex_compare (v, v_next) == 0) {
-	    pen->num_vertices--;
-	    memmove (&pen->vertex[i], &pen->vertex[i+1],
-		     (pen->num_vertices - i) * sizeof (cairo_pen_vertex_t));
-	    /* There may be more of the same duplicate, check again */
-	    i--;
-	}
-    }
+    _cairo_hull_compute (pen->vertices, &pen->num_vertices);
 
     _cairo_pen_compute_slopes (pen);
 
@@ -199,53 +182,15 @@
     for (i=0, i_prev = pen->num_vertices - 1;
 	 i < pen->num_vertices;
 	 i_prev = i++) {
-	prev = &pen->vertex[i_prev];
-	v = &pen->vertex[i];
-	next = &pen->vertex[(i + 1) % pen->num_vertices];
+	prev = &pen->vertices[i_prev];
+	v = &pen->vertices[i];
+	next = &pen->vertices[(i + 1) % pen->num_vertices];
 
 	_cairo_slope_init (&v->slope_cw, &prev->point, &v->point);
 	_cairo_slope_init (&v->slope_ccw, &v->point, &next->point);
     }
 }
 
-/* Is a further clockwise from (1,0) than b?
- *
- * There are a two special cases to consider:
- *  1) a and b are not in the same half plane.
- *  2) both a and b are on the X axis
- * After that, the computation is a simple slope comparison.
- */
-static int
-_pen_vertex_compare (const void *av, const void *bv)
-{
-    const cairo_pen_vertex_t *a = av;
-    const cairo_pen_vertex_t *b = bv;
-    cairo_fixed_48_16_t diff;
-
-    int a_above = a->point.y >= 0;
-    int b_above = b->point.y >= 0;
-
-    if (a_above != b_above)
-	return b_above - a_above;
-
-    if (a->point.y == 0 && b->point.y == 0) {
-	int a_right = a->point.x >= 0;
-	int b_right = b->point.x >= 0;
-
-	if (a_right != b_right)
-	    return b_right - a_right;
-    }
-
-    diff = ((cairo_fixed_48_16_t) a->point.y * (cairo_fixed_48_16_t) b->point.x 
-	    - (cairo_fixed_48_16_t) b->point.y * (cairo_fixed_48_16_t) a->point.x);
-
-    if (diff > 0)
-	return 1;
-    if (diff < 0)
-	return -1;
-    return 0;
-}
-
 /* Find active pen vertex for clockwise edge of stroke at the given slope.
  *
  * NOTE: The behavior of this function is sensitive to the sense of
@@ -264,8 +209,8 @@
     int i;
 
     for (i=0; i < pen->num_vertices; i++) {
-	if (_cairo_slope_clockwise (slope, &pen->vertex[i].slope_ccw)
-	    && _cairo_slope_counter_clockwise (slope, &pen->vertex[i].slope_cw))
+	if (_cairo_slope_clockwise (slope, &pen->vertices[i].slope_ccw)
+	    && _cairo_slope_counter_clockwise (slope, &pen->vertices[i].slope_cw))
 	    break;
     }
 
@@ -292,8 +237,8 @@
     slope_reverse.dy = -slope_reverse.dy;
 
     for (i=pen->num_vertices-1; i >= 0; i--) {
-	if (_cairo_slope_counter_clockwise (&pen->vertex[i].slope_ccw, &slope_reverse)
-	    && _cairo_slope_clockwise (&pen->vertex[i].slope_cw, &slope_reverse))
+	if (_cairo_slope_counter_clockwise (&pen->vertices[i].slope_ccw, &slope_reverse)
+	    && _cairo_slope_clockwise (&pen->vertices[i].slope_cw, &slope_reverse))
 	    break;
     }
 
@@ -339,8 +284,8 @@
 
     i = start;
     while (i != stop) {
-	hull_point.x = point[i].x + pen->vertex[active].point.x;
-	hull_point.y = point[i].y + pen->vertex[active].point.y;
+	hull_point.x = point[i].x + pen->vertices[active].point.x;
+	hull_point.y = point[i].y + pen->vertices[active].point.y;
 	status = _cairo_polygon_add_point (polygon, &hull_point);
 	if (status)
 	    return status;
@@ -349,10 +294,10 @@
 	    slope = final_slope;
 	else
 	    _cairo_slope_init (&slope, &point[i], &point[i+step]);
-	if (_cairo_slope_counter_clockwise (&slope, &pen->vertex[active].slope_ccw)) {
+	if (_cairo_slope_counter_clockwise (&slope, &pen->vertices[active].slope_ccw)) {
 	    if (++active == pen->num_vertices)
 		active = 0;
-	} else if (_cairo_slope_clockwise (&slope, &pen->vertex[active].slope_cw)) {
+	} else if (_cairo_slope_clockwise (&slope, &pen->vertices[active].slope_cw)) {
 	    if (--active == -1)
 		active = pen->num_vertices - 1;
 	} else {

Index: cairo_slope.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo_slope.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo_slope.c	30 Jul 2003 15:30:51 -0000	1.1
+++ cairo_slope.c	4 Oct 2003 21:34:42 -0000	1.2
@@ -34,6 +34,43 @@
     slope->dy = b->y - a->y;
 }
 
+/* Compare two slopes. Slope angles begin at 0 in the direction of the
+   positive X axis and increase in the direction of the positive Y
+   axis.
+
+   WARNING: This function only gives correct results if the angular
+   difference between a and b is less than PI.
+
+   <  0 => a less positive than b
+   == 0 => a equal to be
+   >  0 => a more positive than b
+*/
+int
+_cairo_slope_compare (cairo_slope_t *a, cairo_slope_t *b)
+{
+    cairo_fixed_48_16_t diff;
+
+    diff = ((cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx 
+	    - (cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx);
+
+    if (diff > 0)
+	return 1;
+    if (diff < 0)
+	return -1;
+
+    if (a->dx == 0 && a->dy == 0)
+	return 1;
+    if (b->dx == 0 && b->dy ==0)
+	return -1;
+
+    return 0;
+}
+
+/* XXX: It might be cleaner to move away from usage of
+   _cairo_slope_clockwise/_cairo_slope_counter_clockwise in favor of
+   directly using _cairo_slope_compare.
+*/
+
 /* Is a clockwise of b?
  *
  * NOTE: The strict equality here is not significant in and of itself,
@@ -43,8 +80,7 @@
 int
 _cairo_slope_clockwise (cairo_slope_t *a, cairo_slope_t *b)
 {
-    return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx 
-	    > (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
+    return _cairo_slope_compare (a, b) < 0;
 }
 
 int

Index: cairoint.h
===================================================================
RCS file: /local/src/CVS/cairo/src/cairoint.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- cairoint.h	4 Oct 2003 16:06:16 -0000	1.27
+++ cairoint.h	4 Oct 2003 21:34:42 -0000	1.28
@@ -222,8 +222,8 @@
     double radius;
     double tolerance;
 
+    cairo_pen_vertex_t *vertices;
     int num_vertices;
-    cairo_pen_vertex_t *vertex;
 } cairo_pen_t;
 
 typedef struct cairo_color cairo_color_t;
@@ -715,6 +715,10 @@
 		       double			y,
 		       const unsigned char	*utf8);
 
+/* cairo_hull.c */
+extern cairo_status_t
+_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);
+
 /* cairo_path.c */
 extern void __internal_linkage
 _cairo_path_init (cairo_path_t *path);




More information about the Commit mailing list