diff options
-rw-r--r-- | ChangeLog | 47 | ||||
-rw-r--r-- | src/cairo-fixed.c | 7 | ||||
-rw-r--r-- | src/cairo-ft-font.c | 56 | ||||
-rw-r--r-- | src/cairo-gstate.c | 88 | ||||
-rw-r--r-- | src/cairo-path-bounds.c | 23 | ||||
-rw-r--r-- | src/cairo-path-fill.c | 58 | ||||
-rw-r--r-- | src/cairo-path-stroke.c | 107 | ||||
-rw-r--r-- | src/cairo-path.c | 111 | ||||
-rw-r--r-- | src/cairo-traps.c | 2 | ||||
-rw-r--r-- | src/cairo.h | 13 | ||||
-rw-r--r-- | src/cairo_fixed.c | 7 | ||||
-rw-r--r-- | src/cairo_ft_font.c | 56 | ||||
-rw-r--r-- | src/cairo_gstate.c | 88 | ||||
-rw-r--r-- | src/cairo_path.c | 111 | ||||
-rw-r--r-- | src/cairo_path_bounds.c | 23 | ||||
-rw-r--r-- | src/cairo_path_fill.c | 58 | ||||
-rw-r--r-- | src/cairo_path_stroke.c | 107 | ||||
-rw-r--r-- | src/cairo_traps.c | 2 | ||||
-rw-r--r-- | src/cairoint.h | 63 |
19 files changed, 573 insertions, 454 deletions
@@ -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); |