[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