aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--generic/Curve.c146
1 files changed, 113 insertions, 33 deletions
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];
}