[cairo-commit] 8 commits - configure.ac src/cairo-bentley-ottmann.c src/cairo.c src/cairoint.h src/cairo-os2.h src/cairo-path-fill.c src/cairo-path-fixed.c src/cairo-path-in-fill.c src/cairo-path-stroke.c src/cairo-pen.c src/cairo-polygon.c src/cairo-skiplist.c src/cairo-spline.c src/cairo-type1-subset.c src/cairo-types-private.h src/Makefile.am test/any2ppm.c test/Makefile.am

Chris Wilson ickle at kemper.freedesktop.org
Sun Nov 16 08:25:45 PST 2008


 configure.ac                |    3 
 src/Makefile.am             |    5 
 src/cairo-bentley-ottmann.c |   12 --
 src/cairo-os2.h             |    4 
 src/cairo-path-fill.c       |   23 +--
 src/cairo-path-fixed.c      |   27 +---
 src/cairo-path-in-fill.c    |   21 +--
 src/cairo-path-stroke.c     |  101 +++++++++--------
 src/cairo-pen.c             |  254 ++++++++++++++++++++++++++++----------------
 src/cairo-polygon.c         |   23 +--
 src/cairo-skiplist.c        |  236 ++++++++--------------------------------
 src/cairo-spline.c          |  121 +++-----------------
 src/cairo-type1-subset.c    |   14 ++
 src/cairo-types-private.h   |   13 +-
 src/cairo.c                 |   11 +
 src/cairoint.h              |   65 +++++++----
 test/Makefile.am            |    3 
 test/any2ppm.c              |    8 -
 18 files changed, 410 insertions(+), 534 deletions(-)

New commits:
commit a2eff7c7deb9b41c387472bb91b9a7b9c8f319f0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Nov 16 16:19:25 2008 +0000

    [test] Add build rule for libcairo-script-interpreter.la
    
    Add a rule to build the cairo-script-interpreter on behalf of any2ppm.

diff --git a/test/Makefile.am b/test/Makefile.am
index 5517977..749b309 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1155,6 +1155,9 @@ $(top_builddir)/src/libcairo.la:
 $(top_builddir)/test/pdiff/libpdiff.la:
 	cd $(top_builddir)/test/pdiff && $(MAKE) $(AM_MAKEFLAGS) libpdiff.la
 
+$(top_builddir)/util/cairo-script/libcairo-script-interpreter.la: $(top_builddir)/src/libcairo.la
+	cd $(top_builddir)/util/cair-script && $(MAKE) $(AM_MAKEFLAGS) libcairo-script-interpreter.la
+
 EXTRA_PROGRAMS += imagediff png-flatten
 
 imagediff_SOURCES = \
commit bf309aab6072ee1004073e71bccdf3c8040a8ad6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Nov 15 11:36:41 2008 +0000

    [configure] Delete CAN_TEST_SCRIPT
    
    A CairoScript interpreter is built under utils and so is always available.

diff --git a/configure.ac b/configure.ac
index 9bc22e1..7384ccc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -238,10 +238,7 @@ dnl ===========================================================================
 
 any2ppm_cs=no
 CAIRO_ENABLE_SURFACE_BACKEND(script, script, no, [
-  test_script=yes
   any2ppm_cs=yes
-  AC_DEFINE([CAIRO_CAN_TEST_SCRIPT_SURFACE], 1,
-	    [Define to 1 if the CairoScript backend can be tested])
 ])
 
 dnl ===========================================================================
diff --git a/test/any2ppm.c b/test/any2ppm.c
index c4cf085..e39775b 100644
--- a/test/any2ppm.c
+++ b/test/any2ppm.c
@@ -236,7 +236,6 @@ write_ppm (cairo_surface_t *surface, int fd)
     return NULL;
 }
 
-#if CAIRO_CAN_TEST_SCRIPT_SURFACE
 static cairo_surface_t *
 _create_image (void *closure,
 	       double width, double height)
@@ -293,13 +292,6 @@ cs_convert (char **argv, int fd)
 
     return err;
 }
-#else
-static const char *
-cs_convert (char **argv, int fd)
-{
-    return "compiled without CairoScript support.";
-}
-#endif
 
 #if CAIRO_CAN_TEST_PDF_SURFACE
 /* adapted from pdf2png.c */
commit d7873eecc598a558a2a862add8e9b056c4a23a4a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Nov 14 17:18:47 2008 +0000

    [spline] Eliminate intermediate allocations during spline decomposition.
    
    The spline decomposition code allocates and stores points in a temporary
    buffer which is immediately consumed by the caller. If the caller supplies
    a callback that handles each point computed along the spline, then we can
    use the point immediately and avoid the allocation.

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index b22731d..eca28d5 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -87,7 +87,7 @@ struct _cairo_bo_edge {
     cairo_bo_point32_t top;
     cairo_bo_point32_t middle;
     cairo_bo_point32_t bottom;
-    cairo_bool_t reversed;
+    int dir;
     cairo_bo_edge_t *prev;
     cairo_bo_edge_t *next;
     cairo_bo_trap_t *deferred_trap;
@@ -1439,10 +1439,7 @@ _active_edges_to_traps (cairo_bo_edge_t		*head,
 
     for (edge = head; edge; edge = edge->next) {
 	if (fill_rule == CAIRO_FILL_RULE_WINDING) {
-	    if (edge->reversed)
-		in_out++;
-	    else
-		in_out--;
+	    in_out += edge->dir;
 	    if (in_out == 0) {
 		status = _cairo_bo_edge_end_trap (edge, top, bo_traps);
 		if (status)
@@ -1734,10 +1731,7 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t	 *traps,
 	edge->top.y = top.y;
 	edge->bottom.x = bot.x;
 	edge->bottom.y = bot.y;
-	/* XXX: The 'clockWise' name that cairo_polygon_t uses is
-	 * totally bogus. It's really a (negated!) description of
-	 * whether the edge is reversed. */
-	edge->reversed = (! polygon->edges[i].clockWise);
+	edge->dir = polygon->edges[i].dir;
 	edge->deferred_trap = NULL;
 	edge->prev = NULL;
 	edge->next = NULL;
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index 1cef20e..46046bb 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -118,30 +118,23 @@ _cairo_filler_curve_to (void *closure,
 			cairo_point_t *c,
 			cairo_point_t *d)
 {
-    int i;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_filler_t *filler = closure;
-    cairo_polygon_t *polygon = &filler->polygon;
     cairo_spline_t spline;
 
-    status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);
-
-    if (status == CAIRO_INT_STATUS_DEGENERATE)
+    if (! _cairo_spline_init (&spline,
+			      (cairo_add_point_func_t) _cairo_polygon_line_to,
+			      &filler->polygon,
+			      &filler->current_point, b, c, d))
+    {
 	return CAIRO_STATUS_SUCCESS;
+    }
 
-    status = _cairo_spline_decompose (&spline, filler->tolerance);
-    if (status)
-	goto CLEANUP_SPLINE;
-
-    for (i = 1; i < spline.num_points; i++)
-	_cairo_polygon_line_to (polygon, &spline.points[i]);
-
-  CLEANUP_SPLINE:
+    _cairo_spline_decompose (&spline, filler->tolerance);
     _cairo_spline_fini (&spline);
 
     filler->current_point = *d;
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index 027ebed..b36f4d8 100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -890,33 +890,24 @@ _cpf_curve_to (void		*closure,
 	       cairo_point_t	*p3)
 {
     cpf_t *cpf = closure;
-    cairo_status_t status;
     cairo_spline_t spline;
-    int i;
 
     cairo_point_t *p0 = &cpf->current_point;
 
-    status = _cairo_spline_init (&spline, p0, p1, p2, p3);
-    if (status == CAIRO_INT_STATUS_DEGENERATE)
+    if (! _cairo_spline_init (&spline,
+			      (cairo_add_point_func_t) cpf->line_to,
+			      cpf->closure,
+			      p0, p1, p2, p3))
+    {
 	return CAIRO_STATUS_SUCCESS;
-
-    status = _cairo_spline_decompose (&spline, cpf->tolerance);
-    if (status)
-      goto out;
-
-    for (i=1; i < spline.num_points; i++) {
-	status = cpf->line_to (cpf->closure, &spline.points[i]);
-	if (status)
-	    goto out;
     }
 
-    cpf->current_point = *p3;
+    _cairo_spline_decompose (&spline, cpf->tolerance);
+    _cairo_spline_fini (&spline);
 
-    status = CAIRO_STATUS_SUCCESS;
+    cpf->current_point = *p3;
 
- out:
-    _cairo_spline_fini (&spline);
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c
index fcac9b1..2b9b057 100644
--- a/src/cairo-path-in-fill.c
+++ b/src/cairo-path-in-fill.c
@@ -165,8 +165,6 @@ _cairo_in_fill_curve_to (void *closure,
     cairo_in_fill_t *in_fill = closure;
     cairo_spline_t spline;
     cairo_fixed_t top, bot, left;
-    cairo_status_t status;
-    int i;
 
     /* first reject based on bbox */
     bot = top = in_fill->current_point.y;
@@ -187,21 +185,18 @@ _cairo_in_fill_curve_to (void *closure,
 	return CAIRO_STATUS_SUCCESS;
 
     /* XXX Investigate direct inspection of the inflections? */
-    status = _cairo_spline_init (&spline, &in_fill->current_point, b, c, d);
-    if (status == CAIRO_INT_STATUS_DEGENERATE)
+    if (! _cairo_spline_init (&spline,
+			      (cairo_add_point_func_t) _cairo_in_fill_line_to,
+			      in_fill,
+			      &in_fill->current_point, b, c, d))
+    {
 	return CAIRO_STATUS_SUCCESS;
+    }
 
-    status = _cairo_spline_decompose (&spline, in_fill->tolerance);
-    if (status)
-	goto CLEANUP_SPLINE;
-
-    for (i = 1; i < spline.num_points; i++)
-	_cairo_in_fill_line_to (in_fill, &spline.points[i]);
-
-  CLEANUP_SPLINE:
+    _cairo_spline_decompose (&spline, in_fill->tolerance);
     _cairo_spline_fini (&spline);
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index efccbcf..3c02a94 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -283,13 +283,17 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
 
 	tri[0] = in->point;
 	if (clockwise) {
-	    _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
+	    start =
+		_cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector);
+	    stop =
+		_cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector);
 	    step = -1;
-	    _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
 	} else {
-	    _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
+	    start =
+		_cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector);
+	    stop =
+		_cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector);
 	    step = +1;
-	    _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
 	}
 
 	i = start;
@@ -494,10 +498,10 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
 	cairo_pen_t *pen = &stroker->pen;
 
 	slope = f->dev_vector;
-	_cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
+	start = _cairo_pen_find_active_cw_vertex_index (pen, &slope);
 	slope.dx = -slope.dx;
 	slope.dy = -slope.dy;
-	_cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
+	stop = _cairo_pen_find_active_cw_vertex_index (pen, &slope);
 
 	tri[0] = f->point;
 	tri[1] = f->cw;
@@ -968,40 +972,51 @@ _cairo_stroker_curve_to (void *closure,
 			 cairo_point_t *c,
 			 cairo_point_t *d)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_stroker_t *stroker = closure;
-    cairo_spline_t spline;
-    cairo_pen_t pen;
+    cairo_pen_stroke_spline_t spline_pen;
     cairo_stroke_face_t start, end;
     cairo_point_t extra_points[4];
     cairo_point_t *a = &stroker->current_point;
     double initial_slope_dx, initial_slope_dy;
     double final_slope_dx, final_slope_dy;
+    cairo_status_t status;
 
-    status = _cairo_spline_init (&spline, a, b, c, d);
+    status = _cairo_pen_stroke_spline_init (&spline_pen,
+					    &stroker->pen,
+					    a, b, c, d);
     if (status == CAIRO_INT_STATUS_DEGENERATE)
 	return _cairo_stroker_line_to (closure, d);
+    else if (status)
+	return status;
 
-    status = _cairo_pen_init_copy (&pen, &stroker->pen);
-    if (status)
-	goto CLEANUP_SPLINE;
-
-    initial_slope_dx = _cairo_fixed_to_double (spline.initial_slope.dx);
-    initial_slope_dy = _cairo_fixed_to_double (spline.initial_slope.dy);
-    final_slope_dx = _cairo_fixed_to_double (spline.final_slope.dx);
-    final_slope_dy = _cairo_fixed_to_double (spline.final_slope.dy);
+    initial_slope_dx = _cairo_fixed_to_double (spline_pen.spline.initial_slope.dx);
+    initial_slope_dy = _cairo_fixed_to_double (spline_pen.spline.initial_slope.dy);
+    final_slope_dx = _cairo_fixed_to_double (spline_pen.spline.final_slope.dx);
+    final_slope_dy = _cairo_fixed_to_double (spline_pen.spline.final_slope.dy);
 
-    if (_compute_normalized_device_slope (&initial_slope_dx, &initial_slope_dy, stroker->ctm_inverse, NULL))
-	_compute_face (a, &spline.initial_slope, initial_slope_dx, initial_slope_dy, stroker, &start);
+    if (_compute_normalized_device_slope (&initial_slope_dx, &initial_slope_dy,
+					  stroker->ctm_inverse, NULL))
+    {
+	_compute_face (a,
+		       &spline_pen.spline.initial_slope,
+		       initial_slope_dx, initial_slope_dy,
+		       stroker, &start);
+    }
 
-    if (_compute_normalized_device_slope (&final_slope_dx, &final_slope_dy, stroker->ctm_inverse, NULL))
-	_compute_face (d, &spline.final_slope, final_slope_dx, final_slope_dy, stroker, &end);
+    if (_compute_normalized_device_slope (&final_slope_dx, &final_slope_dy,
+					  stroker->ctm_inverse, NULL))
+    {
+	_compute_face (d,
+		       &spline_pen.spline.final_slope,
+		       final_slope_dx, final_slope_dy,
+		       stroker, &end);
+    }
 
     if (stroker->has_current_face) {
 	status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
 	if (status)
 	    goto CLEANUP_PEN;
-    } else if (!stroker->has_first_face) {
+    } else if (! stroker->has_first_face) {
 	stroker->first_face = start;
 	stroker->has_first_face = TRUE;
     }
@@ -1021,18 +1036,16 @@ _cairo_stroker_curve_to (void *closure,
     extra_points[3].x -= end.point.x;
     extra_points[3].y -= end.point.y;
 
-    status = _cairo_pen_add_points (&pen, extra_points, 4);
+    status = _cairo_pen_add_points (&spline_pen.pen, extra_points, 4);
     if (status)
 	goto CLEANUP_PEN;
 
-    status = _cairo_pen_stroke_spline (&pen, &spline, stroker->tolerance, stroker->traps);
-    if (status)
-	goto CLEANUP_PEN;
+    status = _cairo_pen_stroke_spline (&spline_pen,
+				       stroker->tolerance,
+				       stroker->traps);
 
   CLEANUP_PEN:
-    _cairo_pen_fini (&pen);
-  CLEANUP_SPLINE:
-    _cairo_spline_fini (&spline);
+    _cairo_pen_stroke_spline_fini (&spline_pen);
 
     stroker->current_point = *d;
 
@@ -1063,16 +1076,20 @@ _cairo_stroker_curve_to_dashed (void *closure,
 				cairo_point_t *c,
 				cairo_point_t *d)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_stroker_t *stroker = closure;
     cairo_spline_t spline;
     cairo_point_t *a = &stroker->current_point;
     cairo_line_join_t line_join_save;
-    int i;
 
-    status = _cairo_spline_init (&spline, a, b, c, d);
-    if (status == CAIRO_INT_STATUS_DEGENERATE)
+    if (! _cairo_spline_init (&spline,
+			      stroker->dashed ?
+			      (cairo_add_point_func_t) _cairo_stroker_line_to_dashed :
+			      (cairo_add_point_func_t) _cairo_stroker_line_to,
+			      stroker,
+			      a, b, c, d))
+    {
 	return _cairo_stroker_line_to_dashed (closure, d);
+    }
 
     /* If the line width is so small that the pen is reduced to a
        single point, then we have nothing to do. */
@@ -1084,26 +1101,14 @@ _cairo_stroker_curve_to_dashed (void *closure,
     line_join_save = stroker->style->line_join;
     stroker->style->line_join = CAIRO_LINE_JOIN_ROUND;
 
-    status = _cairo_spline_decompose (&spline, stroker->tolerance);
-    if (status)
-	goto CLEANUP_GSTATE;
-
-    for (i = 1; i < spline.num_points; i++) {
-	if (stroker->dashed)
-	    status = _cairo_stroker_line_to_dashed (stroker, &spline.points[i]);
-	else
-	    status = _cairo_stroker_line_to (stroker, &spline.points[i]);
-	if (status)
-	    break;
-    }
+    _cairo_spline_decompose (&spline, stroker->tolerance);
 
-  CLEANUP_GSTATE:
     stroker->style->line_join = line_join_save;
 
   CLEANUP_SPLINE:
     _cairo_spline_fini (&spline);
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 425b3b9..43d344a 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -1,6 +1,7 @@
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2002 University of Southern California
+ * Copyright © 2008 Chris Wilson
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public
@@ -32,6 +33,7 @@
  *
  * Contributor(s):
  *	Carl D. Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
  */
 
 #include "cairoint.h"
@@ -42,9 +44,6 @@ _cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *mat
 static void
 _cairo_pen_compute_slopes (cairo_pen_t *pen);
 
-static void
-_cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_direction_t dir, cairo_polygon_t *polygon);
-
 cairo_status_t
 _cairo_pen_init (cairo_pen_t	*pen,
 		 double		 radius,
@@ -104,7 +103,7 @@ _cairo_pen_fini (cairo_pen_t *pen)
 }
 
 cairo_status_t
-_cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other)
+_cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other)
 {
     *pen = *other;
 
@@ -323,10 +322,9 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
  * pen's "extra points" from the spline's initial and final slopes are
  * properly found when beginning the spline stroking.]
  */
-void
-_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
-					cairo_slope_t *slope,
-					int *active)
+int
+_cairo_pen_find_active_cw_vertex_index (const cairo_pen_t *pen,
+					const cairo_slope_t *slope)
 {
     int i;
 
@@ -344,7 +342,7 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
     if (i == pen->num_vertices)
 	i = 0;
 
-    *active = i;
+    return i;
 }
 
 /* Find active pen vertex for counterclockwise edge of stroke at the given slope.
@@ -352,13 +350,12 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
  * Note: See the comments for _cairo_pen_find_active_cw_vertex_index
  * for some details about the strictness of the inequalities here.
  */
-void
-_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
-					 cairo_slope_t *slope,
-					 int *active)
+int
+_cairo_pen_find_active_ccw_vertex_index (const cairo_pen_t *pen,
+					 const cairo_slope_t *slope)
 {
-    int i;
     cairo_slope_t slope_reverse;
+    int i;
 
     slope_reverse = *slope;
     slope_reverse.dx = -slope_reverse.dx;
@@ -378,56 +375,26 @@ _cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
     if (i < 0)
 	i = pen->num_vertices - 1;
 
-    *active = i;
+    return i;
 }
 
-static void
-_cairo_pen_stroke_spline_half (cairo_pen_t *pen,
-			       cairo_spline_t *spline,
-			       cairo_direction_t dir,
-			       cairo_polygon_t *polygon)
+static int
+_cairo_pen_stroke_spline_add_convolved_point (cairo_pen_stroke_spline_t	*stroker,
+					      const cairo_point_t *last_point,
+					      const cairo_slope_t *slope,
+					      cairo_point_t *last_hull_point,
+					      int active,
+					      int step)
 {
-    int i;
-    int start, stop, step;
-    int active = 0;
-    cairo_point_t hull_point;
-    cairo_slope_t slope, initial_slope, final_slope;
-    cairo_point_t *point = spline->points;
-    int num_points = spline->num_points;
-
-    if (dir == CAIRO_DIRECTION_FORWARD) {
-	start = 0;
-	stop = num_points;
-	step = 1;
-	initial_slope = spline->initial_slope;
-	final_slope = spline->final_slope;
-    } else {
-	start = num_points - 1;
-	stop = -1;
-	step = -1;
-	initial_slope = spline->final_slope;
-	initial_slope.dx = -initial_slope.dx;
-	initial_slope.dy = -initial_slope.dy;
-	final_slope = spline->initial_slope;
-	final_slope.dx = -final_slope.dx;
-	final_slope.dy = -final_slope.dy;
-    }
-
-    _cairo_pen_find_active_cw_vertex_index (pen,
-	                                    &initial_slope,
-					    &active);
+    do {
+	cairo_point_t hull_point;
 
-    i = start;
-    while (i != stop) {
-	hull_point.x = point[i].x + pen->vertices[active].point.x;
-	hull_point.y = point[i].y + pen->vertices[active].point.y;
-
-	_cairo_polygon_line_to (polygon, &hull_point);
-
-	if (i + step == stop)
-	    slope = final_slope;
-	else
-	    _cairo_slope_init (&slope, &point[i], &point[i+step]);
+	hull_point.x = last_point->x + stroker->pen.vertices[active].point.x;
+	hull_point.y = last_point->y + stroker->pen.vertices[active].point.y;
+	_cairo_polygon_add_edge (&stroker->polygon,
+				 last_hull_point, &hull_point,
+				 step);
+	*last_hull_point = hull_point;
 
 	/* The strict inequalities here ensure that if a spline slope
 	 * compares identically with either of the slopes of the
@@ -439,53 +406,164 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
 	 * consider it unequal and reject. This is due to the inherent
 	 * ambiguity when comparing slopes that differ by exactly
 	 * pi. */
-	if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_ccw) > 0) {
-	    if (++active == pen->num_vertices)
+	if (_cairo_slope_compare (slope,
+				  &stroker->pen.vertices[active].slope_ccw) > 0)
+	{
+	    if (++active == stroker->pen.num_vertices)
 		active = 0;
-	} else if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_cw) < 0) {
+	}
+	else if (_cairo_slope_compare (slope,
+				       &stroker->pen.vertices[active].slope_cw) < 0)
+	{
 	    if (--active == -1)
-		active = pen->num_vertices - 1;
-	} else {
-	    i += step;
+		active = stroker->pen.num_vertices - 1;
 	}
-    }
+	else
+	{
+	    return active;
+	}
+    } while (TRUE);
 }
 
+
 /* Compute outline of a given spline using the pen.
-   The trapezoids needed to fill that outline will be added to traps
-*/
+ * The trapezoids needed to fill that outline will be added to traps
+ */
 cairo_status_t
-_cairo_pen_stroke_spline (cairo_pen_t		*pen,
-			  cairo_spline_t	*spline,
-			  double		tolerance,
-			  cairo_traps_t		*traps)
+_cairo_pen_stroke_spline (cairo_pen_stroke_spline_t	*stroker,
+			  double			 tolerance,
+			  cairo_traps_t			*traps)
 {
     cairo_status_t status;
-    cairo_polygon_t polygon;
+    cairo_slope_t slope;
 
     /* If the line width is so small that the pen is reduced to a
        single point, then we have nothing to do. */
-    if (pen->num_vertices <= 1)
+    if (stroker->pen.num_vertices <= 1)
 	return CAIRO_STATUS_SUCCESS;
 
-    _cairo_polygon_init (&polygon);
-
-    status = _cairo_spline_decompose (spline, tolerance);
+    /* open the polygon */
+    slope = stroker->spline.initial_slope;
+    stroker->forward_vertex =
+	_cairo_pen_find_active_cw_vertex_index (&stroker->pen, &slope);
+    stroker->forward_hull_point.x = stroker->last_point.x +
+	stroker->pen.vertices[stroker->forward_vertex].point.x;
+    stroker->forward_hull_point.y = stroker->last_point.y +
+	stroker->pen.vertices[stroker->forward_vertex].point.y;
+
+    slope.dx = -slope.dx;
+    slope.dy = -slope.dy;
+    stroker->backward_vertex =
+	_cairo_pen_find_active_cw_vertex_index (&stroker->pen, &slope);
+    stroker->backward_hull_point.x = stroker->last_point.x +
+	stroker->pen.vertices[stroker->backward_vertex].point.x;
+    stroker->backward_hull_point.y = stroker->last_point.y +
+	stroker->pen.vertices[stroker->backward_vertex].point.y;
+
+    _cairo_polygon_add_edge (&stroker->polygon,
+			     &stroker->backward_hull_point,
+			     &stroker->forward_hull_point,
+			     1);
+
+    _cairo_spline_decompose (&stroker->spline, tolerance);
+
+    /* close the polygon */
+    slope = stroker->spline.final_slope;
+    _cairo_pen_stroke_spline_add_convolved_point (stroker,
+						  &stroker->last_point,
+						  &slope,
+						  &stroker->forward_hull_point,
+						  stroker->forward_vertex,
+						  1);
+
+    slope.dx = -slope.dx;
+    slope.dy = -slope.dy;
+    _cairo_pen_stroke_spline_add_convolved_point (stroker,
+						  &stroker->last_point,
+						  &slope,
+						  &stroker->backward_hull_point,
+						  stroker->backward_vertex,
+						  -1);
+
+    _cairo_polygon_add_edge (&stroker->polygon,
+			     &stroker->forward_hull_point,
+			     &stroker->backward_hull_point,
+			     1);
+
+    status = _cairo_polygon_status (&stroker->polygon);
     if (status)
 	goto BAIL;
 
-    _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon);
+    status = _cairo_bentley_ottmann_tessellate_polygon (traps,
+							&stroker->polygon,
+							CAIRO_FILL_RULE_WINDING);
+BAIL:
 
-    _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon);
+    return status;
+}
 
-    _cairo_polygon_close (&polygon);
-    status = _cairo_polygon_status (&polygon);
-    if (status)
-	goto BAIL;
+static void
+_cairo_pen_stroke_spline_add_point (cairo_pen_stroke_spline_t	*stroker,
+				    const cairo_point_t		*point)
+{
+    cairo_slope_t slope;
+
+    _cairo_slope_init (&slope, &stroker->last_point, point);
+    stroker->forward_vertex =
+	_cairo_pen_stroke_spline_add_convolved_point (stroker,
+						      &stroker->last_point,
+						      &slope,
+						      &stroker->forward_hull_point,
+						      stroker->forward_vertex,
+						      1);
+
+    slope.dx = -slope.dx;
+    slope.dy = -slope.dy;
+    stroker->backward_vertex =
+	_cairo_pen_stroke_spline_add_convolved_point (stroker,
+						      &stroker->last_point,
+						      &slope,
+						      &stroker->backward_hull_point,
+						      stroker->backward_vertex,
+						      -1);
+    stroker->last_point = *point;
+}
 
-    status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
-BAIL:
-    _cairo_polygon_fini (&polygon);
+cairo_int_status_t
+_cairo_pen_stroke_spline_init (cairo_pen_stroke_spline_t *stroker,
+			       const cairo_pen_t *pen,
+			       const cairo_point_t *a,
+			       const cairo_point_t *b,
+			       const cairo_point_t *c,
+			       const cairo_point_t *d)
+{
+    cairo_int_status_t status;
 
-    return status;
+    if (! _cairo_spline_init (&stroker->spline,
+			      (cairo_add_point_func_t) _cairo_pen_stroke_spline_add_point,
+			      stroker,
+			      a, b, c, d))
+    {
+	return CAIRO_INT_STATUS_DEGENERATE;
+    }
+
+    status = _cairo_pen_init_copy (&stroker->pen, pen);
+    if (status) {
+	_cairo_spline_fini (&stroker->spline);
+	return status;
+    }
+
+    _cairo_polygon_init (&stroker->polygon);
+
+    stroker->last_point = *a;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+void
+_cairo_pen_stroke_spline_fini (cairo_pen_stroke_spline_t *stroker)
+{
+    _cairo_polygon_fini (&stroker->polygon);
+    _cairo_spline_fini (&stroker->spline);
+    _cairo_pen_fini (&stroker->pen);
 }
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index 1392bfa..95cadc9 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -84,16 +84,17 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
     return TRUE;
 }
 
-static void
+void
 _cairo_polygon_add_edge (cairo_polygon_t *polygon,
 			 const cairo_point_t *p1,
-			 const cairo_point_t *p2)
+			 const cairo_point_t *p2,
+			 int		      dir)
 {
     cairo_edge_t *edge;
 
     /* drop horizontal edges */
     if (p1->y == p2->y)
-	goto DONE;
+	return;
 
     if (polygon->num_edges == polygon->edges_size) {
 	if (! _cairo_polygon_grow (polygon))
@@ -104,15 +105,12 @@ _cairo_polygon_add_edge (cairo_polygon_t *polygon,
     if (p1->y < p2->y) {
 	edge->edge.p1 = *p1;
 	edge->edge.p2 = *p2;
-	edge->clockWise = 1;
+	edge->dir = dir;
     } else {
 	edge->edge.p1 = *p2;
 	edge->edge.p2 = *p1;
-	edge->clockWise = 0;
+	edge->dir = -dir;
     }
-
-  DONE:
-    _cairo_polygon_move_to (polygon, p2);
 }
 
 void
@@ -131,9 +129,9 @@ _cairo_polygon_line_to (cairo_polygon_t *polygon,
 			const cairo_point_t *point)
 {
     if (polygon->has_current_point)
-	_cairo_polygon_add_edge (polygon, &polygon->current_point, point);
-    else
-	_cairo_polygon_move_to (polygon, point);
+	_cairo_polygon_add_edge (polygon, &polygon->current_point, point, 1);
+
+    _cairo_polygon_move_to (polygon, point);
 }
 
 void
@@ -142,7 +140,8 @@ _cairo_polygon_close (cairo_polygon_t *polygon)
     if (polygon->has_current_point) {
 	_cairo_polygon_add_edge (polygon,
 				 &polygon->current_point,
-				 &polygon->first_point);
+				 &polygon->first_point,
+				 1);
 
 	polygon->has_current_point = FALSE;
     }
diff --git a/src/cairo-spline.c b/src/cairo-spline.c
index b39257e..7ec1c56 100644
--- a/src/cairo-spline.c
+++ b/src/cairo-spline.c
@@ -36,29 +36,16 @@
 
 #include "cairoint.h"
 
-static cairo_status_t
-_cairo_spline_grow (cairo_spline_t *spline);
-
-static cairo_status_t
-_cairo_spline_add_point (cairo_spline_t *spline, const cairo_point_t *point);
-
-static void
-_lerp_half (const cairo_point_t *a, const cairo_point_t *b, cairo_point_t *result);
-
-static void
-_de_casteljau (cairo_spline_knots_t *s1, cairo_spline_knots_t *s2);
-
-static double
-_cairo_spline_error_squared (const cairo_spline_knots_t *spline);
-
-static cairo_status_t
-_cairo_spline_decompose_into (cairo_spline_knots_t *spline, double tolerance_squared, cairo_spline_t *result);
-
-cairo_int_status_t
+cairo_bool_t
 _cairo_spline_init (cairo_spline_t *spline,
+		    void (*add_point_func) (void*, const cairo_point_t *),
+		    void *closure,
 		    const cairo_point_t *a, const cairo_point_t *b,
 		    const cairo_point_t *c, const cairo_point_t *d)
 {
+    spline->add_point_func = add_point_func;
+    spline->closure = closure;
+
     spline->knots.a = *a;
     spline->knots.b = *b;
     spline->knots.c = *c;
@@ -71,7 +58,7 @@ _cairo_spline_init (cairo_spline_t *spline,
     else if (a->x != d->x || a->y != d->y)
 	_cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.d);
     else
-	return CAIRO_INT_STATUS_DEGENERATE;
+	return FALSE;
 
     if (c->x != d->x || c->y != d->y)
 	_cairo_slope_init (&spline->final_slope, &spline->knots.c, &spline->knots.d);
@@ -80,74 +67,25 @@ _cairo_spline_init (cairo_spline_t *spline,
     else
 	_cairo_slope_init (&spline->final_slope, &spline->knots.a, &spline->knots.d);
 
-    spline->points = spline->points_embedded;
-    spline->points_size = ARRAY_LENGTH (spline->points_embedded);
-    spline->num_points = 0;
-
-    return CAIRO_STATUS_SUCCESS;
+    return TRUE;
 }
 
 void
 _cairo_spline_fini (cairo_spline_t *spline)
 {
-    if (spline->points != spline->points_embedded)
-	free (spline->points);
-
-    spline->points = spline->points_embedded;
-    spline->points_size = ARRAY_LENGTH (spline->points_embedded);
-    spline->num_points = 0;
-}
-
-/* make room for at least one more point */
-static cairo_status_t
-_cairo_spline_grow (cairo_spline_t *spline)
-{
-    cairo_point_t *new_points;
-    int old_size = spline->points_size;
-    int new_size = 2 * MAX (old_size, 16);
-
-    assert (spline->num_points <= spline->points_size);
-
-    if (spline->points == spline->points_embedded) {
-	new_points = _cairo_malloc_ab (new_size, sizeof (cairo_point_t));
-	if (new_points)
-	    memcpy (new_points, spline->points, old_size * sizeof (cairo_point_t));
-    } else {
-	new_points = _cairo_realloc_ab (spline->points,
-		                        new_size, sizeof (cairo_point_t));
-    }
-
-    if (new_points == NULL)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    spline->points = new_points;
-    spline->points_size = new_size;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static void
 _cairo_spline_add_point (cairo_spline_t *spline, const cairo_point_t *point)
 {
-    cairo_status_t status;
     cairo_point_t *prev;
 
-    if (spline->num_points) {
-	prev = &spline->points[spline->num_points - 1];
-	if (prev->x == point->x && prev->y == point->y)
-	    return CAIRO_STATUS_SUCCESS;
-    }
-
-    if (spline->num_points >= spline->points_size) {
-	status = _cairo_spline_grow (spline);
-	if (status)
-	    return status;
-    }
-
-    spline->points[spline->num_points] = *point;
-    spline->num_points++;
+    prev = &spline->last_point;
+    if (prev->x == point->x && prev->y == point->y)
+	return;
 
-    return CAIRO_STATUS_SUCCESS;
+    spline->add_point_func (spline->closure, point);
+    spline->last_point = *point;
 }
 
 static void
@@ -243,45 +181,28 @@ _cairo_spline_error_squared (const cairo_spline_knots_t *knots)
 	return cerr;
 }
 
-static cairo_status_t
+static void
 _cairo_spline_decompose_into (cairo_spline_knots_t *s1, double tolerance_squared, cairo_spline_t *result)
 {
     cairo_spline_knots_t s2;
-    cairo_status_t status;
 
     if (_cairo_spline_error_squared (s1) < tolerance_squared)
 	return _cairo_spline_add_point (result, &s1->a);
 
     _de_casteljau (s1, &s2);
 
-    status = _cairo_spline_decompose_into (s1, tolerance_squared, result);
-    if (status)
-	return status;
-
-    status = _cairo_spline_decompose_into (&s2, tolerance_squared, result);
-    if (status)
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
+    _cairo_spline_decompose_into (s1, tolerance_squared, result);
+    _cairo_spline_decompose_into (&s2, tolerance_squared, result);
 }
 
-cairo_status_t
+void
 _cairo_spline_decompose (cairo_spline_t *spline, double tolerance)
 {
-    cairo_status_t status;
     cairo_spline_knots_t s1;
 
-    /* reset the spline, but keep the buffer */
-    spline->num_points = 0;
-
     s1 = spline->knots;
-    status = _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline);
-    if (status)
-	return status;
-
-    status = _cairo_spline_add_point (spline, &spline->knots.d);
-    if (status)
-	return status;
+    spline->last_point = s1.a;
+    _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline);
 
-    return CAIRO_STATUS_SUCCESS;
+    _cairo_spline_add_point (spline, &spline->knots.d);
 }
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 905bc40..6f1354d 100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -265,9 +265,7 @@ typedef enum _cairo_clip_mode {
 
 typedef struct _cairo_edge {
     cairo_line_t edge;
-    int clockWise;
-
-    cairo_fixed_t current_x;
+    int dir;
 } cairo_edge_t;
 
 typedef struct _cairo_polygon {
@@ -287,15 +285,16 @@ typedef struct _cairo_spline_knots {
     cairo_point_t a, b, c, d;
 } cairo_spline_knots_t;
 typedef struct _cairo_spline {
+    void (*add_point_func) (void *, const cairo_point_t *);
+    void *closure;
+
     cairo_spline_knots_t knots;
 
     cairo_slope_t initial_slope;
     cairo_slope_t final_slope;
 
-    int num_points;
-    int points_size;
-    cairo_point_t *points;
-    cairo_point_t  points_embedded[64];
+    cairo_bool_t has_point;
+    cairo_point_t last_point;
 } cairo_spline_t;
 
 typedef struct _cairo_pen_vertex {
diff --git a/src/cairoint.h b/src/cairoint.h
index 940e33c..c0e9b21 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2114,7 +2114,7 @@ cairo_private void
 _cairo_pen_init_empty (cairo_pen_t *pen);
 
 cairo_private cairo_status_t
-_cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other);
+_cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other);
 
 cairo_private void
 _cairo_pen_fini (cairo_pen_t *pen);
@@ -2129,21 +2129,40 @@ _cairo_pen_add_points_for_slopes (cairo_pen_t *pen,
 				  cairo_point_t *c,
 				  cairo_point_t *d);
 
-cairo_private void
-_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
-					cairo_slope_t *slope,
-					int *active);
+cairo_private int
+_cairo_pen_find_active_cw_vertex_index (const cairo_pen_t *pen,
+					const cairo_slope_t *slope);
 
-cairo_private void
-_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
-					 cairo_slope_t *slope,
-					 int *active);
+cairo_private int
+_cairo_pen_find_active_ccw_vertex_index (const cairo_pen_t *pen,
+					 const cairo_slope_t *slope);
+
+typedef struct _cairo_pen_stroke_spline {
+    cairo_pen_t pen;
+    cairo_spline_t spline;
+    cairo_polygon_t polygon;
+    cairo_point_t last_point;
+    cairo_point_t forward_hull_point;
+    cairo_point_t backward_hull_point;
+    int forward_vertex;
+    int backward_vertex;
+} cairo_pen_stroke_spline_t;
+
+cairo_private cairo_int_status_t
+_cairo_pen_stroke_spline_init (cairo_pen_stroke_spline_t *stroker,
+			       const cairo_pen_t *pen,
+			       const cairo_point_t *a,
+			       const cairo_point_t *b,
+			       const cairo_point_t *c,
+			       const cairo_point_t *d);
 
 cairo_private cairo_status_t
-_cairo_pen_stroke_spline (cairo_pen_t *pen,
-			  cairo_spline_t *spline,
-			  double tolerance,
-			  cairo_traps_t *traps);
+_cairo_pen_stroke_spline (cairo_pen_stroke_spline_t	*pen,
+			  double			 tolerance,
+			  cairo_traps_t			*traps);
+
+cairo_private void
+_cairo_pen_stroke_spline_fini (cairo_pen_stroke_spline_t *stroker);
 
 /* cairo-polygon.c */
 cairo_private void
@@ -2153,6 +2172,12 @@ cairo_private void
 _cairo_polygon_fini (cairo_polygon_t *polygon);
 
 cairo_private void
+_cairo_polygon_add_edge (cairo_polygon_t *polygon,
+			 const cairo_point_t *p1,
+			 const cairo_point_t *p2,
+			 int dir);
+
+cairo_private void
 _cairo_polygon_move_to (cairo_polygon_t *polygon,
 			const cairo_point_t *point);
 
@@ -2166,14 +2191,16 @@ _cairo_polygon_close (cairo_polygon_t *polygon);
 #define _cairo_polygon_status(P) (P)->status
 
 /* cairo-spline.c */
-cairo_private cairo_int_status_t
+typedef void (*cairo_add_point_func_t) (void*, const cairo_point_t *);
+
+cairo_private cairo_bool_t
 _cairo_spline_init (cairo_spline_t *spline,
-		    const cairo_point_t *a,
-		    const cairo_point_t *b,
-		    const cairo_point_t *c,
-		    const cairo_point_t *d);
+		    cairo_add_point_func_t add_point_func,
+		    void *closure,
+		    const cairo_point_t *a, const cairo_point_t *b,
+		    const cairo_point_t *c, const cairo_point_t *d);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_spline_decompose (cairo_spline_t *spline, double tolerance);
 
 cairo_private void
commit 3bf8379408ce9b1e08d130bcd1076766e36f1bef
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Nov 14 09:50:29 2008 +0000

    [type1] Propagate fatal NO_MEMORY erro from FreeType.
    
    If FreeType fails to load the glyph, check for a fatal error before
    falling back (and effectively masking the fatal condition).

diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index bbff33d..e555758 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -553,14 +553,24 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f
 	error = FT_Load_Glyph (font->face, i,
 			       FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING |
 			       FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
-	if (error != 0)
+	if (error != FT_Err_Ok) {
+	    /* propagate fatal errors from FreeType */
+	    if (error == FT_Err_Out_Of_Memory)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	}
 
 	font->glyphs[i].width = font->face->glyph->metrics.horiAdvance;
 
 	error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
-	if (error != 0)
+	if (error != FT_Err_Ok) {
+	    /* propagate fatal errors from FreeType */
+	    if (error == FT_Err_Out_Of_Memory)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	}
 
 	font->glyphs[i].name = strdup (buffer);
 	if (font->glyphs[i].name == NULL)
commit db9ed77d8aa4f4b4c8410e52e5bbd16ffa94ee24
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 13 20:36:14 2008 +0000

    [cairo] FLush surface on cairo_destroy()
    
    When discussing the implications of snapshot cow, one of the questions
    that we raised was what happens on cairo_destroy()? The lifetime of the
    context implicitly marks the extents of the drawing operations, typically
    the expose event (or perhaps one phase of it). Therefore at the end of the
    sequence we implicitly wish to flush the graphics events to the surface.

diff --git a/src/cairo.c b/src/cairo.c
index 56f99e4..bd31063 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -212,6 +212,8 @@ cairo_reference (cairo_t *cr)
 void
 cairo_destroy (cairo_t *cr)
 {
+    cairo_surface_t *surface;
+
     if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
 	return;
 
@@ -225,6 +227,15 @@ cairo_destroy (cairo_t *cr)
 	    break;
     }
 
+    /* The context is expected (>99% of all use cases) to be held for the
+     * duration of a single expose event/sequence of graphic operations.
+     * Therefore, on destroy we explicitly flush the Cairo pipeline of any
+     * pending operations.
+     */
+    surface = _cairo_gstate_get_original_target (cr->gstate);
+    if (surface != NULL)
+	cairo_surface_flush (surface);
+
     _cairo_gstate_fini (cr->gstate);
     while (cr->gstate_freelist != NULL) {
 	cairo_gstate_t *gstate = cr->gstate_freelist;
commit 032be9849dfc32ec8802a4f086619755a3a397f5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 13 16:36:01 2008 +0000

    [skiplist] Inline testing.
    
    Add a loop to create a skip list to allow manual checking.

diff --git a/src/Makefile.am b/src/Makefile.am
index bf87efb..b09fadf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -84,9 +84,12 @@ TESTS += check-link$(EXEEXT)
 endif
 
 EXTRA_DIST += $(TESTS_SH) check-has-hidden-symbols.c
-check_PROGRAMS += check-link
+check_PROGRAMS += check-link check-skiplist
 check_link_LDADD = libcairo.la
 
+check_skiplist_SOURCES = cairo-skiplist.c
+check_skiplist_CPPFLAGS = -DMAIN $(AM_CPPFLAGS)
+
 check: headers-standalone
 
 PREPROCESS_ARGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS)
diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index 4037715..b08453b 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -305,3 +305,39 @@ _cairo_skip_list_delete_given (cairo_skip_list_t *list, skip_elt_t *given)
 	list->max_level--;
     free_elt (list, elt);
 }
+
+#if MAIN
+typedef struct {
+    int n;
+    skip_elt_t elt;
+} test_elt_t;
+
+static int
+test_cmp (void *list, void *A, void *B)
+{
+    const test_elt_t *a = A, *b = B;
+    return a->n - b->n;
+}
+
+int
+main (void)
+{
+    cairo_skip_list_t list;
+    test_elt_t elt;
+    int n;
+
+    _cairo_skip_list_init (&list, test_cmp, sizeof (test_elt_t));
+    for (n = 0; n < 10000000; n++) {
+	void *elt_and_data;
+	elt.n = n;
+	elt_and_data = _cairo_skip_list_insert (&list, &elt, TRUE);
+	assert (elt_and_data != NULL);
+    }
+    _cairo_skip_list_fini (&list);
+
+    return 0;
+}
+
+/* required supporting stubs */
+cairo_status_t _cairo_error (cairo_status_t status) { return status; }
+#endif
commit e44c1f26e48cfb2f74834b6a8ef8532b0bd28982
Author: M Joonas Pihlaja <jpihlaja at cc.helsinki.fi>
Date:   Sat Oct 18 01:15:44 2008 +0300

    Use a smaller and faster random number generator.
    
    The previous LFSR generator used a large table to be speedy.  The
    replacement generator is the single stage generator (1) from section
    5.4 of [HP2007], requires no tables or extra state.  I've run the
    generator through Rob Brown's extended Dieharder test suite and it
    passes all but one self-proclaimed buggy test (-d2) and the 2D sphere
    minimum distance test (-d12).
    
    [HP2007] Hars L. and Petruska G., ``Pseudorandom Recursions: Small and Fast Pseurodandom Number Generators for Embedded Applications'',
    Hindawi Publishing Corporation
    EURASIP Journal on Embedded Systems
    Volume 2007, Article ID 98417, 13 pages
    doi:10.1155/2007/98417
    http://www.hindawi.com/getarticle.aspx?doi=10.1155/2007/98417&e=cta

diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index e2b793e..4037715 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -28,201 +28,23 @@
 #define ELT_DATA(elt) (void *)	((char*) (elt) - list->data_size)
 #define NEXT_TO_ELT(next)	(skip_elt_t *) ((char *) (next) - offsetof (skip_elt_t, next))
 
-/* Four 256 element lookup tables back to back implementing a linear
- * feedback shift register of degree 32. */
-static unsigned const _cairo_lfsr_random_lut[1024] = {
- 0x00000000, 0x9a795537, 0xae8bff59, 0x34f2aa6e, 0xc76eab85, 0x5d17feb2,
- 0x69e554dc, 0xf39c01eb, 0x14a4023d, 0x8edd570a, 0xba2ffd64, 0x2056a853,
- 0xd3caa9b8, 0x49b3fc8f, 0x7d4156e1, 0xe73803d6, 0x2948047a, 0xb331514d,
- 0x87c3fb23, 0x1dbaae14, 0xee26afff, 0x745ffac8, 0x40ad50a6, 0xdad40591,
- 0x3dec0647, 0xa7955370, 0x9367f91e, 0x091eac29, 0xfa82adc2, 0x60fbf8f5,
- 0x5409529b, 0xce7007ac, 0x529008f4, 0xc8e95dc3, 0xfc1bf7ad, 0x6662a29a,
- 0x95fea371, 0x0f87f646, 0x3b755c28, 0xa10c091f, 0x46340ac9, 0xdc4d5ffe,
- 0xe8bff590, 0x72c6a0a7, 0x815aa14c, 0x1b23f47b, 0x2fd15e15, 0xb5a80b22,
- 0x7bd80c8e, 0xe1a159b9, 0xd553f3d7, 0x4f2aa6e0, 0xbcb6a70b, 0x26cff23c,
- 0x123d5852, 0x88440d65, 0x6f7c0eb3, 0xf5055b84, 0xc1f7f1ea, 0x5b8ea4dd,
- 0xa812a536, 0x326bf001, 0x06995a6f, 0x9ce00f58, 0xa52011e8, 0x3f5944df,
- 0x0babeeb1, 0x91d2bb86, 0x624eba6d, 0xf837ef5a, 0xccc54534, 0x56bc1003,
- 0xb18413d5, 0x2bfd46e2, 0x1f0fec8c, 0x8576b9bb, 0x76eab850, 0xec93ed67,
- 0xd8614709, 0x4218123e, 0x8c681592, 0x161140a5, 0x22e3eacb, 0xb89abffc,
- 0x4b06be17, 0xd17feb20, 0xe58d414e, 0x7ff41479, 0x98cc17af, 0x02b54298,
- 0x3647e8f6, 0xac3ebdc1, 0x5fa2bc2a, 0xc5dbe91d, 0xf1294373, 0x6b501644,
- 0xf7b0191c, 0x6dc94c2b, 0x593be645, 0xc342b372, 0x30deb299, 0xaaa7e7ae,
- 0x9e554dc0, 0x042c18f7, 0xe3141b21, 0x796d4e16, 0x4d9fe478, 0xd7e6b14f,
- 0x247ab0a4, 0xbe03e593, 0x8af14ffd, 0x10881aca, 0xdef81d66, 0x44814851,
- 0x7073e23f, 0xea0ab708, 0x1996b6e3, 0x83efe3d4, 0xb71d49ba, 0x2d641c8d,
- 0xca5c1f5b, 0x50254a6c, 0x64d7e002, 0xfeaeb535, 0x0d32b4de, 0x974be1e9,
- 0xa3b94b87, 0x39c01eb0, 0xd03976e7, 0x4a4023d0, 0x7eb289be, 0xe4cbdc89,
- 0x1757dd62, 0x8d2e8855, 0xb9dc223b, 0x23a5770c, 0xc49d74da, 0x5ee421ed,
- 0x6a168b83, 0xf06fdeb4, 0x03f3df5f, 0x998a8a68, 0xad782006, 0x37017531,
- 0xf971729d, 0x630827aa, 0x57fa8dc4, 0xcd83d8f3, 0x3e1fd918, 0xa4668c2f,
- 0x90942641, 0x0aed7376, 0xedd570a0, 0x77ac2597, 0x435e8ff9, 0xd927dace,
- 0x2abbdb25, 0xb0c28e12, 0x8430247c, 0x1e49714b, 0x82a97e13, 0x18d02b24,
- 0x2c22814a, 0xb65bd47d, 0x45c7d596, 0xdfbe80a1, 0xeb4c2acf, 0x71357ff8,
- 0x960d7c2e, 0x0c742919, 0x38868377, 0xa2ffd640, 0x5163d7ab, 0xcb1a829c,
- 0xffe828f2, 0x65917dc5, 0xabe17a69, 0x31982f5e, 0x056a8530, 0x9f13d007,
- 0x6c8fd1ec, 0xf6f684db, 0xc2042eb5, 0x587d7b82, 0xbf457854, 0x253c2d63,
- 0x11ce870d, 0x8bb7d23a, 0x782bd3d1, 0xe25286e6, 0xd6a02c88, 0x4cd979bf,
- 0x7519670f, 0xef603238, 0xdb929856, 0x41ebcd61, 0xb277cc8a, 0x280e99bd,
- 0x1cfc33d3, 0x868566e4, 0x61bd6532, 0xfbc43005, 0xcf369a6b, 0x554fcf5c,
- 0xa6d3ceb7, 0x3caa9b80, 0x085831ee, 0x922164d9, 0x5c516375, 0xc6283642,
- 0xf2da9c2c, 0x68a3c91b, 0x9b3fc8f0, 0x01469dc7, 0x35b437a9, 0xafcd629e,
- 0x48f56148, 0xd28c347f, 0xe67e9e11, 0x7c07cb26, 0x8f9bcacd, 0x15e29ffa,
- 0x21103594, 0xbb6960a3, 0x27896ffb, 0xbdf03acc, 0x890290a2, 0x137bc595,
- 0xe0e7c47e, 0x7a9e9149, 0x4e6c3b27, 0xd4156e10, 0x332d6dc6, 0xa95438f1,
- 0x9da6929f, 0x07dfc7a8, 0xf443c643, 0x6e3a9374, 0x5ac8391a, 0xc0b16c2d,
- 0x0ec16b81, 0x94b83eb6, 0xa04a94d8, 0x3a33c1ef, 0xc9afc004, 0x53d69533,
- 0x67243f5d, 0xfd5d6a6a, 0x1a6569bc, 0x801c3c8b, 0xb4ee96e5, 0x2e97c3d2,
- 0xdd0bc239, 0x4772970e, 0x73803d60, 0xe9f96857, 0x00000000, 0x3a0bb8f9,
- 0x741771f2, 0x4e1cc90b, 0xe82ee3e4, 0xd2255b1d, 0x9c399216, 0xa6322aef,
- 0x4a2492ff, 0x702f2a06, 0x3e33e30d, 0x04385bf4, 0xa20a711b, 0x9801c9e2,
- 0xd61d00e9, 0xec16b810, 0x944925fe, 0xae429d07, 0xe05e540c, 0xda55ecf5,
- 0x7c67c61a, 0x466c7ee3, 0x0870b7e8, 0x327b0f11, 0xde6db701, 0xe4660ff8,
- 0xaa7ac6f3, 0x90717e0a, 0x364354e5, 0x0c48ec1c, 0x42542517, 0x785f9dee,
- 0xb2eb1ecb, 0x88e0a632, 0xc6fc6f39, 0xfcf7d7c0, 0x5ac5fd2f, 0x60ce45d6,
- 0x2ed28cdd, 0x14d93424, 0xf8cf8c34, 0xc2c434cd, 0x8cd8fdc6, 0xb6d3453f,
- 0x10e16fd0, 0x2aead729, 0x64f61e22, 0x5efda6db, 0x26a23b35, 0x1ca983cc,
- 0x52b54ac7, 0x68bef23e, 0xce8cd8d1, 0xf4876028, 0xba9ba923, 0x809011da,
- 0x6c86a9ca, 0x568d1133, 0x1891d838, 0x229a60c1, 0x84a84a2e, 0xbea3f2d7,
- 0xf0bf3bdc, 0xcab48325, 0xffaf68a1, 0xc5a4d058, 0x8bb81953, 0xb1b3a1aa,
- 0x17818b45, 0x2d8a33bc, 0x6396fab7, 0x599d424e, 0xb58bfa5e, 0x8f8042a7,
- 0xc19c8bac, 0xfb973355, 0x5da519ba, 0x67aea143, 0x29b26848, 0x13b9d0b1,
- 0x6be64d5f, 0x51edf5a6, 0x1ff13cad, 0x25fa8454, 0x83c8aebb, 0xb9c31642,
- 0xf7dfdf49, 0xcdd467b0, 0x21c2dfa0, 0x1bc96759, 0x55d5ae52, 0x6fde16ab,
- 0xc9ec3c44, 0xf3e784bd, 0xbdfb4db6, 0x87f0f54f, 0x4d44766a, 0x774fce93,
- 0x39530798, 0x0358bf61, 0xa56a958e, 0x9f612d77, 0xd17de47c, 0xeb765c85,
- 0x0760e495, 0x3d6b5c6c, 0x73779567, 0x497c2d9e, 0xef4e0771, 0xd545bf88,
- 0x9b597683, 0xa152ce7a, 0xd90d5394, 0xe306eb6d, 0xad1a2266, 0x97119a9f,
- 0x3123b070, 0x0b280889, 0x4534c182, 0x7f3f797b, 0x9329c16b, 0xa9227992,
- 0xe73eb099, 0xdd350860, 0x7b07228f, 0x410c9a76, 0x0f10537d, 0x351beb84,
- 0x65278475, 0x5f2c3c8c, 0x1130f587, 0x2b3b4d7e, 0x8d096791, 0xb702df68,
- 0xf91e1663, 0xc315ae9a, 0x2f03168a, 0x1508ae73, 0x5b146778, 0x611fdf81,
- 0xc72df56e, 0xfd264d97, 0xb33a849c, 0x89313c65, 0xf16ea18b, 0xcb651972,
- 0x8579d079, 0xbf726880, 0x1940426f, 0x234bfa96, 0x6d57339d, 0x575c8b64,
- 0xbb4a3374, 0x81418b8d, 0xcf5d4286, 0xf556fa7f, 0x5364d090, 0x696f6869,
- 0x2773a162, 0x1d78199b, 0xd7cc9abe, 0xedc72247, 0xa3dbeb4c, 0x99d053b5,
- 0x3fe2795a, 0x05e9c1a3, 0x4bf508a8, 0x71feb051, 0x9de80841, 0xa7e3b0b8,
- 0xe9ff79b3, 0xd3f4c14a, 0x75c6eba5, 0x4fcd535c, 0x01d19a57, 0x3bda22ae,
- 0x4385bf40, 0x798e07b9, 0x3792ceb2, 0x0d99764b, 0xabab5ca4, 0x91a0e45d,
- 0xdfbc2d56, 0xe5b795af, 0x09a12dbf, 0x33aa9546, 0x7db65c4d, 0x47bde4b4,
- 0xe18fce5b, 0xdb8476a2, 0x9598bfa9, 0xaf930750, 0x9a88ecd4, 0xa083542d,
- 0xee9f9d26, 0xd49425df, 0x72a60f30, 0x48adb7c9, 0x06b17ec2, 0x3cbac63b,
- 0xd0ac7e2b, 0xeaa7c6d2, 0xa4bb0fd9, 0x9eb0b720, 0x38829dcf, 0x02892536,
- 0x4c95ec3d, 0x769e54c4, 0x0ec1c92a, 0x34ca71d3, 0x7ad6b8d8, 0x40dd0021,
- 0xe6ef2ace, 0xdce49237, 0x92f85b3c, 0xa8f3e3c5, 0x44e55bd5, 0x7eeee32c,
- 0x30f22a27, 0x0af992de, 0xaccbb831, 0x96c000c8, 0xd8dcc9c3, 0xe2d7713a,
- 0x2863f21f, 0x12684ae6, 0x5c7483ed, 0x667f3b14, 0xc04d11fb, 0xfa46a902,
- 0xb45a6009, 0x8e51d8f0, 0x624760e0, 0x584cd819, 0x16501112, 0x2c5ba9eb,
- 0x8a698304, 0xb0623bfd, 0xfe7ef2f6, 0xc4754a0f, 0xbc2ad7e1, 0x86216f18,
- 0xc83da613, 0xf2361eea, 0x54043405, 0x6e0f8cfc, 0x201345f7, 0x1a18fd0e,
- 0xf60e451e, 0xcc05fde7, 0x821934ec, 0xb8128c15, 0x1e20a6fa, 0x242b1e03,
- 0x6a37d708, 0x503c6ff1, 0x00000000, 0xca4f08ea, 0x0ee744e3, 0xc4a84c09,
- 0x1dce89c6, 0xd781812c, 0x1329cd25, 0xd966c5cf, 0x3b9d138c, 0xf1d21b66,
- 0x357a576f, 0xff355f85, 0x26539a4a, 0xec1c92a0, 0x28b4dea9, 0xe2fbd643,
- 0x773a2718, 0xbd752ff2, 0x79dd63fb, 0xb3926b11, 0x6af4aede, 0xa0bba634,
- 0x6413ea3d, 0xae5ce2d7, 0x4ca73494, 0x86e83c7e, 0x42407077, 0x880f789d,
- 0x5169bd52, 0x9b26b5b8, 0x5f8ef9b1, 0x95c1f15b, 0xee744e30, 0x243b46da,
- 0xe0930ad3, 0x2adc0239, 0xf3bac7f6, 0x39f5cf1c, 0xfd5d8315, 0x37128bff,
- 0xd5e95dbc, 0x1fa65556, 0xdb0e195f, 0x114111b5, 0xc827d47a, 0x0268dc90,
- 0xc6c09099, 0x0c8f9873, 0x994e6928, 0x530161c2, 0x97a92dcb, 0x5de62521,
- 0x8480e0ee, 0x4ecfe804, 0x8a67a40d, 0x4028ace7, 0xa2d37aa4, 0x689c724e,
- 0xac343e47, 0x667b36ad, 0xbf1df362, 0x7552fb88, 0xb1fab781, 0x7bb5bf6b,
- 0x4691c957, 0x8cdec1bd, 0x48768db4, 0x8239855e, 0x5b5f4091, 0x9110487b,
- 0x55b80472, 0x9ff70c98, 0x7d0cdadb, 0xb743d231, 0x73eb9e38, 0xb9a496d2,
- 0x60c2531d, 0xaa8d5bf7, 0x6e2517fe, 0xa46a1f14, 0x31abee4f, 0xfbe4e6a5,
- 0x3f4caaac, 0xf503a246, 0x2c656789, 0xe62a6f63, 0x2282236a, 0xe8cd2b80,
- 0x0a36fdc3, 0xc079f529, 0x04d1b920, 0xce9eb1ca, 0x17f87405, 0xddb77cef,
- 0x191f30e6, 0xd350380c, 0xa8e58767, 0x62aa8f8d, 0xa602c384, 0x6c4dcb6e,
- 0xb52b0ea1, 0x7f64064b, 0xbbcc4a42, 0x718342a8, 0x937894eb, 0x59379c01,
- 0x9d9fd008, 0x57d0d8e2, 0x8eb61d2d, 0x44f915c7, 0x805159ce, 0x4a1e5124,
- 0xdfdfa07f, 0x1590a895, 0xd138e49c, 0x1b77ec76, 0xc21129b9, 0x085e2153,
- 0xccf66d5a, 0x06b965b0, 0xe442b3f3, 0x2e0dbb19, 0xeaa5f710, 0x20eafffa,
- 0xf98c3a35, 0x33c332df, 0xf76b7ed6, 0x3d24763c, 0x8d2392ae, 0x476c9a44,
- 0x83c4d64d, 0x498bdea7, 0x90ed1b68, 0x5aa21382, 0x9e0a5f8b, 0x54455761,
- 0xb6be8122, 0x7cf189c8, 0xb859c5c1, 0x7216cd2b, 0xab7008e4, 0x613f000e,
- 0xa5974c07, 0x6fd844ed, 0xfa19b5b6, 0x3056bd5c, 0xf4fef155, 0x3eb1f9bf,
- 0xe7d73c70, 0x2d98349a, 0xe9307893, 0x237f7079, 0xc184a63a, 0x0bcbaed0,
- 0xcf63e2d9, 0x052cea33, 0xdc4a2ffc, 0x16052716, 0xd2ad6b1f, 0x18e263f5,
- 0x6357dc9e, 0xa918d474, 0x6db0987d, 0xa7ff9097, 0x7e995558, 0xb4d65db2,
- 0x707e11bb, 0xba311951, 0x58cacf12, 0x9285c7f8, 0x562d8bf1, 0x9c62831b,
- 0x450446d4, 0x8f4b4e3e, 0x4be30237, 0x81ac0add, 0x146dfb86, 0xde22f36c,
- 0x1a8abf65, 0xd0c5b78f, 0x09a37240, 0xc3ec7aaa, 0x074436a3, 0xcd0b3e49,
- 0x2ff0e80a, 0xe5bfe0e0, 0x2117ace9, 0xeb58a403, 0x323e61cc, 0xf8716926,
- 0x3cd9252f, 0xf6962dc5, 0xcbb25bf9, 0x01fd5313, 0xc5551f1a, 0x0f1a17f0,
- 0xd67cd23f, 0x1c33dad5, 0xd89b96dc, 0x12d49e36, 0xf02f4875, 0x3a60409f,
- 0xfec80c96, 0x3487047c, 0xede1c1b3, 0x27aec959, 0xe3068550, 0x29498dba,
- 0xbc887ce1, 0x76c7740b, 0xb26f3802, 0x782030e8, 0xa146f527, 0x6b09fdcd,
- 0xafa1b1c4, 0x65eeb92e, 0x87156f6d, 0x4d5a6787, 0x89f22b8e, 0x43bd2364,
- 0x9adbe6ab, 0x5094ee41, 0x943ca248, 0x5e73aaa2, 0x25c615c9, 0xef891d23,
- 0x2b21512a, 0xe16e59c0, 0x38089c0f, 0xf24794e5, 0x36efd8ec, 0xfca0d006,
- 0x1e5b0645, 0xd4140eaf, 0x10bc42a6, 0xdaf34a4c, 0x03958f83, 0xc9da8769,
- 0x0d72cb60, 0xc73dc38a, 0x52fc32d1, 0x98b33a3b, 0x5c1b7632, 0x96547ed8,
- 0x4f32bb17, 0x857db3fd, 0x41d5fff4, 0x8b9af71e, 0x6961215d, 0xa32e29b7,
- 0x678665be, 0xadc96d54, 0x74afa89b, 0xbee0a071, 0x7a48ec78, 0xb007e492,
- 0x00000000, 0x803e706b, 0x9a05b5e1, 0x1a3bc58a, 0xae723ef5, 0x2e4c4e9e,
- 0x34778b14, 0xb449fb7f, 0xc69d28dd, 0x46a358b6, 0x5c989d3c, 0xdca6ed57,
- 0x68ef1628, 0xe8d16643, 0xf2eaa3c9, 0x72d4d3a2, 0x1743048d, 0x977d74e6,
- 0x8d46b16c, 0x0d78c107, 0xb9313a78, 0x390f4a13, 0x23348f99, 0xa30afff2,
- 0xd1de2c50, 0x51e05c3b, 0x4bdb99b1, 0xcbe5e9da, 0x7fac12a5, 0xff9262ce,
- 0xe5a9a744, 0x6597d72f, 0x2e86091a, 0xaeb87971, 0xb483bcfb, 0x34bdcc90,
- 0x80f437ef, 0x00ca4784, 0x1af1820e, 0x9acff265, 0xe81b21c7, 0x682551ac,
- 0x721e9426, 0xf220e44d, 0x46691f32, 0xc6576f59, 0xdc6caad3, 0x5c52dab8,
- 0x39c50d97, 0xb9fb7dfc, 0xa3c0b876, 0x23fec81d, 0x97b73362, 0x17894309,
- 0x0db28683, 0x8d8cf6e8, 0xff58254a, 0x7f665521, 0x655d90ab, 0xe563e0c0,
- 0x512a1bbf, 0xd1146bd4, 0xcb2fae5e, 0x4b11de35, 0x5d0c1234, 0xdd32625f,
- 0xc709a7d5, 0x4737d7be, 0xf37e2cc1, 0x73405caa, 0x697b9920, 0xe945e94b,
- 0x9b913ae9, 0x1baf4a82, 0x01948f08, 0x81aaff63, 0x35e3041c, 0xb5dd7477,
- 0xafe6b1fd, 0x2fd8c196, 0x4a4f16b9, 0xca7166d2, 0xd04aa358, 0x5074d333,
- 0xe43d284c, 0x64035827, 0x7e389dad, 0xfe06edc6, 0x8cd23e64, 0x0cec4e0f,
- 0x16d78b85, 0x96e9fbee, 0x22a00091, 0xa29e70fa, 0xb8a5b570, 0x389bc51b,
- 0x738a1b2e, 0xf3b46b45, 0xe98faecf, 0x69b1dea4, 0xddf825db, 0x5dc655b0,
- 0x47fd903a, 0xc7c3e051, 0xb51733f3, 0x35294398, 0x2f128612, 0xaf2cf679,
- 0x1b650d06, 0x9b5b7d6d, 0x8160b8e7, 0x015ec88c, 0x64c91fa3, 0xe4f76fc8,
- 0xfeccaa42, 0x7ef2da29, 0xcabb2156, 0x4a85513d, 0x50be94b7, 0xd080e4dc,
- 0xa254377e, 0x226a4715, 0x3851829f, 0xb86ff2f4, 0x0c26098b, 0x8c1879e0,
- 0x9623bc6a, 0x161dcc01, 0xba182468, 0x3a265403, 0x201d9189, 0xa023e1e2,
- 0x146a1a9d, 0x94546af6, 0x8e6faf7c, 0x0e51df17, 0x7c850cb5, 0xfcbb7cde,
- 0xe680b954, 0x66bec93f, 0xd2f73240, 0x52c9422b, 0x48f287a1, 0xc8ccf7ca,
- 0xad5b20e5, 0x2d65508e, 0x375e9504, 0xb760e56f, 0x03291e10, 0x83176e7b,
- 0x992cabf1, 0x1912db9a, 0x6bc60838, 0xebf87853, 0xf1c3bdd9, 0x71fdcdb2,
- 0xc5b436cd, 0x458a46a6, 0x5fb1832c, 0xdf8ff347, 0x949e2d72, 0x14a05d19,
- 0x0e9b9893, 0x8ea5e8f8, 0x3aec1387, 0xbad263ec, 0xa0e9a666, 0x20d7d60d,
- 0x520305af, 0xd23d75c4, 0xc806b04e, 0x4838c025, 0xfc713b5a, 0x7c4f4b31,
- 0x66748ebb, 0xe64afed0, 0x83dd29ff, 0x03e35994, 0x19d89c1e, 0x99e6ec75,
- 0x2daf170a, 0xad916761, 0xb7aaa2eb, 0x3794d280, 0x45400122, 0xc57e7149,
- 0xdf45b4c3, 0x5f7bc4a8, 0xeb323fd7, 0x6b0c4fbc, 0x71378a36, 0xf109fa5d,
- 0xe714365c, 0x672a4637, 0x7d1183bd, 0xfd2ff3d6, 0x496608a9, 0xc95878c2,
- 0xd363bd48, 0x535dcd23, 0x21891e81, 0xa1b76eea, 0xbb8cab60, 0x3bb2db0b,
- 0x8ffb2074, 0x0fc5501f, 0x15fe9595, 0x95c0e5fe, 0xf05732d1, 0x706942ba,
- 0x6a528730, 0xea6cf75b, 0x5e250c24, 0xde1b7c4f, 0xc420b9c5, 0x441ec9ae,
- 0x36ca1a0c, 0xb6f46a67, 0xaccfafed, 0x2cf1df86, 0x98b824f9, 0x18865492,
- 0x02bd9118, 0x8283e173, 0xc9923f46, 0x49ac4f2d, 0x53978aa7, 0xd3a9facc,
- 0x67e001b3, 0xe7de71d8, 0xfde5b452, 0x7ddbc439, 0x0f0f179b, 0x8f3167f0,
- 0x950aa27a, 0x1534d211, 0xa17d296e, 0x21435905, 0x3b789c8f, 0xbb46ece4,
- 0xded13bcb, 0x5eef4ba0, 0x44d48e2a, 0xc4eafe41, 0x70a3053e, 0xf09d7555,
- 0xeaa6b0df, 0x6a98c0b4, 0x184c1316, 0x9872637d, 0x8249a6f7, 0x0277d69c,
- 0xb63e2de3, 0x36005d88, 0x2c3b9802, 0xac05e869};
-
-static unsigned _cairo_lfsr_random_state = 0x12345678;
-
-static unsigned
-lfsr_random(void)
+static uint32_t
+hars_petruska_f54_1_random (void)
 {
-    unsigned next;
-    next  = _cairo_lfsr_random_lut[((_cairo_lfsr_random_state>> 0) & 0xFF) + 0*256];
-    next ^= _cairo_lfsr_random_lut[((_cairo_lfsr_random_state>> 8) & 0xFF) + 1*256];
-    next ^= _cairo_lfsr_random_lut[((_cairo_lfsr_random_state>>16) & 0xFF) + 2*256];
-    next ^= _cairo_lfsr_random_lut[((_cairo_lfsr_random_state>>24) & 0xFF) + 3*256];
-    return _cairo_lfsr_random_state = next;
+#  define rol(x,k) ((x << k) | (x >> (32-k)))
+    static uint32_t x = 0;
+    x = (x ^ rol(x, 5) ^ rol(x, 24)) + 0x37798849;
+    return x;
+#  undef rol
 }
 
 /*
  * Initialize an empty skip list
  */
 void
-_cairo_skip_list_init (cairo_skip_list_t		*list,
-		cairo_skip_list_compare_t	 compare,
-		size_t			 elt_size)
+_cairo_skip_list_init (cairo_skip_list_t	*list,
+                       cairo_skip_list_compare_t compare,
+                       size_t			 elt_size)
 {
     int i;
 
@@ -273,7 +95,7 @@ random_level (void)
     /* tricky bit -- each bit is '1' 75% of the time.
      * This works because we only use the lower MAX_LEVEL
      * bits, and MAX_LEVEL < 16 */
-    long int	bits = lfsr_random();
+    uint32_t bits = hars_petruska_f54_1_random ();
     bits |= bits >> 16;
 
     while (++level < MAX_LEVEL)
commit a4c5371b5e6d0df71efc75fee6f6a8fe8c6d3488
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 13 14:56:38 2008 +0000

    [os2] Move include cairo.h before os2.h
    
    The defines need to come first, but we specify that cairo.h is the first
    header file to be included by files.

diff --git a/src/cairo-os2.h b/src/cairo-os2.h
index 17f0263..0d18674 100644
--- a/src/cairo-os2.h
+++ b/src/cairo-os2.h
@@ -44,10 +44,10 @@
 #define INCL_WIN
 #define INCL_GPI
 
-#include <os2.h>
-
 #include "cairo.h"
 
+#include <os2.h>
+
 CAIRO_BEGIN_DECLS
 
 /* The OS/2 Specific Cairo API */


More information about the cairo-commit mailing list