From 882fdc59d80bc71c7d9116196fd6683cf82c46ac Mon Sep 17 00:00:00 2001 From: lecoanet Date: Thu, 15 Mar 2001 08:57:28 +0000 Subject: Correction d'un core dump quand le curve est -closed. Correction du style de relief, il �tait invers�. Un curve sans points n'a pas de contours, avant il avait un contour vide. Correction d'un bug qui emp�chait d'ajouter des points ou de modifier un curve sans contour par la commande coords. --- generic/Curve.c | 146 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 33 deletions(-) (limited to 'generic/Curve.c') diff --git a/generic/Curve.c b/generic/Curve.c index efed448..8bda064 100644 --- a/generic/Curve.c +++ b/generic/Curve.c @@ -312,7 +312,7 @@ Clone(Item item) int i; ZnContour *conts; ZnBool *holes; - + POLY_INIT(&cv->dev_shape); if (cv->shape.num_contours) { @@ -389,6 +389,7 @@ Destroy(Item item) CurveItem cv = (CurveItem) item; POLY_FREE(&cv->shape); + cv->dev_shape.holes = NULL; POLY_FREE(&cv->dev_shape); if (cv->first_end) { @@ -644,6 +645,7 @@ ComputeCoordinates(Item item, ResetBBox(&item->item_bounding_box); + /*printf("flags %x\n", cv->flags);*/ SetRenderFlags(cv); /* @@ -677,6 +679,7 @@ ComputeCoordinates(Item item, * Allocate space for devices coordinates, the holes array is _NOT_ * duplicated. */ + cv->dev_shape.holes = NULL; POLY_FREE(&cv->dev_shape); if (cv->shape.contours != &cv->shape.contour1) { cv->dev_shape.contours = (ZnContour *) ZnMalloc(num_contours*sizeof(ZnContour)); @@ -685,6 +688,7 @@ ComputeCoordinates(Item item, cv->dev_shape.contours = &cv->dev_shape.contour1; cv->dev_shape.cw = &cv->dev_shape.cw1; } + cv->dev_shape.holes = cv->shape.holes; cv->dev_shape.num_contours = num_contours; c1 = cv->shape.contours; c2 = cv->dev_shape.contours; @@ -695,9 +699,9 @@ ComputeCoordinates(Item item, * if needed. */ if (ISSET(cv->flags, CLOSED_BIT) && - ((c2->points[0].x != c2->points[c2->num_points-1].x) || - (c2->points[0].y != c2->points[c2->num_points-1].y)) && - (c2->num_points != 1)) { + ((c1->points[0].x != c1->points[c2->num_points-1].x) || + (c1->points[0].y != c1->points[c2->num_points-1].y)) && + (c1->num_points != 1)) { c2->num_points++; } c2->points = (ZnPoint *) ZnMalloc((c2->num_points)*sizeof(ZnPoint)); @@ -1034,6 +1038,7 @@ Draw(Item item) unsigned int gc_mask; ZnPoint *points=NULL; XPoint *xpoints=NULL; + ReliefStyle relief; if ((cv->dev_shape.num_contours == 0) || (ISCLEAR(cv->flags, FILLED_OK) && @@ -1121,11 +1126,29 @@ Draw(Item item) for (j = 0; j < cv->dev_shape.num_contours; j++) { num_points = cv->dev_shape.contours[j].num_points; points = cv->dev_shape.contours[j].points; - /*printf("Draw: num_points %d %g@%g %g@%g, cw %d\n", + /*printf("Draw: item %d, num_points %d %g@%g %g@%g, holes %d cw %d i/o %d\n", + item->id, num_points, points[0].x, points[0].y, - points[num_points-1].x, points[num_points-1].y, - cv->dev_shape.cw[j]);*/ - DrawPolygonRelief(wi, cv->relief, cv->gradient, points, num_points, + points[num_points-1].x, points[num_points-1].y,cv->shape.holes[j], + cv->dev_shape.cw[j], cv->dev_shape.cw[j]^cv->shape.holes[j]);*/ + relief = cv->relief; + if (cv->dev_shape.cw[j]^cv->shape.holes[j]) { + switch (relief) { + case RELIEF_BEVEL_OUT: + relief = RELIEF_BEVEL_IN; + break; + case RELIEF_BEVEL_IN: + relief = RELIEF_BEVEL_OUT; + break; + case RELIEF_RIDGE: + relief = RELIEF_GROOVE; + break; + case RELIEF_GROOVE: + relief = RELIEF_RIDGE; + break; + } + } + DrawPolygonRelief(wi, relief, cv->gradient, points, num_points, (cv->dev_shape.cw[j]^cv->shape.holes[j])?-cv->line_width:cv->line_width); } } @@ -1510,36 +1533,57 @@ Coords(Item item, /*printf("contour %d, num_pts %d, index %d, cmd %d\n", contour, *num_pts, index, cmd);*/ + /*printf("nb contours: %d\n", cv->shape.num_contours);*/ if (contour < 0) { contour += cv->shape.num_contours; } - 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))) { Tcl_AppendResult(item->wi->interp, " curve contour index out of range", NULL); return ZN_ERROR; } - c = &cv->shape.contours[contour]; + if (cv->shape.num_contours != 0) { + c = &cv->shape.contours[contour]; + } + + /* REPLACE */ if ((cmd == COORDS_REPLACE) || (cmd == COORDS_REPLACE_ALL)) { - if (*num_pts == 0) { - Tcl_AppendResult(item->wi->interp, - " coords command need at least 1 point on curves", NULL); - return ZN_ERROR; - } if (cmd == COORDS_REPLACE_ALL) { - replace_all: - if (c->points) { - ZnFree(c->points); + /* + * 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); + c = &cv->shape.contours[0]; + } + if (*num_pts) { + if (c->points) { + ZnFree(c->points); + } + c->points = (ZnPoint *) ZnMalloc(*num_pts*sizeof(ZnPoint)); + c->num_points = *num_pts; + memcpy(c->points, *pts, *num_pts*sizeof(ZnPoint)); + } + else { + goto cont_remove; } - c->points = (ZnPoint *) ZnMalloc(*num_pts*sizeof(ZnPoint)); - c->num_points = *num_pts; - memcpy(c->points, *pts, *num_pts*sizeof(ZnPoint)); } else { - if (c->num_points == 0) { - edit_err: + 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 command cannot edit empty curve contour", NULL); + " coords replace command need at least 1 point on curves", NULL); return ZN_ERROR; } if (index < 0) { @@ -1555,11 +1599,15 @@ Coords(Item item, CLEAR(cv->flags, REDUCED_BIT); ITEM.Invalidate(item, ZN_COORDS_FLAG); } + + /* READ */ + else if ((cmd == COORDS_READ) || (cmd == COORDS_READ_ALL)) { - if (c->num_points == 0) { - *num_pts = 0; - *pts = NULL; - return ZN_OK; + 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; @@ -1576,9 +1624,20 @@ Coords(Item item, *pts = &c->points[index]; } } + + /* ADD */ + else if ((cmd == COORDS_ADD) || (cmd == COORDS_ADD_LAST)) { - if (c->num_points == 0) { - goto replace_all; + 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); + c = &cv->shape.contours[0]; } if (cmd == COORDS_ADD_LAST) { index = c->num_points; @@ -1604,9 +1663,15 @@ Coords(Item item, CLEAR(cv->flags, REDUCED_BIT); ITEM.Invalidate(item, ZN_COORDS_FLAG); } + + /* REMOVE */ + else if (cmd == COORDS_REMOVE) { - if (c->num_points == 0) { - goto edit_err; + 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; @@ -1615,7 +1680,22 @@ Coords(Item item, goto range_err; } c->num_points--; - if (index != c->num_points) { + if (c->num_points == 0) { + /* + * Contour is removed. + */ + cont_remove: + if (cv->shape.num_contours == 1) { + POLY_FREE(&cv->shape); + } + else { + ZnFree(c->points); + for (i = contour; i < cv->shape.num_contours; i++) { + cv->shape.contours[i] = cv->shape.contours[i+1]; + } + } + } + else if (index != c->num_points) { for (i = index; i < c->num_points; i++) { c->points[i] = c->points[i+1]; } -- cgit v1.1