mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-02 02:38:07 +02:00
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:
parent
810037bc7c
commit
b55f107679
19 changed files with 573 additions and 454 deletions
47
ChangeLog
47
ChangeLog
|
|
@ -1,3 +1,50 @@
|
|||
2004-02-12 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* src/cairo.h: Add typedefs for new callbacks to be used by
|
||||
cairo_current_path: cairo_move_to_func, cairo_line_to_func,
|
||||
cairo_curve_to_func, and cairo_close_path_func.
|
||||
|
||||
* src/cairoint.h: cairo_path.last_move_point and
|
||||
cairo_path.current_point are now fixed-point not doubles for
|
||||
consistency.
|
||||
|
||||
* src/cairo_path.c (_cairo_path_interpret): Now accept 4 explicit
|
||||
function pointers rather than a structure. Eliminate unnecessary
|
||||
done_path callback.
|
||||
|
||||
* src/cairo_path_bounds.c (_cairo_path_bounds):
|
||||
* src/cairo_path_stroke.c (_cairo_path_stroke_to_traps):
|
||||
* src/cairo_path_fill.c (_cairo_path_fill_to_traps): Track change
|
||||
in _cairo_path_interpret. Code previously in done_path callback is
|
||||
now here immediately after call to _cairo_path_interpret.
|
||||
|
||||
* src/cairo_path.c (_cairo_path_move_to):
|
||||
(_cairo_path_rel_move_to):
|
||||
(_cairo_path_line_to):
|
||||
(_cairo_path_rel_line_to):
|
||||
(_cairo_path_curve_to):
|
||||
(_cairo_path_rel_curve_to):
|
||||
(_cairo_path_current_point): Internal _cairo_path API modified to
|
||||
accept fixed-point data everywhere. Much cleaner this way.
|
||||
|
||||
* src/cairo_gstate.c (_cairo_gstate_move_to):
|
||||
(_cairo_gstate_line_to):
|
||||
(_cairo_gstate_curve_to):
|
||||
(_cairo_gstate_rel_move_to):
|
||||
(_cairo_gstate_rel_line_to):
|
||||
(_cairo_gstate_rel_curve_to):
|
||||
(_cairo_gstate_current_point):
|
||||
(_cairo_gstate_show_text):
|
||||
(_cairo_gstate_text_path): Have to convert doubles to fixed-point
|
||||
to track changes in _cairo_path API.
|
||||
|
||||
* src/cairo_ft_font.c (_move_to, _line_to, _conic_to, _cubic_to):
|
||||
Keep data in fixed-point rather than going through intermediate
|
||||
doubles. Track changes in _cairo_path API.
|
||||
|
||||
* src/cairo_fixed.c (_cairo_fixed_from_26_6): New function to help
|
||||
when working with freetype.
|
||||
|
||||
2004-02-02 Jamey Sharp <jamey@minilop.net>
|
||||
|
||||
* configure.in:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
111
src/cairo-path.c
111
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
13
src/cairo.h
13
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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
111
src/cairo_path.c
111
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue