aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/Curve.c120
1 files changed, 28 insertions, 92 deletions
diff --git a/generic/Curve.c b/generic/Curve.c
index 23933d9..a881a4b 100644
--- a/generic/Curve.c
+++ b/generic/Curve.c
@@ -85,6 +85,7 @@ typedef struct _CurveItemStruct {
ZnImage line_pattern;
ZnGradient *line_color;
ZnGradient *marker_color;
+ int fill_rule;
ZnImage tile;
/* Private data */
@@ -112,10 +113,12 @@ static ZnAttrConfig cv_attrs[] = {
{ ZN_CONFIG_GRADIENT, "-fillcolor", NULL,
Tk_Offset(CurveItemStruct, fill_color), 0,
ZN_COORDS_FLAG|ZN_BORDER_FLAG, False },
- { ZN_CONFIG_BITMAP, "-fillpattern", NULL,
- Tk_Offset(CurveItemStruct, fill_pattern), 0, ZN_DRAW_FLAG, False },
{ ZN_CONFIG_BOOL, "-filled", NULL,
Tk_Offset(CurveItemStruct, flags), FILLED_BIT, ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_BITMAP, "-fillpattern", NULL,
+ Tk_Offset(CurveItemStruct, fill_pattern), 0, ZN_DRAW_FLAG, False },
+ { ZN_CONFIG_FILL_RULE, "-fillrule", NULL,
+ Tk_Offset(CurveItemStruct, fill_rule), 0, ZN_COORDS_FLAG, False },
{ ZN_CONFIG_LINE_END, "-firstend", NULL,
Tk_Offset(CurveItemStruct, first_end), 0, ZN_COORDS_FLAG, False },
{ ZN_CONFIG_JOIN_STYLE, "-joinstyle", NULL,
@@ -175,7 +178,7 @@ Init(Item item,
CurveItem cv = (CurveItem) item;
int i, num_points, count;
ZnPoint *p, *points;
- char *controls, *c;
+ char *controls;
cv->outlines.num_contours = 0;
cv->outlines.contours = NULL;
@@ -183,7 +186,7 @@ Init(Item item,
cv->tristrip.strips = NULL;
cv->gradient = NULL;
cv->grad_geo = NULL;
-
+
/* Init attributes */
SET(item->flags, VISIBLE_BIT);
SET(item->flags, SENSITIVE_BIT);
@@ -192,14 +195,16 @@ Init(Item item,
SET(item->flags, COMPOSE_SCALE_BIT);
CLEAR(cv->flags, CLOSED_BIT);
CLEAR(cv->flags, SMOOTH_RELIEF_BIT);
-
+ cv->fill_rule = GLU_TESS_WINDING_ODD;
+
item->priority = DEFAULT_CURVE_PRIORITY;
if (*argc < 1) {
Tcl_AppendResult(wi->interp, " curve coords expected", NULL);
return ZN_ERROR;
}
- if (ZnParseCoordList(wi, (*args)[0], &points, &controls, &num_points) == ZN_ERROR) {
+ if (ZnParseCoordList(wi, (*args)[0], &points,
+ &controls, &num_points, NULL) == ZN_ERROR) {
return ZN_ERROR;
}
@@ -236,31 +241,13 @@ Init(Item item,
}
}
/*
- * Do not allow a hole to be added as the first contour, it breaks
- * backward compatibility. Instead silently convert it to a plain
- * contour.
+ * Make a local copy of the points. This is not necessary
+ * for the optional control list.
*/
p = ZnMalloc(num_points * sizeof(ZnPoint));
- if (! TestCCW(points, num_points)) {
- if (controls) {
- c = ZnMalloc(num_points * sizeof(char));
- for (i = 0; i < num_points; i++) {
- c[num_points-i-1] = controls[i];
- }
- ZnFree(controls);
- controls = c;
- }
- for (i = 0; i < num_points; i++) {
- p[num_points-i-1] = points[i];
- }
- /*printf("revert hole to contour, numpoints: %d %g@%g\n",
- num_points, points[0].x, points[0].y);*/
- }
- else {
- /*printf("plain contour, numpoints: %d %g@%g\n",
- num_points, points[0].x, points[0].y);*/
- memcpy(p, points, num_points * sizeof(ZnPoint));
- }
+ /*printf("plain contour, numpoints: %d %g@%g\n",
+ num_points, points[0].x, points[0].y);*/
+ memcpy(p, points, num_points * sizeof(ZnPoint));
POLY_CONTOUR1(&cv->shape, p, num_points, False);
cv->shape.contours[0].controls = controls;
}
@@ -653,7 +640,7 @@ UpdateTristrip(CurveItem cv,
gluTessCallback(wi->tess, GLU_TESS_END_DATA, (void (*)()) CurveTessEnd);
gluTessCallback(wi->tess, GLU_TESS_COMBINE_DATA, (void (*)()) CurveTessCombine);
gluTessCallback(wi->tess, GLU_TESS_ERROR_DATA, (void (*)()) CurveTessError);
- gluTessProperty(wi->tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
+ gluTessProperty(wi->tess, GLU_TESS_WINDING_RULE, cv->fill_rule);
gluTessNormal(wi->tess, 0, 0, -1);
if (cv->tristrip.num_strips == 0) {
@@ -724,7 +711,7 @@ UpdateOutlines(CurveItem cv,
gluTessCallback(wi->tess, GLU_TESS_END_DATA, (void (*)()) CurveTessEnd);
gluTessCallback(wi->tess, GLU_TESS_COMBINE_DATA, (void (*)()) CurveTessCombine);
gluTessCallback(wi->tess, GLU_TESS_ERROR_DATA, (void (*)()) CurveTessError);
- gluTessProperty(wi->tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
+ gluTessProperty(wi->tess, GLU_TESS_WINDING_RULE, cv->fill_rule);
gluTessNormal(wi->tess, 0, 0, -1);
if (cv->outlines.num_contours == 0) {
@@ -859,7 +846,7 @@ ComputeCoordinates(Item item,
if (!c1->controls[j]) {
if (segment_start != j-1) {
/* traitement bezier */
- /* printf("arcto %g@%g %g@%g %g@%g\n",
+ /*printf("arcto %g@%g %g@%g %g@%g\n",
c2->points[segment_start+1].x, c2->points[segment_start+1].y,
c2->points[j-1].x, c2->points[j-1].y,
c2->points[j].x, c2->points[j].y);*/
@@ -1849,9 +1836,7 @@ Coords(Item item,
if (contour < 0) {
contour += cv->shape.num_contours;
}
- if ((contour < 0) ||
- ((cv->shape.num_contours == 0) && (contour != 0)) ||
- ((cv->shape.num_contours != 0) && (contour >= cv->shape.num_contours))) {
+ if ((contour < 0) || (contour >= cv->shape.num_contours)) {
Tcl_AppendResult(item->wi->interp,
" curve contour index out of range", NULL);
return ZN_ERROR;
@@ -1865,15 +1850,9 @@ Coords(Item item,
if ((cmd == COORDS_REPLACE) || (cmd == COORDS_REPLACE_ALL)) {
if (cmd == COORDS_REPLACE_ALL) {
/*
- * Replacing all coordinates of an empty curve is legal, resulting
- * in a curve with one contour.
* Replacing all the coordinates of a contour by no coordinates
* is also legal, resulting in the contour being removed.
*/
- if ((cv->shape.num_contours == 0) && (*num_pts)) {
- POLY_CONTOUR1(&cv->shape, NULL, 0, False);
- c = &cv->shape.contours[0];
- }
if (*num_pts) {
if (c->points) {
ZnFree(c->points);
@@ -1886,17 +1865,8 @@ Coords(Item item,
memcpy(c->controls, *controls, *num_pts*sizeof(char));
}
}
- else {
- goto cont_remove;
- }
}
else {
- if (cv->shape.num_contours == 0) {
- Tcl_AppendResult(item->wi->interp,
- " coords replace command cannot be performed on an empty curve",
- NULL);
- return ZN_ERROR;
- }
if (*num_pts == 0) {
Tcl_AppendResult(item->wi->interp,
" coords replace command need at least 1 point on curves", NULL);
@@ -1962,12 +1932,6 @@ Coords(Item item,
/* READ */
else if ((cmd == COORDS_READ) || (cmd == COORDS_READ_ALL)) {
- if (cv->shape.num_contours == 0) {
- Tcl_AppendResult(item->wi->interp,
- " coords read command cannot be performed on an empty curve",
- NULL);
- return ZN_ERROR;
- }
if (cmd == COORDS_READ_ALL) {
*num_pts = c->num_points;
*pts = c->points;
@@ -1996,14 +1960,6 @@ Coords(Item item,
if (*num_pts == 0) {
return ZN_OK;
}
- /*
- * Adding to an empty curve is possible. A contour zero is
- * created.
- */
- if (cv->shape.num_contours == 0) {
- POLY_CONTOUR1(&cv->shape, NULL, 0, False);
- c = &cv->shape.contours[0];
- }
if (cmd == COORDS_ADD_LAST) {
index = c->num_points;
}
@@ -2033,7 +1989,7 @@ Coords(Item item,
for (i = index-1; c->controls[i] && (i >= 0); i--, num_controls++);
}
}
- printf("******* num controls: %d\n", num_controls);
+ /*printf("******* num controls: %d\n", num_controls);*/
for (i = 0; i < *num_pts; i++) {
if (!(*controls)[i]) {
num_controls = 0;
@@ -2045,11 +2001,11 @@ Coords(Item item,
}
}
}
- printf("******* num controls(2): %d\n", num_controls);
+ /*printf("******* num controls(2): %d\n", num_controls);*/
if (c->controls) {
for (i = index; c->controls[i] && (i < c->num_points); i++, num_controls++);
}
- printf("******* num controls(3): %d\n", num_controls);
+ /*printf("******* num controls(3): %d\n", num_controls);*/
if (num_controls > 2) {
goto control_err;
}
@@ -2086,12 +2042,6 @@ Coords(Item item,
/* REMOVE */
else if (cmd == COORDS_REMOVE) {
- if (cv->shape.num_contours == 0) {
- Tcl_AppendResult(item->wi->interp,
- " coords remove command cannot be performed on an empty curve",
- NULL);
- return ZN_ERROR;
- }
if (index < 0) {
index += c->num_points;
}
@@ -2111,25 +2061,7 @@ Coords(Item item,
}
c->num_points--;
- if (c->num_points == 0) {
- /*
- * Contour is removed.
- */
- cont_remove:
- if (c->controls) {
- ZnFree(c->controls);
- }
- ZnFree(c->points);
- if (cv->shape.num_contours == 1) {
- POLY_FREE(&cv->shape);
- }
- else {
- for (i = contour; i < cv->shape.num_contours; i++) {
- cv->shape.contours[i] = cv->shape.contours[i+1];
- }
- }
- }
- else if (index != c->num_points) {
+ if ((c->num_points != 0) && (index != c->num_points)) {
for (i = index; i < c->num_points; i++) {
c->points[i] = c->points[i+1];
if (c->controls) {
@@ -2137,6 +2069,10 @@ Coords(Item item,
}
}
}
+ c->points = ZnRealloc(c->points, (c->num_points)*sizeof(ZnPoint));
+ if (c->controls) {
+ c->controls = ZnRealloc(c->controls, (c->num_points)*sizeof(char));
+ }
ITEM.Invalidate(item, ZN_COORDS_FLAG);
}