mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-06-20 05:58:31 +02:00
cairo_new_sub_path: Making cairo_arc easier to use and more.
This adds a new function which has as its only effect the elimination of the current point. This makes it much easier to use the various cairo_arc calls when the initial line_to is not actually desired. This function also unifies and generalizes the long-existing behavior of cairo_line_to being treated as cairo_move_to when there is no current point. With the addition of cairo_new_sub_path this becomes a documented feature with similar behavior in cairo_curve_to as well.
This commit is contained in:
parent
0354956a09
commit
1dc1b57b4e
14 changed files with 209 additions and 124 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -22,3 +22,4 @@ stamp-h
|
|||
stamp-h1
|
||||
stamp-h.in
|
||||
*~
|
||||
*.orig
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ typedef struct cairo_stroker {
|
|||
|
||||
cairo_pen_t pen;
|
||||
|
||||
cairo_bool_t has_current_point;
|
||||
cairo_point_t current_point;
|
||||
cairo_point_t first_point;
|
||||
|
||||
|
|
@ -159,7 +158,6 @@ _cairo_stroker_init (cairo_stroker_t *stroker,
|
|||
stroke_style->line_width / 2.0,
|
||||
tolerance, ctm);
|
||||
|
||||
stroker->has_current_point = FALSE;
|
||||
stroker->has_current_face = FALSE;
|
||||
stroker->has_first_face = FALSE;
|
||||
|
||||
|
|
@ -607,7 +605,6 @@ _cairo_stroker_move_to (void *closure, cairo_point_t *point)
|
|||
|
||||
stroker->first_point = *point;
|
||||
stroker->current_point = *point;
|
||||
stroker->has_current_point = 1;
|
||||
|
||||
stroker->has_first_face = 0;
|
||||
stroker->has_current_face = 0;
|
||||
|
|
@ -624,9 +621,6 @@ _cairo_stroker_line_to (void *closure, cairo_point_t *point)
|
|||
cairo_point_t *p1 = &stroker->current_point;
|
||||
cairo_point_t *p2 = point;
|
||||
|
||||
if (!stroker->has_current_point)
|
||||
return _cairo_stroker_move_to (stroker, point);
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y) {
|
||||
/* XXX: Need to rethink how this case should be handled, (both
|
||||
here and in cairo_stroker_add_sub_edge and in _compute_face). The
|
||||
|
|
@ -674,9 +668,6 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
cairo_point_t *p1 = &stroker->current_point;
|
||||
cairo_point_t *p2 = point;
|
||||
|
||||
if (!stroker->has_current_point)
|
||||
return _cairo_stroker_move_to (stroker, point);
|
||||
|
||||
dx = _cairo_fixed_to_double (p2->x - p1->x);
|
||||
dy = _cairo_fixed_to_double (p2->y - p1->y);
|
||||
|
||||
|
|
@ -914,14 +905,12 @@ _cairo_stroker_close_path (void *closure)
|
|||
cairo_status_t status;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
||||
if (stroker->has_current_point) {
|
||||
if (stroker->dashed)
|
||||
status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point);
|
||||
else
|
||||
status = _cairo_stroker_line_to (stroker, &stroker->first_point);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
if (stroker->dashed)
|
||||
status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point);
|
||||
else
|
||||
status = _cairo_stroker_line_to (stroker, &stroker->first_point);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (stroker->has_first_face && stroker->has_current_face) {
|
||||
status = _cairo_stroker_join (stroker, &stroker->current_face, &stroker->first_face);
|
||||
|
|
@ -931,7 +920,6 @@ _cairo_stroker_close_path (void *closure)
|
|||
|
||||
stroker->has_first_face = 0;
|
||||
stroker->has_current_face = 0;
|
||||
stroker->has_current_point = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path)
|
|||
|
||||
path->current_point.x = 0;
|
||||
path->current_point.y = 0;
|
||||
path->has_current_point = 0;
|
||||
path->has_current_point = FALSE;
|
||||
path->last_move_point = path->current_point;
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ _cairo_path_fixed_fini (cairo_path_fixed_t *path)
|
|||
}
|
||||
path->arg_buf_tail = NULL;
|
||||
|
||||
path->has_current_point = 0;
|
||||
path->has_current_point = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -189,12 +189,18 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
|||
return status;
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
path->last_move_point = path->current_point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path)
|
||||
{
|
||||
path->has_current_point = FALSE;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
|
|
@ -202,7 +208,7 @@ _cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
|||
{
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (!path->has_current_point)
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
|
|
@ -222,12 +228,16 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
|||
point.x = x;
|
||||
point.y = y;
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
if (! path->has_current_point)
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
|
||||
else
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -239,7 +249,7 @@ _cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path,
|
|||
{
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (!path->has_current_point)
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
|
|
@ -261,12 +271,19 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
|
|||
point[1].x = x1; point[1].y = y1;
|
||||
point[2].x = x2; point[2].y = y2;
|
||||
|
||||
if (! path->has_current_point) {
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO,
|
||||
&point[0], 1);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point = point[2];
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -281,7 +298,7 @@ _cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path,
|
|||
cairo_fixed_t x1, y1;
|
||||
cairo_fixed_t x2, y2;
|
||||
|
||||
if (!path->has_current_point)
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
|
||||
x0 = path->current_point.x + dx0;
|
||||
|
|
@ -304,13 +321,16 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path)
|
|||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CLOSE_PATH, NULL, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point.x = path->last_move_point.x;
|
||||
path->current_point.y = path->last_move_point.y;
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1263,22 +1263,15 @@ intersect (cairo_line_t *line, cairo_fixed_t y)
|
|||
_cairo_fixed_to_double (line->p2.y - line->p1.y);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cairo_output_stream_t *output_stream;
|
||||
cairo_bool_t has_current_point;
|
||||
} pdf_path_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
pdf_path_info_t *info = closure;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"%f %f m ",
|
||||
_cairo_fixed_to_double (point->x),
|
||||
_cairo_fixed_to_double (point->y));
|
||||
info->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1286,20 +1279,12 @@ _cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
|
|||
static cairo_status_t
|
||||
_cairo_pdf_path_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
pdf_path_info_t *info = closure;
|
||||
const char *pdf_operator;
|
||||
|
||||
if (info->has_current_point)
|
||||
pdf_operator = "l";
|
||||
else
|
||||
pdf_operator = "m";
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
"%f %f %s ",
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"%f %f l ",
|
||||
_cairo_fixed_to_double (point->x),
|
||||
_cairo_fixed_to_double (point->y),
|
||||
pdf_operator);
|
||||
info->has_current_point = TRUE;
|
||||
_cairo_fixed_to_double (point->y));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1310,9 +1295,9 @@ _cairo_pdf_path_curve_to (void *closure,
|
|||
cairo_point_t *c,
|
||||
cairo_point_t *d)
|
||||
{
|
||||
pdf_path_info_t *info = closure;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"%f %f %f %f %f %f c ",
|
||||
_cairo_fixed_to_double (b->x),
|
||||
_cairo_fixed_to_double (b->y),
|
||||
|
|
@ -1327,11 +1312,10 @@ _cairo_pdf_path_curve_to (void *closure,
|
|||
static cairo_status_t
|
||||
_cairo_pdf_path_close_path (void *closure)
|
||||
{
|
||||
pdf_path_info_t *info = closure;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"h\r\n");
|
||||
info->has_current_point = FALSE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1349,7 +1333,6 @@ _cairo_pdf_surface_fill (void *abstract_surface,
|
|||
cairo_pdf_document_t *document = surface->document;
|
||||
const char *pdf_operator;
|
||||
cairo_status_t status;
|
||||
pdf_path_info_t info;
|
||||
|
||||
status = emit_pattern (surface, pattern);
|
||||
if (status)
|
||||
|
|
@ -1360,16 +1343,13 @@ _cairo_pdf_surface_fill (void *abstract_surface,
|
|||
assert (document->current_stream != NULL &&
|
||||
document->current_stream == surface->current_stream);
|
||||
|
||||
info.output_stream = document->output_stream;
|
||||
info.has_current_point = FALSE;
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_pdf_path_move_to,
|
||||
_cairo_pdf_path_line_to,
|
||||
_cairo_pdf_path_curve_to,
|
||||
_cairo_pdf_path_close_path,
|
||||
&info);
|
||||
document->output_stream);
|
||||
|
||||
switch (fill_rule) {
|
||||
case CAIRO_FILL_RULE_WINDING:
|
||||
|
|
@ -1600,7 +1580,6 @@ _cairo_pdf_surface_intersect_clip_path (void *dst,
|
|||
cairo_pdf_document_t *document = surface->document;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
cairo_status_t status;
|
||||
pdf_path_info_t info;
|
||||
const char *pdf_operator;
|
||||
|
||||
_cairo_pdf_surface_ensure_stream (surface);
|
||||
|
|
@ -1617,16 +1596,13 @@ _cairo_pdf_surface_intersect_clip_path (void *dst,
|
|||
surface->has_clip = TRUE;
|
||||
}
|
||||
|
||||
info.output_stream = document->output_stream;
|
||||
info.has_current_point = FALSE;
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_pdf_path_move_to,
|
||||
_cairo_pdf_path_line_to,
|
||||
_cairo_pdf_path_curve_to,
|
||||
_cairo_pdf_path_close_path,
|
||||
&info);
|
||||
document->output_stream);
|
||||
|
||||
switch (fill_rule) {
|
||||
case CAIRO_FILL_RULE_WINDING:
|
||||
|
|
|
|||
|
|
@ -1049,22 +1049,16 @@ _cairo_ps_surface_composite_trapezoids (cairo_operator_t op,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cairo_output_stream_t *output_stream;
|
||||
cairo_bool_t has_current_point;
|
||||
} cairo_ps_surface_path_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_path_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cairo_ps_surface_path_info_t *info = closure;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"%f %f moveto ",
|
||||
_cairo_fixed_to_double (point->x),
|
||||
_cairo_fixed_to_double (point->y));
|
||||
info->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1072,33 +1066,25 @@ _cairo_ps_surface_path_move_to (void *closure, cairo_point_t *point)
|
|||
static cairo_status_t
|
||||
_cairo_ps_surface_path_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
cairo_ps_surface_path_info_t *info = closure;
|
||||
const char *ps_operator;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
if (info->has_current_point)
|
||||
ps_operator = "lineto";
|
||||
else
|
||||
ps_operator = "moveto";
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
"%f %f %s ",
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"%f %f lineto ",
|
||||
_cairo_fixed_to_double (point->x),
|
||||
_cairo_fixed_to_double (point->y),
|
||||
ps_operator);
|
||||
info->has_current_point = TRUE;
|
||||
_cairo_fixed_to_double (point->y));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_path_curve_to (void *closure,
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d)
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d)
|
||||
{
|
||||
cairo_ps_surface_path_info_t *info = closure;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"%f %f %f %f %f %f curveto ",
|
||||
_cairo_fixed_to_double (b->x),
|
||||
_cairo_fixed_to_double (b->y),
|
||||
|
|
@ -1113,11 +1099,10 @@ _cairo_ps_surface_path_curve_to (void *closure,
|
|||
static cairo_status_t
|
||||
_cairo_ps_surface_path_close_path (void *closure)
|
||||
{
|
||||
cairo_ps_surface_path_info_t *info = closure;
|
||||
cairo_output_stream_t *output_stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (info->output_stream,
|
||||
_cairo_output_stream_printf (output_stream,
|
||||
"closepath\n");
|
||||
info->has_current_point = FALSE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1132,7 +1117,6 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface,
|
|||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->stream;
|
||||
cairo_status_t status;
|
||||
cairo_ps_surface_path_info_t info;
|
||||
const char *ps_operator;
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
|
|
@ -1143,16 +1127,13 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
info.output_stream = stream;
|
||||
info.has_current_point = FALSE;
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_ps_surface_path_move_to,
|
||||
_cairo_ps_surface_path_line_to,
|
||||
_cairo_ps_surface_path_curve_to,
|
||||
_cairo_ps_surface_path_close_path,
|
||||
&info);
|
||||
stream);
|
||||
|
||||
switch (fill_rule) {
|
||||
case CAIRO_FILL_RULE_WINDING:
|
||||
|
|
@ -1276,7 +1257,6 @@ _cairo_ps_surface_fill (void *abstract_surface,
|
|||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->stream;
|
||||
cairo_int_status_t status;
|
||||
cairo_ps_surface_path_info_t info;
|
||||
const char *ps_operator;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, source))
|
||||
|
|
@ -1293,16 +1273,13 @@ _cairo_ps_surface_fill (void *abstract_surface,
|
|||
|
||||
emit_pattern (surface, source);
|
||||
|
||||
info.output_stream = stream;
|
||||
info.has_current_point = FALSE;
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_ps_surface_path_move_to,
|
||||
_cairo_ps_surface_path_line_to,
|
||||
_cairo_ps_surface_path_curve_to,
|
||||
_cairo_ps_surface_path_close_path,
|
||||
&info);
|
||||
stream);
|
||||
|
||||
switch (fill_rule) {
|
||||
case CAIRO_FILL_RULE_WINDING:
|
||||
|
|
|
|||
|
|
@ -783,7 +783,6 @@ emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern,
|
|||
typedef struct
|
||||
{
|
||||
cairo_svg_document_t *document;
|
||||
cairo_bool_t has_current_point;
|
||||
xmlBufferPtr path;
|
||||
} svg_path_info_t;
|
||||
|
||||
|
|
@ -801,7 +800,6 @@ _cairo_svg_path_move_to (void *closure, cairo_point_t *point)
|
|||
_cairo_dtostr (buffer, sizeof buffer, _cairo_fixed_to_double (point->y));
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" "));
|
||||
info->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -813,10 +811,7 @@ _cairo_svg_path_line_to (void *closure, cairo_point_t *point)
|
|||
xmlBufferPtr path = info->path;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
if (info->has_current_point)
|
||||
xmlBufferCat (path, CC2XML ("L "));
|
||||
else
|
||||
xmlBufferCat (path, CC2XML ("M "));
|
||||
xmlBufferCat (path, CC2XML ("L "));
|
||||
|
||||
_cairo_dtostr (buffer, sizeof buffer, _cairo_fixed_to_double (point->x));
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
|
|
@ -825,8 +820,6 @@ _cairo_svg_path_line_to (void *closure, cairo_point_t *point)
|
|||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" "));
|
||||
|
||||
info->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -868,10 +861,7 @@ _cairo_svg_path_close_path (void *closure)
|
|||
{
|
||||
svg_path_info_t *info = closure;
|
||||
|
||||
if (info->has_current_point)
|
||||
xmlBufferCat (info->path, CC2XML ("Z "));
|
||||
|
||||
info->has_current_point = FALSE;
|
||||
xmlBufferCat (info->path, CC2XML ("Z "));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -893,7 +883,6 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
xmlBufferPtr style;
|
||||
|
||||
info.document = document;
|
||||
info.has_current_point = FALSE;
|
||||
info.path = xmlBufferCreate ();
|
||||
|
||||
style = xmlBufferCreate ();
|
||||
|
|
@ -1035,7 +1024,6 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
|||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
info.document = document;
|
||||
info.has_current_point = FALSE;
|
||||
info.path = xmlBufferCreate ();
|
||||
|
||||
rx = ry = stroke_style->line_width;
|
||||
|
|
@ -1176,7 +1164,6 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
|
|||
|
||||
if (path != NULL) {
|
||||
info.document = document;
|
||||
info.has_current_point = FALSE;
|
||||
info.path = xmlBufferCreate ();
|
||||
|
||||
group = xmlNewChild (surface->xml_node, NULL, CC2XML ("g"), NULL);
|
||||
|
|
|
|||
60
src/cairo.c
60
src/cairo.c
|
|
@ -957,8 +957,8 @@ cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy)
|
|||
* cairo_new_path:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Clears the current path. After this call there will be no current
|
||||
* point.
|
||||
* Clears the current path. After this call there will be no path and
|
||||
* no current point.
|
||||
**/
|
||||
void
|
||||
cairo_new_path (cairo_t *cr)
|
||||
|
|
@ -976,8 +976,8 @@ slim_hidden_def(cairo_new_path);
|
|||
* @x: the X coordinate of the new position
|
||||
* @y: the Y coordinate of the new position
|
||||
*
|
||||
* If the current subpath is not empty, begin a new subpath. After
|
||||
* this call the current point will be (@x, @y).
|
||||
* Begin a new subpath. After this call the current point will be (@x,
|
||||
* @y).
|
||||
**/
|
||||
void
|
||||
cairo_move_to (cairo_t *cr, double x, double y)
|
||||
|
|
@ -997,6 +997,31 @@ cairo_move_to (cairo_t *cr, double x, double y)
|
|||
}
|
||||
slim_hidden_def(cairo_move_to);
|
||||
|
||||
/**
|
||||
* cairo_new_sub_path:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Begin a new subpath. Note that the existing path is not
|
||||
* affected. After this call there will be no current point.
|
||||
*
|
||||
* In many cases, this call is not needed since new subpaths are
|
||||
* frequently started with cairo_move_to().
|
||||
*
|
||||
* A call to cairo_new_sub_path() is particularly useful when
|
||||
* beginning a new subpath with one of the cairo_arc() calls. This
|
||||
* makes things easier as it is no longer necessary to manually
|
||||
* compute the arc's initial coordinates for a call to
|
||||
* cairo_move_to().
|
||||
**/
|
||||
void
|
||||
cairo_new_sub_path (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
_cairo_path_fixed_new_sub_path (&cr->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_line_to:
|
||||
* @cr: a cairo context
|
||||
|
|
@ -1006,6 +1031,9 @@ slim_hidden_def(cairo_move_to);
|
|||
* Adds a line to the path from the current point to position (@x, @y)
|
||||
* in user-space coordinates. After this call the current point
|
||||
* will be (@x, @y).
|
||||
*
|
||||
* If there is no current point before the call to cairo_line_to()
|
||||
* this function will behave as cairo_move_to (@cr, @x, @y).
|
||||
**/
|
||||
void
|
||||
cairo_line_to (cairo_t *cr, double x, double y)
|
||||
|
|
@ -1038,6 +1066,10 @@ cairo_line_to (cairo_t *cr, double x, double y)
|
|||
* position (@x3, @y3) in user-space coordinates, using (@x1, @y1) and
|
||||
* (@x2, @y2) as the control points. After this call the current point
|
||||
* will be (@x3, @y3).
|
||||
*
|
||||
* If there is no current point before the call to cairo_curve_to()
|
||||
* this function will behave as if preceded by a call to
|
||||
* cairo_move_to (@cr, @x1, @y1).
|
||||
**/
|
||||
void
|
||||
cairo_curve_to (cairo_t *cr,
|
||||
|
|
@ -1208,11 +1240,15 @@ cairo_arc_to (cairo_t *cr,
|
|||
* @dx: the X offset
|
||||
* @dy: the Y offset
|
||||
*
|
||||
* If the current subpath is not empty, begin a new subpath. After
|
||||
* this call the current point will offset by (@x, @y).
|
||||
* Begin a new subpath. After this call the current point will offset
|
||||
* by (@x, @y).
|
||||
*
|
||||
* Given a current point of (x, y), cairo_rel_move_to(@cr, @dx, @dy)
|
||||
* is logically equivalent to cairo_move_to (@cr, x + @dx, y + @dy).
|
||||
*
|
||||
* It is an error to call this function with no current point. Doing
|
||||
* so will cause @cr to shutdown with a status of
|
||||
* CAIRO_STATUS_NO_CURRENT_POINT.
|
||||
**/
|
||||
void
|
||||
cairo_rel_move_to (cairo_t *cr, double dx, double dy)
|
||||
|
|
@ -1244,6 +1280,10 @@ cairo_rel_move_to (cairo_t *cr, double dx, double dy)
|
|||
*
|
||||
* Given a current point of (x, y), cairo_rel_line_to(@cr, @dx, @dy)
|
||||
* is logically equivalent to cairo_line_to (@cr, x + @dx, y + @dy).
|
||||
*
|
||||
* It is an error to call this function with no current point. Doing
|
||||
* so will cause @cr to shutdown with a status of
|
||||
* CAIRO_STATUS_NO_CURRENT_POINT.
|
||||
**/
|
||||
void
|
||||
cairo_rel_line_to (cairo_t *cr, double dx, double dy)
|
||||
|
|
@ -1284,6 +1324,10 @@ slim_hidden_def(cairo_rel_line_to);
|
|||
* @dy1, @dx2, @dy2, @dx3, @dy3) is logically equivalent to
|
||||
* cairo_curve_to (@cr, x + @dx1, y + @dy1, x + @dx2, y + @dy2, x +
|
||||
* @dx3, y + @dy3).
|
||||
*
|
||||
* It is an error to call this function with no current point. Doing
|
||||
* so will cause @cr to shutdown with a status of
|
||||
* CAIRO_STATUS_NO_CURRENT_POINT.
|
||||
**/
|
||||
void
|
||||
cairo_rel_curve_to (cairo_t *cr,
|
||||
|
|
@ -1378,8 +1422,10 @@ cairo_stroke_to_path (cairo_t *cr)
|
|||
* The behavior of cairo_close_path() is distinct from simply calling
|
||||
* cairo_line_to() with the equivalent coordinate in the case of
|
||||
* stroking. When a closed subpath is stroked, there are no caps on
|
||||
* the ends of the subpath. Instead, their is a line join connecting
|
||||
* the ends of the subpath. Instead, there is a line join connecting
|
||||
* the final and initial segments of the subpath.
|
||||
*
|
||||
* If there is no current point, this function will have no effect.
|
||||
**/
|
||||
void
|
||||
cairo_close_path (cairo_t *cr)
|
||||
|
|
|
|||
|
|
@ -435,6 +435,9 @@ cairo_new_path (cairo_t *cr);
|
|||
cairo_public void
|
||||
cairo_move_to (cairo_t *cr, double x, double y);
|
||||
|
||||
cairo_public void
|
||||
cairo_new_sub_path (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_line_to (cairo_t *cr, double x, double y);
|
||||
|
||||
|
|
|
|||
|
|
@ -1394,6 +1394,9 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
|||
cairo_fixed_t x,
|
||||
cairo_fixed_t y);
|
||||
|
||||
cairo_private void
|
||||
_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
|
|
|
|||
1
test/.gitignore
vendored
1
test/.gitignore
vendored
|
|
@ -37,6 +37,7 @@ move-to-show-surface
|
|||
multi-page
|
||||
multi-page.pdf
|
||||
multi-page.ps
|
||||
new-sub-path
|
||||
nil-surface
|
||||
operator-clear
|
||||
operator-source
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ mask \
|
|||
mask-ctm \
|
||||
mask-surface-ctm \
|
||||
move-to-show-surface \
|
||||
new-sub-path \
|
||||
nil-surface \
|
||||
operator-clear \
|
||||
operator-source \
|
||||
|
|
@ -143,6 +144,8 @@ mask-surface-ctm-ref.png \
|
|||
mask-surface-ctm-rgb24-ref.png \
|
||||
move-to-show-surface-ref.png \
|
||||
move-to-show-surface-rgb24-ref.png \
|
||||
new-sub-path-ref.png \
|
||||
new-sub-path-rgb24-ref.png \
|
||||
nil-surface-ref.png \
|
||||
nil-surface-rgb24-ref.png \
|
||||
operator-clear-ref.png \
|
||||
|
|
@ -311,6 +314,7 @@ mask_ctm_LDADD = $(LDADDS)
|
|||
mask_surface_ctm_LDADD = $(LDADDS)
|
||||
multi_page_LDADD = $(LDADDS)
|
||||
move_to_show_surface_LDADD = $(LDADDS)
|
||||
new_sub_path_LDADD = $(LDADDS)
|
||||
nil_surface_LDADD = $(LDADDS)
|
||||
operator_clear_LDADD = $(LDADDS)
|
||||
operator_source_LDADD = $(LDADDS)
|
||||
|
|
|
|||
BIN
test/new-sub-path-ref.png
Normal file
BIN
test/new-sub-path-ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 386 B |
BIN
test/new-sub-path-rgb24-ref.png
Normal file
BIN
test/new-sub-path-rgb24-ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 355 B |
79
test/new-sub-path.c
Normal file
79
test/new-sub-path.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairo-test.h"
|
||||
|
||||
#define SIZE 10
|
||||
|
||||
cairo_test_t test = {
|
||||
"new-sub-path",
|
||||
"Test the cairo_new_sub_path call",
|
||||
8 * SIZE,
|
||||
3 * SIZE
|
||||
};
|
||||
|
||||
static cairo_test_status_t
|
||||
draw (cairo_t *cr, int width, int height)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */
|
||||
|
||||
/* Test cairo_new_sub_path followed by several different
|
||||
* path-modification functions in turn...
|
||||
*/
|
||||
|
||||
/* ... cairo_move_to */
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_move_to (cr, SIZE, SIZE);
|
||||
cairo_line_to (cr, SIZE, 2 * SIZE);
|
||||
|
||||
/* ... cairo_line_to */
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_line_to (cr, 2 * SIZE, 1.5 * SIZE);
|
||||
cairo_line_to (cr, 3 * SIZE, 1.5 * SIZE);
|
||||
|
||||
/* ... cairo_curve_to */
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_curve_to (cr,
|
||||
4.0 * SIZE, 1.5 * SIZE,
|
||||
4.5 * SIZE, 1.0 * SIZE,
|
||||
5.0 * SIZE, 1.5 * SIZE);
|
||||
|
||||
/* ... cairo_arc */
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr,
|
||||
6.5 * SIZE, 1.5 * SIZE,
|
||||
0.5 * SIZE,
|
||||
0.0, 2.0 * M_PI);
|
||||
|
||||
cairo_stroke (cr);
|
||||
|
||||
return CAIRO_TEST_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return cairo_test (&test, draw);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue