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.

cairo_path.last_move_point and cairo_path.current_point are now fixed-point not doubles for consistency.
Now accept 4 explicit function pointers rather than a structure. Eliminate unnecessary done_path callback.
Track change in _cairo_path_interpret. Code previously in done_path callback is now here immediately after call to _cairo_path_interpret.
Internal _cairo_path API modified to accept fixed-point data everywhere. Much cleaner this way.
Have to convert doubles to fixed-point to track changes in _cairo_path API.
Keep data in fixed-point rather than going through intermediate doubles. Track changes in _cairo_path API.
New function to help when working with freetype.
This commit is contained in:
Carl Worth 2004-02-12 19:02:33 +00:00
parent 810037bc7c
commit b55f107679
19 changed files with 573 additions and 454 deletions

View file

@ -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:

View file

@ -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;
}

View file

@ -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;
_cairo_path_line_to (path,
DOUBLE_FROM_26_6(to->x),
DOUBLE_FROM_26_6(to->y));
point.x = _cairo_fixed_from_26_6 (to->x);
point.y = _cairo_fixed_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, &x1, &y1);
_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);
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;
_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));
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, &p0, &p1, &p2);
return 0;
}

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 {

View file

@ -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;
}

View file

@ -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;
_cairo_path_line_to (path,
DOUBLE_FROM_26_6(to->x),
DOUBLE_FROM_26_6(to->y));
point.x = _cairo_fixed_from_26_6 (to->x);
point.y = _cairo_fixed_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, &x1, &y1);
_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);
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;
_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));
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, &p0, &p1, &p2);
return 0;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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);