aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in3
-rwxr-xr-xdebian/rules3
-rw-r--r--debian/zinc-perl.files3
-rw-r--r--generic/Triangles.c877
-rw-r--r--sandbox/local.pl59
5 files changed, 926 insertions, 19 deletions
diff --git a/Makefile.in b/Makefile.in
index fe02340..73dc766 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -159,8 +159,10 @@ testptk: ptkzinc
(cd Perl; make test "FULLPERL=PERL_DL_NONLAZY=0 perl")
Perl/Makefile_nodebug:
(cd Perl; perl Makefile.PL ptkzinc$(ZINC_VER).$(ZINC_MAJOR) $(PERLCONFIG))
+ (cd Perl/debug; perl Makefile.PL $(PERLCONFIG))
Perl/Makefile_debug:
(cd Perl; perl Makefile.PL ptkzinc$(ZINC_VER).$(ZINC_MAJOR)_debug $(PERLCONFIG))
+ (cd Perl/debug; perl Makefile.PL $(PERLCONFIG))
libptkzinc$(ZINC_VER).$(ZINC_MAJOR).so: ptk $(ptkobjs) libom.so $(GPC)
$(CC) $(SHARED_TK_LDFLAGS) -o $@ $(ptkobjs) $(SHARED_TK_LIBS) -L. -lom $(GPC) $(GLX)
@@ -220,6 +222,7 @@ installtk: installdirs $(tklibs)
installptk: $(ptklibs)
$(INSTALL_DATA) $(ptklibs) $(libdir)
(cd Perl; make; make $(INSTALL_PERL))
+ (cd Perl/debug; make; make $(INSTALL_PERL))
installdirs:
$(srcdir)/mkinstalldirs $(libdir) $(incdir) $(mandir)
diff --git a/debian/rules b/debian/rules
index ac9581c..74a7005 100755
--- a/debian/rules
+++ b/debian/rules
@@ -53,6 +53,7 @@ binary-arch: checkroot build
install -m644 debian/copyright debian/tmp/usr/share/doc/zinc-perl
install -m644 debian/changelog debian/tmp/usr/share/doc/zinc-perl
gzip -9 debian/tmp/usr/share/doc/zinc-perl/changelog
+ find debian/tmp/usr/lib/perl -type f -name .packlist | xargs rm -f
find debian/tmp/usr/lib/perl5 -type f -name .packlist | xargs rm -f
install -m644 Python/Zinc.py debian/tmp/usr/lib/python1.5/site-packages/
@@ -68,7 +69,7 @@ binary-arch: checkroot build
debstd -m -c -s doc/muwr.tex doc/refman.tex doc/refman.ps
dh_compress -Xrefman.ps
dh_md5sums
- -rm -Rf debian/tmp/usr/share/doc/zinc-perl debian/tmp/usr/share/doc/zinc-python debian/tmp/usr/lib/perl5 debian/tmp/usr/lib/python1.5
+ -rm -Rf debian/tmp/usr/share/doc/zinc-perl debian/tmp/usr/share/doc/zinc-python debian/tmp/usr/lib/perl5 debian/tmp/usr/lib/perl debian/tmp/usr/lib/python1.5
dpkg-gencontrol -isp -pzinc-tk
chown -R root.root debian/tmp
chmod -R go=rX debian/tmp
diff --git a/debian/zinc-perl.files b/debian/zinc-perl.files
index d113693..994f691 100644
--- a/debian/zinc-perl.files
+++ b/debian/zinc-perl.files
@@ -1,3 +1,4 @@
-usr/lib/libptkzinc3.1.so
+usr/lib/libptkzinc3.2.so
+usr/lib/perl
usr/lib/perl5
usr/share/doc/zinc-perl
diff --git a/generic/Triangles.c b/generic/Triangles.c
new file mode 100644
index 0000000..41487e0
--- /dev/null
+++ b/generic/Triangles.c
@@ -0,0 +1,877 @@
+/*
+ * Triangles.c -- Implementation of Triangle fan/strips item.
+ *
+ * Authors : Patrick Lecoanet.
+ * Creation date : Tue Dec 11 10:52:01 2001
+ *
+ * $Id$
+ */
+
+/*
+ * Copyright (c) 1993 - 2001 CENA, Patrick Lecoanet --
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this code; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include "Draw.h"
+#include "Item.h"
+#include "Geo.h"
+#include "Types.h"
+#include "WidgetInfo.h"
+#include "Image.h"
+#include "Color.h"
+
+#include <ctype.h>
+#include <malloc.h>
+
+
+static const char rcsid[] = "$Id";
+static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $";
+
+
+/*
+ * Bit offset of flags.
+ */
+#define FAN_BIT 1<<0 /* Tell if the triangles are arranged in fan or strips. */
+
+
+/*
+ **********************************************************************************
+ *
+ * Specific Triangles item record
+ *
+ **********************************************************************************
+ */
+typedef struct _TrianglesItemStruct {
+ ItemStruct header;
+
+ /* Public data */
+ ZnList points;
+ unsigned int flags;
+ ZnList colors;
+
+ /* Private data */
+ ZnTriStrip dev_points;
+} TrianglesItemStruct, *TrianglesItem;
+
+
+static ZnAttrConfig tr_attrs[] = {
+ { ZN_CONFIG_COLORS, "-colors", NULL,
+ Tk_Offset(TrianglesItemStruct, colors), 0, ZN_DRAW_FLAG, False },
+ { ZN_CONFIG_BOOL, "-composerotation", NULL,
+ Tk_Offset(TrianglesItemStruct, header.flags), COMPOSE_ROTATION_BIT,
+ ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_BOOL, "-composescale", NULL,
+ Tk_Offset(TrianglesItemStruct, header.flags), COMPOSE_SCALE_BIT,
+ ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_BOOL, "-fan", NULL,
+ Tk_Offset(TrianglesItemStruct, flags), FAN_BIT, ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_PRI, "-priority", NULL,
+ Tk_Offset(TrianglesItemStruct, header.priority), 0,
+ ZN_DRAW_FLAG|ZN_REPICK_FLAG, False },
+ { ZN_CONFIG_BOOL, "-sensitive", NULL,
+ Tk_Offset(TrianglesItemStruct, header.flags), SENSITIVE_BIT,
+ ZN_REPICK_FLAG, False },
+ { ZN_CONFIG_TAGS, "-tags", NULL,
+ Tk_Offset(TrianglesItemStruct, header.tags), 0, 0, False },
+ { ZN_CONFIG_BOOL, "-visible", NULL,
+ Tk_Offset(TrianglesItemStruct, header.flags), VISIBLE_BIT,
+ ZN_DRAW_FLAG|ZN_REPICK_FLAG|ZN_VIS_FLAG, False },
+
+ { ZN_CONFIG_END, NULL, NULL, 0, 0, 0 }
+};
+
+
+/*
+ **********************************************************************************
+ *
+ * Init --
+ *
+ **********************************************************************************
+ */
+static int
+Init(Item item,
+ int *argc,
+ Tcl_Obj *CONST *args[])
+{
+ WidgetInfo *wi = item->wi;
+ TrianglesItem tr = (TrianglesItem) item;
+ Tcl_Obj **elems;
+ int i, num_elems;
+ ZnPoint p;
+ ZnGradientColor *colors;
+
+ tr->dev_points.num_strips = 0;
+
+ /* Init attributes */
+ SET(item->flags, VISIBLE_BIT);
+ SET(item->flags, SENSITIVE_BIT);
+ SET(item->flags, COMPOSE_ROTATION_BIT);
+ SET(item->flags, COMPOSE_SCALE_BIT);
+ item->priority = DEFAULT_TRIANGLES_PRIORITY;
+
+ if (*argc < 1) {
+ Tcl_AppendResult(wi->interp, " triangles coords expected", NULL);
+ return ZN_ERROR;
+ }
+ if ((Tcl_ListObjGetElements(wi->interp, (*args)[0], &num_elems, &elems) == ZN_ERROR) ||
+ ((num_elems % 2) != 0) || (num_elems < 6)) {
+ tr_error:
+ Tcl_AppendResult(wi->interp, " malformed triangles coords", NULL);
+ return ZN_ERROR;
+ }
+
+ tr->points = ZnListNew(num_elems/2, sizeof(ZnPoint));
+ for (i = 0; i < num_elems; i += 2) {
+ if (Tcl_GetDoubleFromObj(wi->interp, elems[i], &p.x) == ZN_ERROR) {
+ tr_error2:
+ ZnListFree(tr->points);
+ tr->points = NULL;
+ goto tr_error;
+ }
+ if (Tcl_GetDoubleFromObj(wi->interp, elems[i+1], &p.y) == ZN_ERROR) {
+ goto tr_error2;
+ }
+ ZnListAdd(tr->points, &p, ZnListTail);
+ }
+ (*args)++;
+ (*argc)--;
+
+ CLEAR(tr->flags, FAN_BIT);
+ tr->colors = ZnListNew(1, sizeof(ZnGradientColor));
+ ZnListAssertSize(tr->colors, 1);
+ colors = ZnListArray(tr->colors);
+ colors->alpha = 100;
+ colors->shades[0] = ZnGetColorByValue(wi->win, wi->fore_color);
+
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Clone --
+ *
+ **********************************************************************************
+ */
+static void
+Clone(Item item)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+
+ tr->dev_points.num_strips = 0;
+
+ if (tr->points) {
+ tr->points = ZnListDuplicate(tr->points);
+ }
+ if (tr->colors) {
+ tr->colors = ZnListDuplicate(tr->colors);
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Destroy --
+ *
+ **********************************************************************************
+ */
+static void
+Destroy(Item item)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+
+ if (tr->points) {
+ ZnListFree(tr->points);
+ }
+ if (tr->dev_points.num_strips) {
+ ZnFree(tr->dev_points.strips->points);
+ }
+ if (tr->colors) {
+ ZnListFree(tr->colors);
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Configure --
+ *
+ **********************************************************************************
+ */
+static int
+Configure(Item item,
+ int argc,
+ Tcl_Obj *CONST argv[],
+ int *flags)
+{
+ int status = ZN_OK;
+
+ status = ITEM_P.ConfigureAttributes((char *) item, -1, argc, argv, flags);
+
+ return status;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Query --
+ *
+ **********************************************************************************
+ */
+static int
+Query(Item item,
+ int argc,
+ Tcl_Obj *CONST argv[])
+{
+ if (ITEM_P.QueryAttribute((char *) item, -1, argv[0]) == ZN_ERROR) {
+ return ZN_ERROR;
+ }
+
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * ComputeCoordinates --
+ *
+ **********************************************************************************
+ */
+static void
+ComputeCoordinates(Item item,
+ ZnBool force)
+{
+ WidgetInfo *wi = item->wi;
+ TrianglesItem tr = (TrianglesItem) item;
+ ZnPoint *points;
+ ZnPoint *dev_points;
+ int num_points;
+
+ ResetBBox(&item->item_bounding_box);
+ if (tr->points == NULL) {
+ return;
+ }
+
+ points = (ZnPoint *) ZnListArray(tr->points);
+ num_points = ZnListSize(tr->points);
+
+ /*
+ * Allocate space for devices coordinates
+ */
+ if (tr->dev_points.num_strips == 0) {
+ dev_points = ZnMalloc(num_points * sizeof(ZnPoint));
+ }
+ else {
+ dev_points = tr->dev_points.strips->points;
+ if (tr->dev_points.strips->num_points < num_points) {
+ dev_points = ZnRealloc(dev_points, num_points * sizeof(ZnPoint));
+ }
+ }
+ TRI_STRIP1(&tr->dev_points, dev_points, num_points);
+
+ /*
+ * Compute device coordinates.
+ */
+ ZnTransformPoints(wi->current_transfo, points, dev_points, num_points);
+ tr->dev_points.fan = ISSET(tr->flags, FAN_BIT);
+
+ /*
+ * Compute the bounding box.
+ */
+ AddPointsToBBox(&item->item_bounding_box, dev_points, num_points);
+
+ /*
+ * Expand the bounding box by one pixel in all
+ * directions to take care of rounding errors.
+ */
+ item->item_bounding_box.orig.x -= 1;
+ item->item_bounding_box.orig.y -= 1;
+ item->item_bounding_box.corner.x += 1;
+ item->item_bounding_box.corner.y += 1;
+}
+
+
+
+/*
+ **********************************************************************************
+ *
+ * ToArea --
+ * Tell if the object is entirely outside (-1),
+ * entirely inside (1) or in between (0).
+ *
+ **********************************************************************************
+ */
+static int
+ToArea(Item item,
+ ZnBBox *area,
+ Tk_Uid tag_uid,
+ int enclosed,
+ ZnBool report)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+ ZnPoint *points;
+ int i, num_points, result=-1, result2;
+
+ if (tr->dev_points.num_strips == 0) {
+ return -1;
+ }
+
+ points = tr->dev_points.strips->points;
+ num_points = tr->dev_points.strips->num_points;
+
+ if (ISCLEAR(tr->flags, FAN_BIT)) {
+ result = PolygonInBBox(points, 3, area, NULL);
+ if (result == 0) {
+ return 0;
+ }
+ points++;
+ for (i = 0; i < num_points-3; i++, points++) {
+ result2 = PolygonInBBox(points, 3, area, NULL);
+ if (result2 != result) {
+ return 0;
+ }
+ }
+ }
+ else {
+ ZnPoint tri[3];
+
+ tri[0] = points[0];
+ tri[1] = points[1];
+ tri[2] = points[2];
+ result = PolygonInBBox(points, num_points, area, NULL);
+ if (result == 0) {
+ return 0;
+ }
+ points += 3;
+ for (i = 0; i < num_points-3; i++, points++) {
+ tri[1] = tri[2];
+ tri[2] = *points;
+ result2 = PolygonInBBox(points, num_points, area, NULL);
+ if (result2 != result) {
+ return 0;
+ }
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Draw --
+ *
+ **********************************************************************************
+ */
+static void
+Draw(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ TrianglesItem tr = (TrianglesItem) item;
+ int i, num_points, last_color_index;
+ ZnPoint *points;
+ ZnGradientColor *colors;
+
+ if (tr->dev_points.num_strips == 0) {
+ return;
+ }
+
+ points = tr->dev_points.strips->points;
+ num_points = tr->dev_points.strips->num_points;
+
+ colors = ZnListArray(tr->colors);
+ last_color_index = ZnListSize(tr->colors)-1;
+ XSetFillStyle(wi->dpy, wi->gc, FillSolid);
+
+ if (ISCLEAR(tr->flags, FAN_BIT)) {
+ XPoint *xpoints;
+ ZnListAssertSize(wi->work_xpts, num_points);
+ xpoints = ZnListArray(wi->work_xpts);
+ for (i = 0; i < num_points; i++) {
+ xpoints[i].x = REAL_TO_INT(points[i].x);
+ xpoints[i].y = REAL_TO_INT(points[i].y);
+ }
+ for (i = 0; i < num_points-2; i++, xpoints++) {
+ if (i <= last_color_index) {
+ XSetForeground(wi->dpy, wi->gc, ZnPixel(colors[i].shades[0]));
+ }
+ XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc,
+ xpoints, 3, Convex, CoordModeOrigin);
+ }
+ }
+ else {
+ XPoint tri[3];
+
+ tri[0].x = REAL_TO_INT(points[0].x);
+ tri[0].y = REAL_TO_INT(points[0].y);
+ tri[1].x = REAL_TO_INT(points[1].x);
+ tri[1].y = REAL_TO_INT(points[1].y);
+ tri[2].x = REAL_TO_INT(points[2].x);
+ tri[2].y = REAL_TO_INT(points[2].y);
+ points += 3;
+ for (i = 0; i < num_points-2; i++, points++) {
+ if (i <= last_color_index) {
+ XSetForeground(wi->dpy, wi->gc, ZnPixel(colors[i].shades[0]));
+ }
+ XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc,
+ tri, 3, Convex, CoordModeOrigin);
+ tri[1] = tri[2];
+ tri[2].x = REAL_TO_INT(points->x);
+ tri[2].y = REAL_TO_INT(points->y);
+ }
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Render --
+ *
+ **********************************************************************************
+ */
+static void
+Render(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ TrianglesItem tr = (TrianglesItem) item;
+ int i, num_points, last_color_index;
+ ZnPoint *points;
+ ZnGradientColor *colors;
+ int alpha;
+
+ if (tr->dev_points.num_strips == 0) {
+ return;
+ }
+
+ points = tr->dev_points.strips->points;
+ num_points = tr->dev_points.strips->num_points;
+
+ colors = ZnListArray(tr->colors);
+ last_color_index = ZnListSize(tr->colors)-1;
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ if (ISCLEAR(tr->flags, FAN_BIT)) {
+ glBegin(GL_TRIANGLE_STRIP);
+ }
+ else {
+ glBegin(GL_TRIANGLE_FAN);
+ }
+
+ for (i = 0; i < num_points; i++, points++) {
+ if (i <= last_color_index) {
+ alpha = (colors[i].alpha*wi->alpha/100)*65535/100;
+ glColor4us(colors[i].shades[0]->red, colors[i].shades[0]->green, colors[i].shades[0]->blue, alpha);
+ }
+ glVertex2f(points->x, points->y);
+ }
+ glEnd();
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * IsSensitive --
+ *
+ **********************************************************************************
+ */
+static ZnBool
+IsSensitive(Item item,
+ int item_part)
+{
+ return (ISSET(item->flags, SENSITIVE_BIT) &&
+ item->parent->class->IsSensitive(item->parent, ZN_NO_PART));
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Pick --
+ *
+ **********************************************************************************
+ */
+static double
+Pick(Item item,
+ ZnPoint *p,
+ Item start_item,
+ int aperture,
+ Item *a_item,
+ int *part)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+ double dist=1.0e40, new_dist;
+ ZnPoint *points;
+ int i, num_points;
+
+ if (tr->dev_points.num_strips == 0) {
+ return dist;
+ }
+
+ points = tr->dev_points.strips->points;
+ num_points = tr->dev_points.strips->num_points;
+
+ if (ISCLEAR(tr->flags, FAN_BIT)) {
+ for (i = 0; i < num_points-2; i++, points++) {
+ new_dist = PolygonToPointDist(points, 3, p);
+ if (new_dist <= 0.0) {
+ return 0.0;
+ }
+ if (new_dist < dist) {
+ dist = new_dist;
+ }
+ }
+ }
+ else {
+ ZnPoint tri[3];
+
+ tri[0] = points[0];
+ tri[1] = points[1];
+ tri[2] = points[2];
+ for (i = 0; i < num_points-2; i++, points++) {
+ new_dist = PolygonToPointDist(tri, 3, p);
+ if (new_dist <= 0.0) {
+ return 0.0;
+ }
+ if (new_dist < dist) {
+ dist = new_dist;
+ }
+ tri[1] = tri[2];
+ tri[2] = *points;
+ }
+ }
+
+ return dist;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * PostScript --
+ *
+ **********************************************************************************
+ */
+static void
+PostScript(Item item,
+ PostScriptInfo ps_info)
+{
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetClipVertices --
+ * Get the clipping shape.
+ * Never ever call TRI_FREE on the tristrip returned by GetClipVertices.
+ *
+ **********************************************************************************
+ */
+static ZnBool
+GetClipVertices(Item item,
+ ZnTriStrip *tristrip)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+
+ if (tr->dev_points.num_strips == 0) {
+ tristrip->num_strips = 0;
+ return True;
+ }
+
+ TRI_STRIP1(tristrip, tr->dev_points.strips->points, tr->dev_points.strips->num_points);
+ tristrip->fan = tr->dev_points.fan;
+ return False;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetContours --
+ * Get the external contour(s).
+ * Never ever call POLY_FREE on the poly returned by GetContours.
+ *
+ **********************************************************************************
+ */
+static ZnBool
+GetContours(Item item,
+ ZnPoly *poly)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+ WidgetInfo *wi = item->wi;
+ ZnPoint *points;
+ int i, j, num_points;
+
+ if (tr->dev_points.num_strips == 0) {
+ poly->num_contours = 0;
+ return True;
+ }
+
+ num_points = tr->dev_points.strips->num_points;
+
+ if (ISCLEAR(tr->flags, FAN_BIT)) {
+ ZnListAssertSize(wi->work_pts, num_points);
+ points = ZnListArray(wi->work_pts);
+
+ for (i = 1, j = 0; i < num_points; i += 2, j++) {
+ points[j] = tr->dev_points.strips->points[i];
+ }
+ i = num_points - 1;
+ if (num_points % 2 == 0) {
+ i--;
+ }
+ for ( ; i >= 0; i -= 2, j++) {
+ points[j] = tr->dev_points.strips->points[i];
+ }
+ POLY_CONTOUR1(poly, points, num_points);
+ }
+ else {
+ POLY_CONTOUR1(poly, tr->dev_points.strips->points, num_points);
+ }
+
+ return False;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Coords --
+ * Return or edit the item vertices.
+ *
+ **********************************************************************************
+ */
+static int
+Coords(Item item,
+ int contour,
+ int index,
+ int cmd,
+ ZnPoint **pts,
+ int *num_pts)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+ int num_points, i;
+ ZnPoint *points;
+
+ 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 beziers", NULL);
+ return ZN_ERROR;
+ }
+ if (cmd == COORDS_REPLACE_ALL) {
+ ZnList tmp;
+ replace_all:
+ tmp = ZnListFromArray(*pts, *num_pts, sizeof(ZnPoint));
+ if (!tr->points) {
+ ZnListEmpty(tr->points);
+ }
+ else {
+ tr->points = ZnListNew(*num_pts, sizeof(ZnPoint));
+ }
+ ZnListAppend(tr->points, tmp);
+ ZnListFree(tmp);
+ }
+ else {
+ if (!tr->points) {
+ edit_err:
+ Tcl_AppendResult(item->wi->interp,
+ " coords command cannot edit empty beziers", NULL);
+ return ZN_ERROR;
+ }
+ points = ZnListArray(tr->points);
+ num_points = ZnListSize(tr->points);
+ if (index < 0) {
+ index += num_points;
+ }
+ if ((index < 0) || (index >= num_points)) {
+ range_err:
+ Tcl_AppendResult(item->wi->interp, " coord index out of range", NULL);
+ return ZN_ERROR;
+ }
+ points[index] = (*pts)[0];
+ }
+ ITEM.Invalidate(item, ZN_COORDS_FLAG);
+ }
+ else if ((cmd == COORDS_READ) || (cmd == COORDS_READ_ALL)) {
+ if (!tr->points) {
+ *num_pts = 0;
+ *pts = NULL;
+ return ZN_OK;
+ }
+ points = ZnListArray(tr->points);
+ num_points = ZnListSize(tr->points);
+ if (cmd == COORDS_READ_ALL) {
+ *num_pts = num_points;
+ *pts = points;
+ }
+ else {
+ if (index < 0) {
+ index += num_points;
+ }
+ if ((index < 0) || (index >= num_points)) {
+ goto range_err;
+ }
+ *num_pts = 1;
+ *pts = &points[index];
+ }
+ }
+ else if ((cmd == COORDS_ADD) || (cmd == COORDS_ADD_LAST)) {
+ if (!tr->points) {
+ goto replace_all;
+ }
+ else if (cmd == COORDS_ADD) {
+ num_points = ZnListSize(tr->points);
+ if (index < 0) {
+ index += num_points;
+ }
+ if ((index < 0) || (index >= num_points)) {
+ goto range_err;
+ }
+ for (i = 0; i < *num_pts; i++, index++) {
+ ZnListAdd(tr->points, &(*pts)[i], index);
+ }
+ }
+ else {
+ ZnList tmp;
+ tmp = ZnListFromArray(*pts, *num_pts, sizeof(ZnPoint));
+ ZnListAppend(tr->points, tmp);
+ ZnListFree(tmp);
+ }
+ ITEM.Invalidate(item, ZN_COORDS_FLAG);
+ }
+ else if (cmd == COORDS_REMOVE) {
+ if (!tr->points) {
+ goto edit_err;
+ }
+ points = ZnListArray(tr->points);
+ num_points = ZnListSize(tr->points);
+ if (index < 0) {
+ index += num_points;
+ }
+ if ((index < 0) || (index >= num_points)) {
+ goto range_err;
+ }
+ ZnListDelete(tr->points, index);
+ ITEM.Invalidate(item, ZN_COORDS_FLAG);
+ }
+
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * PickVertex --
+ * Return in 'vertex' the vertex closest to p and in 'o_vertex' the
+ * opposite vertex on the closest edge, if such an edge exists or -1
+ * in the other case.
+ *
+ **********************************************************************************
+ */
+static void
+PickVertex(Item item,
+ ZnPoint *p,
+ int *contour,
+ int *vertex,
+ int *o_vertex)
+{
+ TrianglesItem tr = (TrianglesItem) item;
+ int i, k, num_points;
+ ZnPoint *points;
+ ZnReal dist=1.0e40, new_dist, dist2;
+
+ *contour = *vertex = *o_vertex = -1;
+
+ points = tr->dev_points.strips->points;
+ num_points = tr->dev_points.strips->num_points;
+ for (i = 0; i < num_points; i++) {
+ new_dist = hypot(points[i].x - p->x, points[i].y - p->y);
+ if (new_dist < dist) {
+ dist = new_dist;
+ *contour = 0;
+ *vertex = i;
+ }
+ }
+ /*
+ * Update the opposite vertex.
+ */
+ i = (*vertex+1) % num_points;
+ new_dist = LineToPointDist(&points[*vertex], &points[i], p);
+ k = ((unsigned)(*vertex-1)) % num_points;
+ dist2 = LineToPointDist(&points[*vertex], &points[k], p);
+ if (dist2 < new_dist) {
+ *o_vertex = k;
+ }
+ else {
+ *o_vertex = i;
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Exported functions struct --
+ *
+ **********************************************************************************
+ */
+static ItemClassStruct TRIANGLES_ITEM_CLASS = {
+ sizeof(TrianglesItemStruct),
+ False, /* has_fields */
+ 0, /* num_parts */
+ False, /* has_anchors */
+ "triangles",
+ tr_attrs,
+ Init,
+ Clone,
+ Destroy,
+ Configure,
+ Query,
+ NULL,
+ NULL,
+ GetClipVertices,
+ GetContours,
+ Coords,
+ NULL, /* InsertChars */
+ NULL, /* DeleteChars */
+ NULL, /* Cursor */
+ NULL, /* Index */
+ NULL, /* Part */
+ NULL, /* Selection */
+ NULL, /* Contour */
+ ComputeCoordinates,
+ ToArea,
+ Draw,
+ Render,
+ IsSensitive,
+ Pick,
+ PickVertex, /* PickVertex */
+ PostScript
+};
+
+ZnItemClassId ZnTriangles = (ZnItemClassId) &TRIANGLES_ITEM_CLASS;
diff --git a/sandbox/local.pl b/sandbox/local.pl
index cabd58b..14a8914 100644
--- a/sandbox/local.pl
+++ b/sandbox/local.pl
@@ -13,17 +13,19 @@ $penguin = $mw->Photo(-format => 'png',
-file => "xpenguin.png");
$top = 1;
-$zinc = $mw->Zinc(-render => 0,
- -borderwidth => 5,
- -highlightthickness => 5,
+$zinc = $mw->Zinc(-render => 1,
+ -borderwidth => 0,
+ -highlightthickness => 0,
-relief => 'sunken',
-takefocus => 1,
- -tile => $papier);
+# -tile => $papier
+ );
$zinc->pack(-expand => 1, -fill => 'both');
$zinc->configure(-width => 500, -height => 500);
$gr1 = $zinc->add('group', $top);
#$clip = $zinc->add('rectangle', $gr1, [50, 50, 399, 399],
$clip = $zinc->add('arc', $gr1, [50, 50, 399, 399],
+ -visible => 1,
-filled => 1,
-fillcolor => 'Pink:40',
# -fillpattern => 'AlphaStipple4',
@@ -31,11 +33,15 @@ $clip = $zinc->add('arc', $gr1, [50, 50, 399, 399],
#$zinc->itemconfigure($gr1, -clip => $clip);
$gr2 = $zinc->add('group', $gr1);
$clip2 = $zinc->add('rectangle', $gr2, [200, 200, 450, 300],
+ -visible => 1,
-filled => 1,
+ -fillcolor => '#70C5C0:15',
# -fillcolor => 'white:100|white:0',
- -fillcolor => 'white:100 0|black:100 100(260 230',
+# -fillcolor => '#ffffff:15 0|#ffff00:15 50|#000000:15 100/270',
# -fillcolor => 'white 0 |blue 20|blue 80|black:0 100/270',
- -linewidth => 0);
+ -linewidth => 9,
+ -linestyle => 'dashed',
+ -linecolor => 'red');
#$zinc->itemconfigure($gr2, -clip => $clip2);
$view = $zinc->add('group', $gr2, -tags => "controls");
$zinc->lower($clip);
@@ -80,22 +86,36 @@ $mp = $zinc->add('curve', $view, [50, 150, 100, 250, 270, 170,
-markercolor => 'red');
#$zinc->itemconfigure($gr1, -clip => $mp);
-$mp2 = $zinc->add('curve', $view, [100, 450, 200, 450],
- -linewidth => 10,
+$mp2 = $zinc->add('curve', $view, [0, 320, 80, 470, 200, 470],
+ -visible => 1,
+ -linewidth => 20,
-closed => 0,
-joinstyle => 'round',
- -linecolor => 'tan',
+ -capstyle => 'round',
+ -linestyle => 'mixed',
+ -linecolor => 'red',
-linealpha => 50,
- -filled => 1,
+ -filled => 0,
# -fillcolor => 'white|black(10 10',
-fillcolor => 'wheat',
# -fillpattern => 'AlphaStipple8',
# -tile => $papier,
-marker => '',
-markercolor => 'red');
+$mp3 = $zinc->add('curve', $view, [20, 280, 100, 430, 200, 430],
+ -linewidth => 9,
+ -closed => 0,
+# -linestyle => 'dashed',
+ -joinstyle => 'round',
+ -firstend => [3, 12, 8],
+ -lastend => [12, 12, 8],
+ -capstyle => 'round',
+ -linecolor => 'red',
+ -filled => 1,
+ -linealpha => 100);
$zinc->add('reticle', $view,
- -visible => 0,
+ -visible => 1,
-position => [300, 300],
-firstradius => 60,
-stepsize => 30,
@@ -111,17 +131,19 @@ for ($i = 0; $i < 100; $i++) {
$x = $x+5;
$y = $y+7;
$zinc->add('text', $view,
- -visible => 0,
+ -visible => 1,
-text => "BlaBla et tout et tout, bref...",
-position => [$x, $y], -anchor => 'nw',
-color => 'red', -alpha => 30);
}
$peng = $zinc->add('icon', $view,
+ -visible => 1,
-image => $penguin, -position => [300, 300],
-anchor => 'center',
-alpha => 50);
$fvwm = $zinc->add('icon', $top,
+ -visible => 1,
-mask => '@fvwm.xbm',
-position => [50, 20],
-anchor => 'center',
@@ -129,7 +151,7 @@ $fvwm = $zinc->add('icon', $top,
-alpha => 100);
#$zinc->gname('white 0 80|black[0 0', 'cone');
-$zinc->gname('white:50 0 80|black 30|white 100(0 0', 'oeil');
+$zinc->gname('white:50 0 80|black 50|white 100(0 0', 'oeil');
$zinc->gname('white:100|black:100(-20 -15', 'boule');
$zinc->gname('white:100|black:100(-15 -100', 'arrondi');
$zinc->gname('white:100|black:100/45', 'cyl');
@@ -137,18 +159,21 @@ $arc = $zinc->add('arc', $view, [-45, -45, 45, 45],
-visible => 1,
-fillcolor => 'boule',
-linewidth => 1,
- -filled => 1,
+# -filled => 1,
-startangle => 0,
-# -extent => 240,
- -closed => 1,
+ -extent => 240,
+ -closed => 0,
+ -firstend => [12, 12, 8],
+ -lastend => [12, 12, 8],
# -tile => $logo,
-pieslice => 0
);
+
$zinc->add('rectangle', $view, [100, 100, 200, 200],
-fillcolor => 'cyl',
-linewidth => 1,
-filled => 1,
- -visible => 0
+ -visible => 1
);
$zinc->translate($arc, 125, 300);