From d96c578dc5c23c441057ddacad33acf64b39d71f Mon Sep 17 00:00:00 2001 From: lecoanet Date: Tue, 14 Jan 2003 11:09:16 +0000 Subject: * Le contour pass� � la cr�ation du curve n'est plus maintenu dans le sens CCW. Il est laiss� tel quel. * Ajout d'un attribut -fillrule controlant la fa�on de remplir un curve. * (Coords): suppression de la possiblilit� d'ajouter un contour � une curve sans contour et suppression de la destruction automatique d'un contour lorsqu'il devient vide. Il faudra d�sormais passer par la commande contour. --- generic/Curve.c | 120 +++++++++++++------------------------------------------- 1 file 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); } -- cgit v1.1