[cairo] Inconsistent close_path behavior in
cairo_path_copy_flat/cairo_stroke
T Rowley
tor at cs.brown.edu
Wed Aug 16 14:46:08 PDT 2006
_cpdp_close_path (used by cairo_path_copy_flat) behaves differently than
normal stroking. In a normal stroke, _cairo_stroker_close_path
inserts a line_to so the current point is set to the first point of the
subpath. _cpdp_close_path on the other hand sets the current point to
0,0. This causes a problem if curve_to is called after a close_path.
The attached testcase illustrates the problem we're seeing.
-------------- next part --------------
#include "cairo-test.h"
int
main (void)
{
cairo_surface_t *surface;
cairo_t *ctx;
cairo_path_t *path;
cairo_path_data_t *data;
int i;
float length, startx, starty, x, y;
length = startx = starty = x = y = 0;
cairo_test_init ("flatten-close");
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
ctx = cairo_create (surface);
/* Draw two lines, a horizontal one via line_to and close_path,
* and then a vertial one using curve_to with control points at
* the endpoints.
*/
cairo_move_to (ctx, 100, 100);
cairo_line_to (ctx, 150, 100);
cairo_close_path (ctx);
/* Drawing normally with cairo_stroke, the behavior is as if
* "cairo_move_to (ctx, 100, 100)" was here.
*
* For flattened paths, _cpdp_close_path sets the current point to
* (0,0) so it's as if a "cairo_move_to (ctx, 0, 0)" is here.
*/
cairo_curve_to (ctx, 100, 100, 100,50, 100,50);
path = cairo_copy_path_flat (ctx);
for (i=0; i < path->num_data; i += path->data[i].header.length) {
data = &path->data[i];
switch (data->header.type) {
case CAIRO_PATH_MOVE_TO:
startx = x = data[1].point.x;
starty = y = data[1].point.y;
cairo_test_log ("move_to %f %f\n", x, y);
break;
case CAIRO_PATH_LINE_TO:
{
float dx = data[1].point.x - x;
float dy = data[1].point.y - y;
length += sqrt(dx * dx + dy * dy);
x = data[1].point.x;
y = data[1].point.y;
cairo_test_log ("line_to %f %f\n", x, y);
break;
}
case CAIRO_PATH_CURVE_TO:
break;
case CAIRO_PATH_CLOSE_PATH:
{
float dx = startx - x;
float dy = starty - y;
length += sqrt(dx * dx + dy * dy);
x = startx;
y = starty;
cairo_test_log ("close_path\n");
break;
}
}
}
cairo_path_destroy(path);
cairo_destroy(ctx);
cairo_surface_destroy(surface);
cairo_test_log ("length %f\n", length);
if (length != 150.0)
return CAIRO_TEST_FAILURE;
return CAIRO_TEST_SUCCESS;
}
More information about the cairo
mailing list