From d3df91149969d09b3a805a6468d85efcab77cc75 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Fri, 25 Jan 2002 10:04:54 +0000 Subject: Nouvel item permettant d'afficher une liste de triangles --- Makefile.in | 3 + debian/rules | 3 +- debian/zinc-perl.files | 3 +- generic/Triangles.c | 877 +++++++++++++++++++++++++++++++++++++++++++++++++ sandbox/local.pl | 59 +++- 5 files changed, 926 insertions(+), 19 deletions(-) create mode 100644 generic/Triangles.c 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 +#include + + +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); -- cgit v1.1