summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog47
-rw-r--r--src/cairo-fixed.c7
-rw-r--r--src/cairo-ft-font.c56
-rw-r--r--src/cairo-gstate.c88
-rw-r--r--src/cairo-path-bounds.c23
-rw-r--r--src/cairo-path-fill.c58
-rw-r--r--src/cairo-path-stroke.c107
-rw-r--r--src/cairo-path.c111
-rw-r--r--src/cairo-traps.c2
-rw-r--r--src/cairo.h13
-rw-r--r--src/cairo_fixed.c7
-rw-r--r--src/cairo_ft_font.c56
-rw-r--r--src/cairo_gstate.c88
-rw-r--r--src/cairo_path.c111
-rw-r--r--src/cairo_path_bounds.c23
-rw-r--r--src/cairo_path_fill.c58
-rw-r--r--src/cairo_path_stroke.c107
-rw-r--r--src/cairo_traps.c2
-rw-r--r--src/cairoint.h63
19 files changed, 573 insertions, 454 deletions
diff --git a/ChangeLog b/ChangeLog
index d934bbc3..663bd027 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2004-02-12 Carl Worth <cworth@isi.edu>
+
+ * src/cairo.h: Add typedefs for new callbacks to be used by
+ cairo_current_path: cairo_move_to_func, cairo_line_to_func,
+ cairo_curve_to_func, and cairo_close_path_func.
+
+ * src/cairoint.h: cairo_path.last_move_point and
+ cairo_path.current_point are now fixed-point not doubles for
+ consistency.
+
+ * src/cairo_path.c (_cairo_path_interpret): Now accept 4 explicit
+ function pointers rather than a structure. Eliminate unnecessary
+ done_path callback.
+
+ * src/cairo_path_bounds.c (_cairo_path_bounds):
+ * src/cairo_path_stroke.c (_cairo_path_stroke_to_traps):
+ * src/cairo_path_fill.c (_cairo_path_fill_to_traps): Track change
+ in _cairo_path_interpret. Code previously in done_path callback is
+ now here immediately after call to _cairo_path_interpret.
+
+ * src/cairo_path.c (_cairo_path_move_to):
+ (_cairo_path_rel_move_to):
+ (_cairo_path_line_to):
+ (_cairo_path_rel_line_to):
+ (_cairo_path_curve_to):
+ (_cairo_path_rel_curve_to):
+ (_cairo_path_current_point): Internal _cairo_path API modified to
+ accept fixed-point data everywhere. Much cleaner this way.
+
+ * src/cairo_gstate.c (_cairo_gstate_move_to):
+ (_cairo_gstate_line_to):
+ (_cairo_gstate_curve_to):
+ (_cairo_gstate_rel_move_to):
+ (_cairo_gstate_rel_line_to):
+ (_cairo_gstate_rel_curve_to):
+ (_cairo_gstate_current_point):
+ (_cairo_gstate_show_text):
+ (_cairo_gstate_text_path): Have to convert doubles to fixed-point
+ to track changes in _cairo_path API.
+
+ * src/cairo_ft_font.c (_move_to, _line_to, _conic_to, _cubic_to):
+ Keep data in fixed-point rather than going through intermediate
+ doubles. Track changes in _cairo_path API.
+
+ * src/cairo_fixed.c (_cairo_fixed_from_26_6): New function to help
+ when working with freetype.
+
2004-02-02 Jamey Sharp <jamey@minilop.net>
* configure.in:
diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c
index 33088546..9a7e7bc4 100644
--- a/src/cairo-fixed.c
+++ b/src/cairo-fixed.c
@@ -39,8 +39,15 @@ _cairo_fixed_from_double (double d)
return (cairo_fixed_t) (d * 65536);
}
+cairo_fixed_t
+_cairo_fixed_from_26_6 (uint32_t i)
+{
+ return i << 10;
+}
+
double
_cairo_fixed_to_double (cairo_fixed_t f)
{
return ((double) f) / 65536.0;
}
+
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 3b01f2d0..1b04397c 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -593,11 +593,13 @@ static int
_move_to (FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
+ cairo_point_t point;
+
+ point.x = _cairo_fixed_from_26_6 (to->x);
+ point.y = _cairo_fixed_from_26_6 (to->y);
_cairo_path_close_path (path);
- _cairo_path_move_to (path,
- DOUBLE_FROM_26_6(to->x),
- DOUBLE_FROM_26_6(to->y));
+ _cairo_path_move_to (path, &point);
return 0;
}
@@ -606,10 +608,12 @@ static int
_line_to (FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
+ cairo_point_t point;
+
+ point.x = _cairo_fixed_from_26_6 (to->x);
+ point.y = _cairo_fixed_from_26_6 (to->y);
- _cairo_path_line_to (path,
- DOUBLE_FROM_26_6(to->x),
- DOUBLE_FROM_26_6(to->y));
+ _cairo_path_line_to (path, &point);
return 0;
}
@@ -619,18 +623,25 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
- double x1, y1;
- double x2 = DOUBLE_FROM_26_6(control->x);
- double y2 = DOUBLE_FROM_26_6(control->y);
- double x3 = DOUBLE_FROM_26_6(to->x);
- double y3 = DOUBLE_FROM_26_6(to->y);
+ cairo_point_t p0, p1, p2, p3;
+ cairo_point_t conic;
+
+ _cairo_path_current_point (path, &p0);
+
+ conic.x = _cairo_fixed_from_26_6 (control->x);
+ conic.y = _cairo_fixed_from_26_6 (control->y);
+
+ p3.x = _cairo_fixed_from_26_6 (to->x);
+ p3.y = _cairo_fixed_from_26_6 (to->y);
- _cairo_path_current_point (path, &x1, &y1);
+ p1.x = p0.x + 2.0/3.0 * (conic.x - p0.x);
+ p1.y = p0.y + 2.0/3.0 * (conic.y - p0.y);
+
+ p2.x = p3.x + 2.0/3.0 * (conic.x - p3.x);
+ p2.y = p3.y + 2.0/3.0 * (conic.y - p3.y);
_cairo_path_curve_to (path,
- x1 + 2.0/3.0 * (x2 - x1), y1 + 2.0/3.0 * (y2 - y1),
- x3 + 2.0/3.0 * (x2 - x3), y3 + 2.0/3.0 * (y2 - y3),
- x3, y3);
+ &p1, &p2, &p3);
return 0;
}
@@ -639,11 +650,18 @@ static int
_cubic_to (FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
+ cairo_point_t p0, p1, p2;
+
+ p0.x = _cairo_fixed_from_26_6 (control1->x);
+ p0.y = _cairo_fixed_from_26_6 (control1->y);
+
+ p1.x = _cairo_fixed_from_26_6 (control2->x);
+ p1.y = _cairo_fixed_from_26_6 (control2->y);
+
+ p2.x = _cairo_fixed_from_26_6 (to->x);
+ p2.y = _cairo_fixed_from_26_6 (to->y);
- _cairo_path_curve_to (path,
- DOUBLE_FROM_26_6(control1->x), DOUBLE_FROM_26_6(control1->y),
- DOUBLE_FROM_26_6(control2->x), DOUBLE_FROM_26_6(control2->y),
- DOUBLE_FROM_26_6(to->x), DOUBLE_FROM_26_6(to->y));
+ _cairo_path_curve_to (path, &p0, &p1, &p2);
return 0;
}
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index ce0558a5..ebd00879 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -684,33 +684,51 @@ _cairo_gstate_new_path (cairo_gstate_t *gstate)
cairo_status_t
_cairo_gstate_move_to (cairo_gstate_t *gstate, double x, double y)
{
+ cairo_point_t point;
+
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
- return _cairo_path_move_to (&gstate->path, x, y);
+ point.x = _cairo_fixed_from_double (x);
+ point.y = _cairo_fixed_from_double (y);
+
+ return _cairo_path_move_to (&gstate->path, &point);
}
cairo_status_t
_cairo_gstate_line_to (cairo_gstate_t *gstate, double x, double y)
{
+ cairo_point_t point;
+
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
- return _cairo_path_line_to (&gstate->path, x, y);
+ point.x = _cairo_fixed_from_double (x);
+ point.y = _cairo_fixed_from_double (y);
+
+ return _cairo_path_line_to (&gstate->path, &point);
}
cairo_status_t
_cairo_gstate_curve_to (cairo_gstate_t *gstate,
+ double x0, double y0,
double x1, double y1,
- double x2, double y2,
- double x3, double y3)
+ double x2, double y2)
{
+ cairo_point_t p0, p1, p2;
+
+ cairo_matrix_transform_point (&gstate->ctm, &x0, &y0);
cairo_matrix_transform_point (&gstate->ctm, &x1, &y1);
cairo_matrix_transform_point (&gstate->ctm, &x2, &y2);
- cairo_matrix_transform_point (&gstate->ctm, &x3, &y3);
- return _cairo_path_curve_to (&gstate->path,
- x1, y1,
- x2, y2,
- x3, y3);
+ p0.x = _cairo_fixed_from_double (x0);
+ p0.y = _cairo_fixed_from_double (y0);
+
+ p1.x = _cairo_fixed_from_double (x1);
+ p1.y = _cairo_fixed_from_double (y1);
+
+ p2.x = _cairo_fixed_from_double (x2);
+ p2.y = _cairo_fixed_from_double (y2);
+
+ return _cairo_path_curve_to (&gstate->path, &p0, &p1, &p2);
}
/* Spline deviation from the circle in radius would be given by:
@@ -988,31 +1006,54 @@ _cairo_gstate_arc_to (cairo_gstate_t *gstate,
cairo_status_t
_cairo_gstate_rel_move_to (cairo_gstate_t *gstate, double dx, double dy)
{
+ cairo_distance_t distance;
+
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
- return _cairo_path_rel_move_to (&gstate->path, dx, dy);
+ distance.dx = _cairo_fixed_from_double (dx);
+ distance.dy = _cairo_fixed_from_double (dy);
+
+ return _cairo_path_rel_move_to (&gstate->path, &distance);
}
cairo_status_t
_cairo_gstate_rel_line_to (cairo_gstate_t *gstate, double dx, double dy)
{
+ cairo_distance_t distance;
+
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
- return _cairo_path_rel_line_to (&gstate->path, dx, dy);
+ distance.dx = _cairo_fixed_from_double (dx);
+ distance.dy = _cairo_fixed_from_double (dy);
+
+ return _cairo_path_rel_line_to (&gstate->path, &distance);
}
cairo_status_t
_cairo_gstate_rel_curve_to (cairo_gstate_t *gstate,
+ double dx0, double dy0,
double dx1, double dy1,
- double dx2, double dy2,
- double dx3, double dy3)
+ double dx2, double dy2)
{
+ cairo_distance_t distance[3];
+
+ cairo_matrix_transform_distance (&gstate->ctm, &dx0, &dy0);
cairo_matrix_transform_distance (&gstate->ctm, &dx1, &dy1);
cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2);
- cairo_matrix_transform_distance (&gstate->ctm, &dx3, &dy3);
+
+ distance[0].dx = _cairo_fixed_from_double (dx0);
+ distance[0].dy = _cairo_fixed_from_double (dy0);
+
+ distance[1].dx = _cairo_fixed_from_double (dx1);
+ distance[1].dy = _cairo_fixed_from_double (dy1);
+
+ distance[2].dx = _cairo_fixed_from_double (dx2);
+ distance[2].dy = _cairo_fixed_from_double (dy2);
return _cairo_path_rel_curve_to (&gstate->path,
- dx1, dy1, dx2, dy2, dx3, dy3);
+ &distance[0],
+ &distance[1],
+ &distance[2]);
}
/* XXX: NYI
@@ -1036,13 +1077,16 @@ cairo_status_t
_cairo_gstate_current_point (cairo_gstate_t *gstate, double *x_ret, double *y_ret)
{
cairo_status_t status;
+ cairo_point_t point;
double x, y;
- status = _cairo_path_current_point (&gstate->path, &x, &y);
+ status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0.0;
y = 0.0;
} else {
+ x = _cairo_fixed_to_double (point.x);
+ y = _cairo_fixed_to_double (point.y);
cairo_matrix_transform_point (&gstate->ctm_inverse, &x, &y);
}
@@ -1635,15 +1679,19 @@ _cairo_gstate_show_text (cairo_gstate_t *gstate,
const unsigned char *utf8)
{
cairo_status_t status;
+ cairo_point_t point;
double x, y;
cairo_matrix_t user_to_source;
cairo_matrix_t saved_font_matrix;
- status = _cairo_path_current_point (&gstate->path, &x, &y);
+ status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0;
y = 0;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
+ } else {
+ x = _cairo_fixed_to_double (point.x);
+ y = _cairo_fixed_to_double (point.y);
}
status = setup_text_rendering_context (gstate, &user_to_source);
@@ -1715,17 +1763,21 @@ _cairo_gstate_text_path (cairo_gstate_t *gstate,
cairo_status_t status;
cairo_matrix_t user_to_source;
cairo_matrix_t saved_font_matrix;
+ cairo_point_t point;
double x, y;
status = setup_text_rendering_context (gstate, &user_to_source);
if (status)
return status;
- status = _cairo_path_current_point (&gstate->path, &x, &y);
+ status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0;
y = 0;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
+ } else {
+ x = _cairo_fixed_to_double (point.x);
+ y = _cairo_fixed_to_double (point.y);
}
cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix);
diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c
index ce0d8391..6a02b9ac 100644
--- a/src/cairo-path-bounds.c
+++ b/src/cairo-path-bounds.c
@@ -60,9 +60,6 @@ _cairo_path_bounder_curve_to (void *closure,
static cairo_status_t
_cairo_path_bounder_close_path (void *closure);
-static cairo_status_t
-_cairo_path_bounder_done_path (void *closure);
-
static void
_cairo_path_bounder_init (cairo_path_bounder_t *bounder)
{
@@ -143,30 +140,22 @@ _cairo_path_bounder_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-_cairo_path_bounder_done_path (void *closure)
-{
- return CAIRO_STATUS_SUCCESS;
-}
-
/* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */
cairo_status_t
_cairo_path_bounds (cairo_path_t *path, double *x1, double *y1, double *x2, double *y2)
{
cairo_status_t status;
- static cairo_path_callbacks_t const cb = {
- _cairo_path_bounder_move_to,
- _cairo_path_bounder_line_to,
- _cairo_path_bounder_curve_to,
- _cairo_path_bounder_close_path,
- _cairo_path_bounder_done_path
- };
cairo_path_bounder_t bounder;
_cairo_path_bounder_init (&bounder);
- status = _cairo_path_interpret (path, CAIRO_DIRECTION_FORWARD, &cb, &bounder);
+ status = _cairo_path_interpret (path, CAIRO_DIRECTION_FORWARD,
+ _cairo_path_bounder_move_to,
+ _cairo_path_bounder_line_to,
+ _cairo_path_bounder_curve_to,
+ _cairo_path_bounder_close_path,
+ &bounder);
if (status) {
*x1 = *y1 = *x2 = *y2 = 0.0;
_cairo_path_bounder_fini (&bounder);
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index 74a019d6..fba5bb09 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -57,9 +57,6 @@ _cairo_filler_curve_to (void *closure,
static cairo_status_t
_cairo_filler_close_path (void *closure);
-static cairo_status_t
-_cairo_filler_done_path (void *closure);
-
static void
_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps)
{
@@ -164,52 +161,37 @@ _cairo_filler_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-_cairo_filler_done_path (void *closure)
-{
- cairo_status_t status;
- cairo_filler_t *filler = closure;
- cairo_polygon_t *polygon = &filler->polygon;
-
- status = _cairo_polygon_close (polygon);
- if (status)
- return status;
-
- status = _cairo_traps_tessellate_polygon (filler->traps,
- &filler->polygon,
- filler->gstate->fill_rule);
- if (status)
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
cairo_status_t
_cairo_path_fill_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_traps_t *traps)
{
- static const cairo_path_callbacks_t filler_callbacks = {
- _cairo_filler_move_to,
- _cairo_filler_line_to,
- _cairo_filler_curve_to,
- _cairo_filler_close_path,
- _cairo_filler_done_path
- };
-
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_filler_t filler;
_cairo_filler_init (&filler, gstate, traps);
status = _cairo_path_interpret (path,
CAIRO_DIRECTION_FORWARD,
- &filler_callbacks, &filler);
- if (status) {
- _cairo_filler_fini (&filler);
- return status;
- }
+ _cairo_filler_move_to,
+ _cairo_filler_line_to,
+ _cairo_filler_curve_to,
+ _cairo_filler_close_path,
+ &filler);
+ if (status)
+ goto BAIL;
+
+ status = _cairo_polygon_close (&filler.polygon);
+ if (status)
+ goto BAIL;
+ status = _cairo_traps_tessellate_polygon (filler.traps,
+ &filler.polygon,
+ filler.gstate->fill_rule);
+ if (status)
+ goto BAIL;
+
+BAIL:
_cairo_filler_fini (&filler);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index df7ca79a..c2412579 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -72,9 +72,6 @@ _cairo_stroker_curve_to (void *closure,
static cairo_status_t
_cairo_stroker_close_path (void *closure);
-static cairo_status_t
-_cairo_stroker_done_path (void *closure);
-
static void
_translate_point (cairo_point_t *point, cairo_point_t *offset);
@@ -490,6 +487,12 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
fields from start. */
_compute_face (p2, &slope, gstate, end);
+ /* XXX: I should really check the return value of the
+ move_to/line_to functions here to catch out of memory
+ conditions. But since that would be ugly, I'd prefer to add a
+ status flag to the polygon object that I could check only once
+ at then end of this sequence, (like we do with cairo_t
+ already). */
_cairo_polygon_init (&polygon);
_cairo_polygon_move_to (&polygon, &start->cw);
_cairo_polygon_line_to (&polygon, &start->ccw);
@@ -781,72 +784,56 @@ _cairo_stroker_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-_cairo_stroker_done_path (void *closure)
-{
- cairo_status_t status;
- cairo_stroker_t *stroker = closure;
-
- if (stroker->has_first_face) {
- cairo_point_t t;
- /* The initial cap needs an outward facing vector. Reverse everything */
- stroker->first_face.usr_vector.x = -stroker->first_face.usr_vector.x;
- stroker->first_face.usr_vector.y = -stroker->first_face.usr_vector.y;
- stroker->first_face.dev_vector.dx = -stroker->first_face.dev_vector.dx;
- stroker->first_face.dev_vector.dy = -stroker->first_face.dev_vector.dy;
- t = stroker->first_face.cw;
- stroker->first_face.cw = stroker->first_face.ccw;
- stroker->first_face.ccw = t;
- status = _cairo_stroker_cap (stroker, &stroker->first_face);
- if (status)
- return status;
- }
- if (stroker->has_current_face) {
- status = _cairo_stroker_cap (stroker, &stroker->current_face);
- if (status)
- return status;
- }
-
- stroker->has_first_face = 0;
- stroker->has_current_face = 0;
- stroker->has_current_point = 0;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
cairo_status_t
_cairo_path_stroke_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_traps_t *traps)
{
- static const cairo_path_callbacks_t stroker_solid_cb = {
- _cairo_stroker_move_to,
- _cairo_stroker_line_to,
- _cairo_stroker_curve_to,
- _cairo_stroker_close_path,
- _cairo_stroker_done_path
- };
- static const cairo_path_callbacks_t stroker_dashed_cb = {
- _cairo_stroker_move_to,
- _cairo_stroker_line_to_dashed,
- _cairo_stroker_curve_to,
- _cairo_stroker_close_path,
- _cairo_stroker_done_path
- };
- const cairo_path_callbacks_t *callbacks = gstate->dash ? &stroker_dashed_cb : &stroker_solid_cb;
-
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_stroker_t stroker;
_cairo_stroker_init (&stroker, gstate, traps);
- status = _cairo_path_interpret (path,
- CAIRO_DIRECTION_FORWARD,
- callbacks, &stroker);
- if (status) {
- _cairo_stroker_fini (&stroker);
- return status;
+ if (gstate->dash)
+ status = _cairo_path_interpret (path,
+ CAIRO_DIRECTION_FORWARD,
+ _cairo_stroker_move_to,
+ _cairo_stroker_line_to_dashed,
+ _cairo_stroker_curve_to,
+ _cairo_stroker_close_path,
+ &stroker);
+ else
+ status = _cairo_path_interpret (path,
+ CAIRO_DIRECTION_FORWARD,
+ _cairo_stroker_move_to,
+ _cairo_stroker_line_to,
+ _cairo_stroker_curve_to,
+ _cairo_stroker_close_path,
+ &stroker);
+ if (status)
+ goto BAIL;
+
+ if (stroker.has_first_face) {
+ cairo_point_t t;
+ /* The initial cap needs an outward facing vector. Reverse everything */
+ stroker.first_face.usr_vector.x = -stroker.first_face.usr_vector.x;
+ stroker.first_face.usr_vector.y = -stroker.first_face.usr_vector.y;
+ stroker.first_face.dev_vector.dx = -stroker.first_face.dev_vector.dx;
+ stroker.first_face.dev_vector.dy = -stroker.first_face.dev_vector.dy;
+ t = stroker.first_face.cw;
+ stroker.first_face.cw = stroker.first_face.ccw;
+ stroker.first_face.ccw = t;
+ status = _cairo_stroker_cap (&stroker, &stroker.first_face);
+ if (status)
+ goto BAIL;
}
+ if (stroker.has_current_face) {
+ status = _cairo_stroker_cap (&stroker, &stroker.current_face);
+ if (status)
+ goto BAIL;
+ }
+
+BAIL:
_cairo_stroker_fini (&stroker);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
diff --git a/src/cairo-path.c b/src/cairo-path.c
index 28547ad0..91142c8f 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -71,8 +71,8 @@ _cairo_path_init (cairo_path_t *path)
path->arg_head = NULL;
path->arg_tail = NULL;
- path->current_point.x = 0.0;
- path->current_point.y = 0.0;
+ path->current_point.x = 0;
+ path->current_point.y = 0;
path->has_current_point = 0;
path->last_move_point = path->current_point;
}
@@ -133,20 +133,15 @@ _cairo_path_fini (cairo_path_t *path)
}
cairo_status_t
-_cairo_path_move_to (cairo_path_t *path, double x, double y)
+_cairo_path_move_to (cairo_path_t *path, cairo_point_t *point)
{
cairo_status_t status;
- cairo_point_t point;
-
- point.x = _cairo_fixed_from_double (x);
- point.y = _cairo_fixed_from_double (y);
- status = _cairo_path_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
+ status = _cairo_path_add (path, CAIRO_PATH_OP_MOVE_TO, point, 1);
if (status)
return status;
- path->current_point.x = x;
- path->current_point.y = y;
+ path->current_point = *point;
path->has_current_point = 1;
path->last_move_point = path->current_point;
@@ -154,71 +149,60 @@ _cairo_path_move_to (cairo_path_t *path, double x, double y)
}
cairo_status_t
-_cairo_path_rel_move_to (cairo_path_t *path, double dx, double dy)
+_cairo_path_rel_move_to (cairo_path_t *path, cairo_distance_t *distance)
{
- double x, y;
+ cairo_point_t point;
- x = path->current_point.x + dx;
- y = path->current_point.y + dy;
+ point.x = path->current_point.x + distance->dx;
+ point.y = path->current_point.y + distance->dy;
- return _cairo_path_move_to (path, x, y);
+ return _cairo_path_move_to (path, &point);
}
cairo_status_t
-_cairo_path_line_to (cairo_path_t *path, double x, double y)
+_cairo_path_line_to (cairo_path_t *path, cairo_point_t *point)
{
cairo_status_t status;
- cairo_point_t point;
-
- point.x = _cairo_fixed_from_double (x);
- point.y = _cairo_fixed_from_double (y);
- status = _cairo_path_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
+ status = _cairo_path_add (path, CAIRO_PATH_OP_LINE_TO, point, 1);
if (status)
return status;
- path->current_point.x = x;
- path->current_point.y = y;
+ path->current_point = *point;
path->has_current_point = 1;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
-_cairo_path_rel_line_to (cairo_path_t *path, double dx, double dy)
+_cairo_path_rel_line_to (cairo_path_t *path, cairo_distance_t *distance)
{
- double x, y;
+ cairo_point_t point;
- x = path->current_point.x + dx;
- y = path->current_point.y + dy;
+ point.x = path->current_point.x + distance->dx;
+ point.y = path->current_point.y + distance->dy;
- return _cairo_path_line_to (path, x, y);
+ return _cairo_path_line_to (path, &point);
}
cairo_status_t
_cairo_path_curve_to (cairo_path_t *path,
- double x1, double y1,
- double x2, double y2,
- double x3, double y3)
+ cairo_point_t *p0,
+ cairo_point_t *p1,
+ cairo_point_t *p2)
{
cairo_status_t status;
cairo_point_t point[3];
- point[0].x = _cairo_fixed_from_double (x1);
- point[0].y = _cairo_fixed_from_double (y1);
-
- point[1].x = _cairo_fixed_from_double (x2);
- point[1].y = _cairo_fixed_from_double (y2);
-
- point[2].x = _cairo_fixed_from_double (x3);
- point[2].y = _cairo_fixed_from_double (y3);
+ point[0] = *p0;
+ point[1] = *p1;
+ point[2] = *p2;
status = _cairo_path_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
if (status)
return status;
- path->current_point.x = x3;
- path->current_point.y = y3;
+ path->current_point = *p2;
path->has_current_point = 1;
return CAIRO_STATUS_SUCCESS;
@@ -226,22 +210,22 @@ _cairo_path_curve_to (cairo_path_t *path,
cairo_status_t
_cairo_path_rel_curve_to (cairo_path_t *path,
- double dx1, double dy1,
- double dx2, double dy2,
- double dx3, double dy3)
+ cairo_distance_t *d0,
+ cairo_distance_t *d1,
+ cairo_distance_t *d2)
{
- double x1, y1, x2, y2, x3, y3;
+ cairo_point_t p0, p1, p2;
- x1 = path->current_point.x + dx1;
- y1 = path->current_point.y + dy1;
+ p0.x = path->current_point.x + d0->dx;
+ p0.y = path->current_point.y + d0->dy;
- x2 = path->current_point.x + dx2;
- y2 = path->current_point.y + dy2;
+ p1.x = path->current_point.x + d1->dx;
+ p1.y = path->current_point.y + d1->dy;
- x3 = path->current_point.x + dx3;
- y3 = path->current_point.y + dy3;
+ p2.x = path->current_point.x + d2->dx;
+ p2.y = path->current_point.y + d2->dy;
- return _cairo_path_curve_to (path, x1, y1, x2, y2, x3, y3);
+ return _cairo_path_curve_to (path, &p0, &p1, &p2);
}
cairo_status_t
@@ -261,13 +245,12 @@ _cairo_path_close_path (cairo_path_t *path)
}
cairo_status_t
-_cairo_path_current_point (cairo_path_t *path, double *x, double *y)
+_cairo_path_current_point (cairo_path_t *path, cairo_point_t *point)
{
if (! path->has_current_point)
return CAIRO_STATUS_NO_CURRENT_POINT;
- *x = path->current_point.x;
- *y = path->current_point.y;
+ *point = path->current_point;
return CAIRO_STATUS_SUCCESS;
}
@@ -422,7 +405,13 @@ static int const num_args[] =
};
cairo_status_t
-_cairo_path_interpret (cairo_path_t *path, cairo_direction_t dir, const cairo_path_callbacks_t *cb, void *closure)
+_cairo_path_interpret (cairo_path_t *path,
+ cairo_direction_t dir,
+ cairo_path_move_to_func_t *move_to,
+ cairo_path_line_to_func_t *line_to,
+ cairo_path_curve_to_func_t *curve_to,
+ cairo_path_close_path_func_t *close_path,
+ void *closure)
{
cairo_status_t status;
int i, arg;
@@ -472,17 +461,17 @@ _cairo_path_interpret (cairo_path_t *path, cairo_direction_t dir, const cairo_pa
switch (op) {
case CAIRO_PATH_OP_MOVE_TO:
- status = (*cb->move_to) (closure, &point[0]);
+ status = (*move_to) (closure, &point[0]);
break;
case CAIRO_PATH_OP_LINE_TO:
- status = (*cb->line_to) (closure, &point[0]);
+ status = (*line_to) (closure, &point[0]);
break;
case CAIRO_PATH_OP_CURVE_TO:
- status = (*cb->curve_to) (closure, &point[0], &point[1], &point[2]);
+ status = (*curve_to) (closure, &point[0], &point[1], &point[2]);
break;
case CAIRO_PATH_OP_CLOSE_PATH:
default:
- status = (*cb->close_path) (closure);
+ status = (*close_path) (closure);
break;
}
if (status)
@@ -490,6 +479,6 @@ _cairo_path_interpret (cairo_path_t *path, cairo_direction_t dir, const cairo_pa
}
}
- return (*cb->done_path) (closure);
+ return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 2face9e5..e786ad42 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -490,7 +490,7 @@ _line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_
*/
cairo_status_t
_cairo_traps_tessellate_polygon (cairo_traps_t *traps,
- cairo_polygon_t *poly,
+ cairo_polygon_t *poly,
cairo_fill_rule_t fill_rule)
{
cairo_status_t status;
diff --git a/src/cairo.h b/src/cairo.h
index 27bc0bf5..76dc6b24 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -523,6 +523,19 @@ cairo_current_matrix (cairo_t *cr, cairo_matrix_t *matrix);
cairo_surface_t *
cairo_current_target_surface (cairo_t *cr);
+typedef void (cairo_move_to_func_t) (void *closure,
+ double x, double y);
+
+typedef void (cairo_line_to_func_t) (void *closure,
+ double x, double y);
+
+typedef void (cairo_curve_to_func_t) (void *closure,
+ double x1, double y1,
+ double x2, double y2,
+ double x3, double y3);
+
+typedef void (cairo_close_path_func_t) (void *closure);
+
/* Error status queries */
typedef enum cairo_status {
diff --git a/src/cairo_fixed.c b/src/cairo_fixed.c
index 33088546..9a7e7bc4 100644
--- a/src/cairo_fixed.c
+++ b/src/cairo_fixed.c
@@ -39,8 +39,15 @@ _cairo_fixed_from_double (double d)
return (cairo_fixed_t) (d * 65536);
}
+cairo_fixed_t
+_cairo_fixed_from_26_6 (uint32_t i)
+{
+ return i << 10;
+}
+
double
_cairo_fixed_to_double (cairo_fixed_t f)
{
return ((double) f) / 65536.0;
}
+
diff --git a/src/cairo_ft_font.c b/src/cairo_ft_font.c
index 3b01f2d0..1b04397c 100644
--- a/src/cairo_ft_font.c
+++ b/src/cairo_ft_font.c
@@ -593,11 +593,13 @@ static int
_move_to (FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
+ cairo_point_t point;
+
+ point.x = _cairo_fixed_from_26_6 (to->x);
+ point.y = _cairo_fixed_from_26_6 (to->y);
_cairo_path_close_path (path);
- _cairo_path_move_to (path,
- DOUBLE_FROM_26_6(to->x),
- DOUBLE_FROM_26_6(to->y));
+ _cairo_path_move_to (path, &point);
return 0;
}
@@ -606,10 +608,12 @@ static int
_line_to (FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
+ cairo_point_t point;
+
+ point.x = _cairo_fixed_from_26_6 (to->x);
+ point.y = _cairo_fixed_from_26_6 (to->y);
- _cairo_path_line_to (path,
- DOUBLE_FROM_26_6(to->x),
- DOUBLE_FROM_26_6(to->y));
+ _cairo_path_line_to (path, &point);
return 0;
}
@@ -619,18 +623,25 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
- double x1, y1;
- double x2 = DOUBLE_FROM_26_6(control->x);
- double y2 = DOUBLE_FROM_26_6(control->y);
- double x3 = DOUBLE_FROM_26_6(to->x);
- double y3 = DOUBLE_FROM_26_6(to->y);
+ cairo_point_t p0, p1, p2, p3;
+ cairo_point_t conic;
+
+ _cairo_path_current_point (path, &p0);
+
+ conic.x = _cairo_fixed_from_26_6 (control->x);
+ conic.y = _cairo_fixed_from_26_6 (control->y);
+
+ p3.x = _cairo_fixed_from_26_6 (to->x);
+ p3.y = _cairo_fixed_from_26_6 (to->y);
- _cairo_path_current_point (path, &x1, &y1);
+ p1.x = p0.x + 2.0/3.0 * (conic.x - p0.x);
+ p1.y = p0.y + 2.0/3.0 * (conic.y - p0.y);
+
+ p2.x = p3.x + 2.0/3.0 * (conic.x - p3.x);
+ p2.y = p3.y + 2.0/3.0 * (conic.y - p3.y);
_cairo_path_curve_to (path,
- x1 + 2.0/3.0 * (x2 - x1), y1 + 2.0/3.0 * (y2 - y1),
- x3 + 2.0/3.0 * (x2 - x3), y3 + 2.0/3.0 * (y2 - y3),
- x3, y3);
+ &p1, &p2, &p3);
return 0;
}
@@ -639,11 +650,18 @@ static int
_cubic_to (FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *closure)
{
cairo_path_t *path = closure;
+ cairo_point_t p0, p1, p2;
+
+ p0.x = _cairo_fixed_from_26_6 (control1->x);
+ p0.y = _cairo_fixed_from_26_6 (control1->y);
+
+ p1.x = _cairo_fixed_from_26_6 (control2->x);
+ p1.y = _cairo_fixed_from_26_6 (control2->y);
+
+ p2.x = _cairo_fixed_from_26_6 (to->x);
+ p2.y = _cairo_fixed_from_26_6 (to->y);
- _cairo_path_curve_to (path,
- DOUBLE_FROM_26_6(control1->x), DOUBLE_FROM_26_6(control1->y),
- DOUBLE_FROM_26_6(control2->x), DOUBLE_FROM_26_6(control2->y),
- DOUBLE_FROM_26_6(to->x), DOUBLE_FROM_26_6(to->y));
+ _cairo_path_curve_to (path, &p0, &p1, &p2);
return 0;
}
diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c
index ce0558a5..ebd00879 100644
--- a/src/cairo_gstate.c
+++ b/src/cairo_gstate.c
@@ -684,33 +684,51 @@ _cairo_gstate_new_path (cairo_gstate_t *gstate)
cairo_status_t
_cairo_gstate_move_to (cairo_gstate_t *gstate, double x, double y)
{
+ cairo_point_t point;
+
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
- return _cairo_path_move_to (&gstate->path, x, y);
+ point.x = _cairo_fixed_from_double (x);
+ point.y = _cairo_fixed_from_double (y);
+
+ return _cairo_path_move_to (&gstate->path, &point);
}
cairo_status_t
_cairo_gstate_line_to (cairo_gstate_t *gstate, double x, double y)
{
+ cairo_point_t point;
+
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
- return _cairo_path_line_to (&gstate->path, x, y);
+ point.x = _cairo_fixed_from_double (x);
+ point.y = _cairo_fixed_from_double (y);
+
+ return _cairo_path_line_to (&gstate->path, &point);
}
cairo_status_t
_cairo_gstate_curve_to (cairo_gstate_t *gstate,
+ double x0, double y0,
double x1, double y1,
- double x2, double y2,
- double x3, double y3)
+ double x2, double y2)
{
+ cairo_point_t p0, p1, p2;
+
+ cairo_matrix_transform_point (&gstate->ctm, &x0, &y0);
cairo_matrix_transform_point (&gstate->ctm, &x1, &y1);
cairo_matrix_transform_point (&gstate->ctm, &x2, &y2);
- cairo_matrix_transform_point (&gstate->ctm, &x3, &y3);
- return _cairo_path_curve_to (&gstate->path,
- x1, y1,
- x2, y2,
- x3, y3);
+ p0.x = _cairo_fixed_from_double (x0);
+ p0.y = _cairo_fixed_from_double (y0);
+
+ p1.x = _cairo_fixed_from_double (x1);
+ p1.y = _cairo_fixed_from_double (y1);
+
+ p2.x = _cairo_fixed_from_double (x2);
+ p2.y = _cairo_fixed_from_double (y2);
+
+ return _cairo_path_curve_to (&gstate->path, &p0, &p1, &p2);
}
/* Spline deviation from the circle in radius would be given by:
@@ -988,31 +1006,54 @@ _cairo_gstate_arc_to (cairo_gstate_t *gstate,
cairo_status_t
_cairo_gstate_rel_move_to (cairo_gstate_t *gstate, double dx, double dy)
{
+ cairo_distance_t distance;
+
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
- return _cairo_path_rel_move_to (&gstate->path, dx, dy);
+ distance.dx = _cairo_fixed_from_double (dx);
+ distance.dy = _cairo_fixed_from_double (dy);
+
+ return _cairo_path_rel_move_to (&gstate->path, &distance);
}
cairo_status_t
_cairo_gstate_rel_line_to (cairo_gstate_t *gstate, double dx, double dy)
{
+ cairo_distance_t distance;
+
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
- return _cairo_path_rel_line_to (&gstate->path, dx, dy);
+ distance.dx = _cairo_fixed_from_double (dx);
+ distance.dy = _cairo_fixed_from_double (dy);
+
+ return _cairo_path_rel_line_to (&gstate->path, &distance);
}
cairo_status_t
_cairo_gstate_rel_curve_to (cairo_gstate_t *gstate,
+ double dx0, double dy0,
double dx1, double dy1,
- double dx2, double dy2,
- double dx3, double dy3)
+ double dx2, double dy2)
{
+ cairo_distance_t distance[3];
+
+ cairo_matrix_transform_distance (&gstate->ctm, &dx0, &dy0);
cairo_matrix_transform_distance (&gstate->ctm, &dx1, &dy1);
cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2);
- cairo_matrix_transform_distance (&gstate->ctm, &dx3, &dy3);
+
+ distance[0].dx = _cairo_fixed_from_double (dx0);
+ distance[0].dy = _cairo_fixed_from_double (dy0);
+
+ distance[1].dx = _cairo_fixed_from_double (dx1);
+ distance[1].dy = _cairo_fixed_from_double (dy1);
+
+ distance[2].dx = _cairo_fixed_from_double (dx2);
+ distance[2].dy = _cairo_fixed_from_double (dy2);
return _cairo_path_rel_curve_to (&gstate->path,
- dx1, dy1, dx2, dy2, dx3, dy3);
+ &distance[0],
+ &distance[1],
+ &distance[2]);
}
/* XXX: NYI
@@ -1036,13 +1077,16 @@ cairo_status_t
_cairo_gstate_current_point (cairo_gstate_t *gstate, double *x_ret, double *y_ret)
{
cairo_status_t status;
+ cairo_point_t point;
double x, y;
- status = _cairo_path_current_point (&gstate->path, &x, &y);
+ status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0.0;
y = 0.0;
} else {
+ x = _cairo_fixed_to_double (point.x);
+ y = _cairo_fixed_to_double (point.y);
cairo_matrix_transform_point (&gstate->ctm_inverse, &x, &y);
}
@@ -1635,15 +1679,19 @@ _cairo_gstate_show_text (cairo_gstate_t *gstate,
const unsigned char *utf8)
{
cairo_status_t status;
+ cairo_point_t point;
double x, y;
cairo_matrix_t user_to_source;
cairo_matrix_t saved_font_matrix;
- status = _cairo_path_current_point (&gstate->path, &x, &y);
+ status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0;
y = 0;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
+ } else {
+ x = _cairo_fixed_to_double (point.x);
+ y = _cairo_fixed_to_double (point.y);
}
status = setup_text_rendering_context (gstate, &user_to_source);
@@ -1715,17 +1763,21 @@ _cairo_gstate_text_path (cairo_gstate_t *gstate,
cairo_status_t status;
cairo_matrix_t user_to_source;
cairo_matrix_t saved_font_matrix;
+ cairo_point_t point;
double x, y;
status = setup_text_rendering_context (gstate, &user_to_source);
if (status)
return status;
- status = _cairo_path_current_point (&gstate->path, &x, &y);
+ status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0;
y = 0;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
+ } else {
+ x = _cairo_fixed_to_double (point.x);
+ y = _cairo_fixed_to_double (point.y);
}
cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix);
diff --git a/src/cairo_path.c b/src/cairo_path.c
index 28547ad0..91142c8f 100644
--- a/src/cairo_path.c
+++ b/src/cairo_path.c
@@ -71,8 +71,8 @@ _cairo_path_init (cairo_path_t *path)
path->arg_head = NULL;
path->arg_tail = NULL;
- path->current_point.x = 0.0;
- path->current_point.y = 0.0;
+ path->current_point.x = 0;
+ path->current_point.y = 0;
path->has_current_point = 0;
path->last_move_point = path->current_point;
}
@@ -133,20 +133,15 @@ _cairo_path_fini (cairo_path_t *path)
}
cairo_status_t
-_cairo_path_move_to (cairo_path_t *path, double x, double y)
+_cairo_path_move_to (cairo_path_t *path, cairo_point_t *point)
{
cairo_status_t status;
- cairo_point_t point;
-
- point.x = _cairo_fixed_from_double (x);
- point.y = _cairo_fixed_from_double (y);
- status = _cairo_path_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
+ status = _cairo_path_add (path, CAIRO_PATH_OP_MOVE_TO, point, 1);
if (status)
return status;
- path->current_point.x = x;
- path->current_point.y = y;
+ path->current_point = *point;
path->has_current_point = 1;
path->last_move_point = path->current_point;
@@ -154,71 +149,60 @@ _cairo_path_move_to (cairo_path_t *path, double x, double y)
}
cairo_status_t
-_cairo_path_rel_move_to (cairo_path_t *path, double dx, double dy)
+_cairo_path_rel_move_to (cairo_path_t *path, cairo_distance_t *distance)
{
- double x, y;
+ cairo_point_t point;
- x = path->current_point.x + dx;
- y = path->current_point.y + dy;
+ point.x = path->current_point.x + distance->dx;
+ point.y = path->current_point.y + distance->dy;
- return _cairo_path_move_to (path, x, y);
+ return _cairo_path_move_to (path, &point);
}
cairo_status_t
-_cairo_path_line_to (cairo_path_t *path, double x, double y)
+_cairo_path_line_to (cairo_path_t *path, cairo_point_t *point)
{
cairo_status_t status;
- cairo_point_t point;
-
- point.x = _cairo_fixed_from_double (x);
- point.y = _cairo_fixed_from_double (y);
- status = _cairo_path_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
+ status = _cairo_path_add (path, CAIRO_PATH_OP_LINE_TO, point, 1);
if (status)
return status;
- path->current_point.x = x;
- path->current_point.y = y;
+ path->current_point = *point;
path->has_current_point = 1;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
-_cairo_path_rel_line_to (cairo_path_t *path, double dx, double dy)
+_cairo_path_rel_line_to (cairo_path_t *path, cairo_distance_t *distance)
{
- double x, y;
+ cairo_point_t point;
- x = path->current_point.x + dx;
- y = path->current_point.y + dy;
+ point.x = path->current_point.x + distance->dx;
+ point.y = path->current_point.y + distance->dy;
- return _cairo_path_line_to (path, x, y);
+ return _cairo_path_line_to (path, &point);
}
cairo_status_t
_cairo_path_curve_to (cairo_path_t *path,
- double x1, double y1,
- double x2, double y2,
- double x3, double y3)
+ cairo_point_t *p0,
+ cairo_point_t *p1,
+ cairo_point_t *p2)
{
cairo_status_t status;
cairo_point_t point[3];
- point[0].x = _cairo_fixed_from_double (x1);
- point[0].y = _cairo_fixed_from_double (y1);
-
- point[1].x = _cairo_fixed_from_double (x2);
- point[1].y = _cairo_fixed_from_double (y2);
-
- point[2].x = _cairo_fixed_from_double (x3);
- point[2].y = _cairo_fixed_from_double (y3);
+ point[0] = *p0;
+ point[1] = *p1;
+ point[2] = *p2;
status = _cairo_path_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
if (status)
return status;
- path->current_point.x = x3;
- path->current_point.y = y3;
+ path->current_point = *p2;
path->has_current_point = 1;
return CAIRO_STATUS_SUCCESS;
@@ -226,22 +210,22 @@ _cairo_path_curve_to (cairo_path_t *path,
cairo_status_t
_cairo_path_rel_curve_to (cairo_path_t *path,
- double dx1, double dy1,
- double dx2, double dy2,
- double dx3, double dy3)
+ cairo_distance_t *d0,
+ cairo_distance_t *d1,
+ cairo_distance_t *d2)
{
- double x1, y1, x2, y2, x3, y3;
+ cairo_point_t p0, p1, p2;
- x1 = path->current_point.x + dx1;
- y1 = path->current_point.y + dy1;
+ p0.x = path->current_point.x + d0->dx;
+ p0.y = path->current_point.y + d0->dy;
- x2 = path->current_point.x + dx2;
- y2 = path->current_point.y + dy2;
+ p1.x = path->current_point.x + d1->dx;
+ p1.y = path->current_point.y + d1->dy;
- x3 = path->current_point.x + dx3;
- y3 = path->current_point.y + dy3;
+ p2.x = path->current_point.x + d2->dx;
+ p2.y = path->current_point.y + d2->dy;
- return _cairo_path_curve_to (path, x1, y1, x2, y2, x3, y3);
+ return _cairo_path_curve_to (path, &p0, &p1, &p2);
}
cairo_status_t
@@ -261,13 +245,12 @@ _cairo_path_close_path (cairo_path_t *path)
}
cairo_status_t
-_cairo_path_current_point (cairo_path_t *path, double *x, double *y)
+_cairo_path_current_point (cairo_path_t *path, cairo_point_t *point)
{
if (! path->has_current_point)
return CAIRO_STATUS_NO_CURRENT_POINT;
- *x = path->current_point.x;
- *y = path->current_point.y;
+ *point = path->current_point;
return CAIRO_STATUS_SUCCESS;
}
@@ -422,7 +405,13 @@ static int const num_args[] =
};
cairo_status_t
-_cairo_path_interpret (cairo_path_t *path, cairo_direction_t dir, const cairo_path_callbacks_t *cb, void *closure)
+_cairo_path_interpret (cairo_path_t *path,
+ cairo_direction_t dir,
+ cairo_path_move_to_func_t *move_to,
+ cairo_path_line_to_func_t *line_to,
+ cairo_path_curve_to_func_t *curve_to,
+ cairo_path_close_path_func_t *close_path,
+ void *closure)
{
cairo_status_t status;
int i, arg;
@@ -472,17 +461,17 @@ _cairo_path_interpret (cairo_path_t *path, cairo_direction_t dir, const cairo_pa
switch (op) {
case CAIRO_PATH_OP_MOVE_TO:
- status = (*cb->move_to) (closure, &point[0]);
+ status = (*move_to) (closure, &point[0]);
break;
case CAIRO_PATH_OP_LINE_TO:
- status = (*cb->line_to) (closure, &point[0]);
+ status = (*line_to) (closure, &point[0]);
break;
case CAIRO_PATH_OP_CURVE_TO:
- status = (*cb->curve_to) (closure, &point[0], &point[1], &point[2]);
+ status = (*curve_to) (closure, &point[0], &point[1], &point[2]);
break;
case CAIRO_PATH_OP_CLOSE_PATH:
default:
- status = (*cb->close_path) (closure);
+ status = (*close_path) (closure);
break;
}
if (status)
@@ -490,6 +479,6 @@ _cairo_path_interpret (cairo_path_t *path, cairo_direction_t dir, const cairo_pa
}
}
- return (*cb->done_path) (closure);
+ return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo_path_bounds.c b/src/cairo_path_bounds.c
index ce0d8391..6a02b9ac 100644
--- a/src/cairo_path_bounds.c
+++ b/src/cairo_path_bounds.c
@@ -60,9 +60,6 @@ _cairo_path_bounder_curve_to (void *closure,
static cairo_status_t
_cairo_path_bounder_close_path (void *closure);
-static cairo_status_t
-_cairo_path_bounder_done_path (void *closure);
-
static void
_cairo_path_bounder_init (cairo_path_bounder_t *bounder)
{
@@ -143,30 +140,22 @@ _cairo_path_bounder_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-_cairo_path_bounder_done_path (void *closure)
-{
- return CAIRO_STATUS_SUCCESS;
-}
-
/* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */
cairo_status_t
_cairo_path_bounds (cairo_path_t *path, double *x1, double *y1, double *x2, double *y2)
{
cairo_status_t status;
- static cairo_path_callbacks_t const cb = {
- _cairo_path_bounder_move_to,
- _cairo_path_bounder_line_to,
- _cairo_path_bounder_curve_to,
- _cairo_path_bounder_close_path,
- _cairo_path_bounder_done_path
- };
cairo_path_bounder_t bounder;
_cairo_path_bounder_init (&bounder);
- status = _cairo_path_interpret (path, CAIRO_DIRECTION_FORWARD, &cb, &bounder);
+ status = _cairo_path_interpret (path, CAIRO_DIRECTION_FORWARD,
+ _cairo_path_bounder_move_to,
+ _cairo_path_bounder_line_to,
+ _cairo_path_bounder_curve_to,
+ _cairo_path_bounder_close_path,
+ &bounder);
if (status) {
*x1 = *y1 = *x2 = *y2 = 0.0;
_cairo_path_bounder_fini (&bounder);
diff --git a/src/cairo_path_fill.c b/src/cairo_path_fill.c
index 74a019d6..fba5bb09 100644
--- a/src/cairo_path_fill.c
+++ b/src/cairo_path_fill.c
@@ -57,9 +57,6 @@ _cairo_filler_curve_to (void *closure,
static cairo_status_t
_cairo_filler_close_path (void *closure);
-static cairo_status_t
-_cairo_filler_done_path (void *closure);
-
static void
_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps)
{
@@ -164,52 +161,37 @@ _cairo_filler_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-_cairo_filler_done_path (void *closure)
-{
- cairo_status_t status;
- cairo_filler_t *filler = closure;
- cairo_polygon_t *polygon = &filler->polygon;
-
- status = _cairo_polygon_close (polygon);
- if (status)
- return status;
-
- status = _cairo_traps_tessellate_polygon (filler->traps,
- &filler->polygon,
- filler->gstate->fill_rule);
- if (status)
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
cairo_status_t
_cairo_path_fill_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_traps_t *traps)
{
- static const cairo_path_callbacks_t filler_callbacks = {
- _cairo_filler_move_to,
- _cairo_filler_line_to,
- _cairo_filler_curve_to,
- _cairo_filler_close_path,
- _cairo_filler_done_path
- };
-
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_filler_t filler;
_cairo_filler_init (&filler, gstate, traps);
status = _cairo_path_interpret (path,
CAIRO_DIRECTION_FORWARD,
- &filler_callbacks, &filler);
- if (status) {
- _cairo_filler_fini (&filler);
- return status;
- }
+ _cairo_filler_move_to,
+ _cairo_filler_line_to,
+ _cairo_filler_curve_to,
+ _cairo_filler_close_path,
+ &filler);
+ if (status)
+ goto BAIL;
+
+ status = _cairo_polygon_close (&filler.polygon);
+ if (status)
+ goto BAIL;
+ status = _cairo_traps_tessellate_polygon (filler.traps,
+ &filler.polygon,
+ filler.gstate->fill_rule);
+ if (status)
+ goto BAIL;
+
+BAIL:
_cairo_filler_fini (&filler);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
diff --git a/src/cairo_path_stroke.c b/src/cairo_path_stroke.c
index df7ca79a..c2412579 100644
--- a/src/cairo_path_stroke.c
+++ b/src/cairo_path_stroke.c
@@ -72,9 +72,6 @@ _cairo_stroker_curve_to (void *closure,
static cairo_status_t
_cairo_stroker_close_path (void *closure);
-static cairo_status_t
-_cairo_stroker_done_path (void *closure);
-
static void
_translate_point (cairo_point_t *point, cairo_point_t *offset);
@@ -490,6 +487,12 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
fields from start. */
_compute_face (p2, &slope, gstate, end);
+ /* XXX: I should really check the return value of the
+ move_to/line_to functions here to catch out of memory
+ conditions. But since that would be ugly, I'd prefer to add a
+ status flag to the polygon object that I could check only once
+ at then end of this sequence, (like we do with cairo_t
+ already). */
_cairo_polygon_init (&polygon);
_cairo_polygon_move_to (&polygon, &start->cw);
_cairo_polygon_line_to (&polygon, &start->ccw);
@@ -781,72 +784,56 @@ _cairo_stroker_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-_cairo_stroker_done_path (void *closure)
-{
- cairo_status_t status;
- cairo_stroker_t *stroker = closure;
-
- if (stroker->has_first_face) {
- cairo_point_t t;
- /* The initial cap needs an outward facing vector. Reverse everything */
- stroker->first_face.usr_vector.x = -stroker->first_face.usr_vector.x;
- stroker->first_face.usr_vector.y = -stroker->first_face.usr_vector.y;
- stroker->first_face.dev_vector.dx = -stroker->first_face.dev_vector.dx;
- stroker->first_face.dev_vector.dy = -stroker->first_face.dev_vector.dy;
- t = stroker->first_face.cw;
- stroker->first_face.cw = stroker->first_face.ccw;
- stroker->first_face.ccw = t;
- status = _cairo_stroker_cap (stroker, &stroker->first_face);
- if (status)
- return status;
- }
- if (stroker->has_current_face) {
- status = _cairo_stroker_cap (stroker, &stroker->current_face);
- if (status)
- return status;
- }
-
- stroker->has_first_face = 0;
- stroker->has_current_face = 0;
- stroker->has_current_point = 0;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
cairo_status_t
_cairo_path_stroke_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_traps_t *traps)
{
- static const cairo_path_callbacks_t stroker_solid_cb = {
- _cairo_stroker_move_to,
- _cairo_stroker_line_to,
- _cairo_stroker_curve_to,
- _cairo_stroker_close_path,
- _cairo_stroker_done_path
- };
- static const cairo_path_callbacks_t stroker_dashed_cb = {
- _cairo_stroker_move_to,
- _cairo_stroker_line_to_dashed,
- _cairo_stroker_curve_to,
- _cairo_stroker_close_path,
- _cairo_stroker_done_path
- };
- const cairo_path_callbacks_t *callbacks = gstate->dash ? &stroker_dashed_cb : &stroker_solid_cb;
-
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_stroker_t stroker;
_cairo_stroker_init (&stroker, gstate, traps);
- status = _cairo_path_interpret (path,
- CAIRO_DIRECTION_FORWARD,
- callbacks, &stroker);
- if (status) {
- _cairo_stroker_fini (&stroker);
- return status;
+ if (gstate->dash)
+ status = _cairo_path_interpret (path,
+ CAIRO_DIRECTION_FORWARD,
+ _cairo_stroker_move_to,
+ _cairo_stroker_line_to_dashed,
+ _cairo_stroker_curve_to,
+ _cairo_stroker_close_path,
+ &stroker);
+ else
+ status = _cairo_path_interpret (path,
+ CAIRO_DIRECTION_FORWARD,
+ _cairo_stroker_move_to,
+ _cairo_stroker_line_to,
+ _cairo_stroker_curve_to,
+ _cairo_stroker_close_path,
+ &stroker);
+ if (status)
+ goto BAIL;
+
+ if (stroker.has_first_face) {
+ cairo_point_t t;
+ /* The initial cap needs an outward facing vector. Reverse everything */
+ stroker.first_face.usr_vector.x = -stroker.first_face.usr_vector.x;
+ stroker.first_face.usr_vector.y = -stroker.first_face.usr_vector.y;
+ stroker.first_face.dev_vector.dx = -stroker.first_face.dev_vector.dx;
+ stroker.first_face.dev_vector.dy = -stroker.first_face.dev_vector.dy;
+ t = stroker.first_face.cw;
+ stroker.first_face.cw = stroker.first_face.ccw;
+ stroker.first_face.ccw = t;
+ status = _cairo_stroker_cap (&stroker, &stroker.first_face);
+ if (status)
+ goto BAIL;
}
+ if (stroker.has_current_face) {
+ status = _cairo_stroker_cap (&stroker, &stroker.current_face);
+ if (status)
+ goto BAIL;
+ }
+
+BAIL:
_cairo_stroker_fini (&stroker);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
diff --git a/src/cairo_traps.c b/src/cairo_traps.c
index 2face9e5..e786ad42 100644
--- a/src/cairo_traps.c
+++ b/src/cairo_traps.c
@@ -490,7 +490,7 @@ _line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_
*/
cairo_status_t
_cairo_traps_tessellate_polygon (cairo_traps_t *traps,
- cairo_polygon_t *poly,
+ cairo_polygon_t *poly,
cairo_fill_rule_t fill_rule)
{
cairo_status_t status;
diff --git a/src/cairoint.h b/src/cairoint.h
index f9b72fb6..28bc6806 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -128,7 +128,7 @@ typedef struct cairo_slope
{
cairo_fixed_t dx;
cairo_fixed_t dy;
-} cairo_slope_t;
+} cairo_slope_t, cairo_distance_t;
typedef struct cairo_point_double {
double x;
@@ -170,14 +170,6 @@ typedef enum cairo_direction {
CAIRO_DIRECTION_REVERSE
} cairo_direction_t;
-typedef struct cairo_path_callbacks {
- cairo_status_t (*move_to) (void *closure, cairo_point_t *point);
- cairo_status_t (*line_to) (void *closure, cairo_point_t *point);
- cairo_status_t (*curve_to) (void *closure, cairo_point_t *b, cairo_point_t *c, cairo_point_t *d);
- cairo_status_t (*close_path) (void *closure);
- cairo_status_t (*done_path) (void *closure);
-} cairo_path_callbacks_t;
-
#define CAIRO_PATH_BUF_SZ 64
typedef struct cairo_path_op_buf {
@@ -201,8 +193,8 @@ typedef struct cairo_path {
cairo_path_arg_buf_t *arg_head;
cairo_path_arg_buf_t *arg_tail;
- cairo_point_double_t last_move_point;
- cairo_point_double_t current_point;
+ cairo_point_t last_move_point;
+ cairo_point_t current_point;
int has_current_point;
} cairo_path_t;
@@ -536,6 +528,9 @@ _cairo_fixed_from_int (int i);
extern cairo_fixed_t
_cairo_fixed_from_double (double d);
+cairo_fixed_t
+_cairo_fixed_from_26_6 (uint32_t i);
+
extern double
_cairo_fixed_to_double (cairo_fixed_t f);
@@ -912,40 +907,56 @@ extern void __internal_linkage
_cairo_path_fini (cairo_path_t *path);
extern cairo_status_t __internal_linkage
-_cairo_path_move_to (cairo_path_t *path, double x, double y);
+_cairo_path_move_to (cairo_path_t *path, cairo_point_t *point);
extern cairo_status_t __internal_linkage
-_cairo_path_rel_move_to (cairo_path_t *path, double dx, double dy);
+_cairo_path_rel_move_to (cairo_path_t *path, cairo_slope_t *slope);
extern cairo_status_t __internal_linkage
-_cairo_path_line_to (cairo_path_t *path, double x, double y);
+_cairo_path_line_to (cairo_path_t *path, cairo_point_t *point);
extern cairo_status_t __internal_linkage
-_cairo_path_rel_line_to (cairo_path_t *path, double dx, double dy);
+_cairo_path_rel_line_to (cairo_path_t *path, cairo_slope_t *slope);
extern cairo_status_t __internal_linkage
_cairo_path_curve_to (cairo_path_t *path,
- double x1, double y1,
- double x2, double y2,
- double x3, double y3);
+ cairo_point_t *p0,
+ cairo_point_t *p1,
+ cairo_point_t *p2);
extern cairo_status_t __internal_linkage
_cairo_path_rel_curve_to (cairo_path_t *path,
- double dx1, double dy1,
- double dx2, double dy2,
- double dx3, double dy3);
+ cairo_slope_t *s0,
+ cairo_slope_t *s1,
+ cairo_slope_t *s2);
extern cairo_status_t __internal_linkage
_cairo_path_close_path (cairo_path_t *path);
extern cairo_status_t __internal_linkage
-_cairo_path_current_point (cairo_path_t *path, double *x, double *y);
+_cairo_path_current_point (cairo_path_t *path, cairo_point_t *point);
+
+typedef cairo_status_t (cairo_path_move_to_func_t) (void *closure,
+ cairo_point_t *point);
+
+typedef cairo_status_t (cairo_path_line_to_func_t) (void *closure,
+ cairo_point_t *point);
+
+typedef cairo_status_t (cairo_path_curve_to_func_t) (void *closure,
+ cairo_point_t *p0,
+ cairo_point_t *p1,
+ cairo_point_t *p2);
+
+typedef cairo_status_t (cairo_path_close_path_func_t) (void *closure);
extern cairo_status_t __internal_linkage
-_cairo_path_interpret (cairo_path_t *path,
- cairo_direction_t dir,
- const cairo_path_callbacks_t *cb,
- void *closure);
+_cairo_path_interpret (cairo_path_t *path,
+ cairo_direction_t dir,
+ cairo_path_move_to_func_t *move_to,
+ cairo_path_line_to_func_t *line_to,
+ cairo_path_curve_to_func_t *curve_to,
+ cairo_path_close_path_func_t *close_path,
+ void *closure);
extern cairo_status_t __internal_linkage
_cairo_path_bounds (cairo_path_t *path, double *x1, double *y1, double *x2, double *y2);