head	1.28;
access;
symbols
	core-8-5-9:1.18
	core-8-5-8:1.18
	macosx-cocoa-merge:1.24
	macosx-cocoa-premerge:1.24
	macosx-carbon-freeze:1.24
	core-8-5-7:1.18
	core-8-5-6:1.18
	core-8-6-b1:1.23
	core-8-6-a3:1.19
	core-8-5-5:1.18
	core-8-6-a2:1.19
	core-8-5-4:1.18
	core-8-5-3:1.18
	core-8-6-a1:1.19
	core-8-4-19:1.10.2.3
	core-8-5-branch:1.18.0.2
	core-8-5-2:1.18
	core-8-4-18:1.10.2.3
	core-8-5-1:1.18
	core-8-4-17:1.10.2.3
	core-8-5-0:1.18
	core-8-5-b3:1.17
	core-8-5-b2:1.17
	core-8-4-16:1.10.2.3
	core-8-5-b1:1.17
	core-stablilizer-merge:1.16
	core-stabilizer-branch:1.16.0.2
	core-stabilizer-merge:1.18
	core-8-4-15:1.10.2.3
	core-8-5-a6:1.16
	core-8-5-a5:1.16
	core-8-4-14:1.10.2.3
	core-8-5-a4:1.15
	core-8-4-13:1.10.2.2
	core-8-4-12:1.10.2.2
	core-8-4-11:1.10.2.1
	core-8-5-a3:1.12
	core-8-4-10:1.10.2.1
	core-8-4-9-branch:1.10.2.1.0.2
	core-8-5-a2:1.12
	core-8-4-9:1.10.2.1
	core-8-4-8:1.10.2.1
	core-8-4-7:1.10.2.1
	core-8-5-a1:1.12
	core-8-4-6:1.10.2.1
	core-8-4-5:1.10.2.1
	mistachkin-dev-branch:1.11.0.2
	core-8-4-4:1.10.2.1
	core-8-4-3:1.10.2.1
	core-8-4-branch:1.10.0.2
	core-8-4-2:1.10
	core-8-4-1:1.9
	core-8-3-5:1.5.2.2
	core-8-4-0:1.9
	macosx-8-4-merge-2002-08-31-trunk:1.9
	macosx-8-4-premerge-2002-08-31-branch:1.8.2.1
	macosx-8-4-premerge-2002-08-31-trunk:1.9
	macosx-8-4-merge-2002-08-30-branch:1.8.2.1
	macosx-8-4-merge-2002-08-30-trunk:1.9
	macosx-8-4-merge-2002-08-20-branch:1.8.2.1
	macosx-8-4-merge-2002-08-20-trunk:1.9
	core-8-4-b2:1.9
	core-8-4-b1:1.8
	macosx-premerge-6-9-02:1.8
	core-8-4-a4:1.8
	core-8-3-4:1.5.2.2
	macosx-8-4-branch:1.8.0.2
	macosx-8-4-branchpoint:1.8
	core-8-4-a3:1.8
	core-8-3-3:1.5.2.1
	dgp-privates-into-namespace:1.6.0.4
	tclpro-1-5-0:1.5.2.1
	core-8-4-win-speedup:1.6.0.2
	core-8-4-a2:1.6
	tclpro-1-4-1:1.5.2.1
	tclpro-1-4-0:1.5.2.1
	core-8-3-2:1.5.2.1
	ajuba-ajuba2-2-1-base:1.5
	ajuba-ajuba2-2-0:1.5
	core-8-4-a1:1.6
	core-8-3-1-branch:1.5.0.2
	core-8-3-1:1.5
	scriptics-sc-2-0-b5:1.5
	scriptics-sc-2-0-fixed:1.5
	scriptics-sc-2-0-b2:1.5
	scriptics-sc-2-0-b1:1.5
	core-8-3-0:1.5
	core-8-3-b2:1.4
	core-8-3-b1:1.4
	scriptics-sc-1-1:1.3
	scriptics-sc-1-1-b1:1.3
	core-8-2-3:1.3
	scriptics-sc-1-1-branch:1.3.0.10
	scriptics-sc-1-1-base:1.3
	scriptics-sc-1-0:1.3
	scriptics-sc-1-0-branch:1.3.0.8
	scriptics-sc-1-0-base:1.3
	core-8-2-2:1.3
	core-8-2-1:1.3
	scriptics-bc-1-0-b1:1.3
	core-8-2-1-branch:1.3.0.6
	scriptics-tclpro-1-3-0:1.3
	core-8-2-0:1.3
	core-8-2-b3-branch:1.3.0.4
	core-8-2-b3-base:1.3
	scriptics-tclpro-1-3-b4:1.3
	core-8-2-b2:1.3
	scriptics-tclpro-1-3-b3:1.3
	core-8-2-b1:1.3
	scriptics-tclpro-1-3-b2:1.3
	merge-to-mainline-5/21/99:1.3
	scriptics-tclpro-1-3-b2-branch:1.3.0.2
	core-8-1-1:1.3
	scriptics-tclpro-1-3-b1:1.3
	core-8-1-1-base:1.3
	core-8-1-0:1.3
	merge-to-mainline-4-29-99:1.3
	merge-to-mainline-4-23-99:1.3
	core-8-1-branch-old:1.1.0.4
	core-8-0-6-branch:1.2.0.6
	core-8-0-6-base:1.2
	core-8-0-5:1.2
	core-8-1-b3:1.1.4.2
	core-8-1-b2:1.1.4.2
	dev-8-1-stubs-branch:1.1.4.2.0.2
	dev-stubs-branch:1.2.0.4
	scriptics-tclpro-1-2:1.2
	scriptics-tclpro-1-2-b2:1.2
	core-8-1-merge-2/10/99:1.2
	core-8-0-5-branch:1.2.0.2
	core-8-0-5-base:1.2
	scriptics-tclpro-1-2-b1:1.2
	scriptics-tclpro-1-2-a1:1.2
	core-8-1-b1:1.1.4.2
	core-8-0-4:1.2
	core-8-1-a2:1.1.4.1
	core-8-0-2:1.1
	core-8-0-3:1.2;
locks; strict;
comment	@ * @;


1.28
date	2010.11.19.14.48.00;	author nijtmans;	state Exp;
branches;
next	1.27;

1.27
date	2010.06.15.11.16.03;	author nijtmans;	state Exp;
branches;
next	1.26;

1.26
date	2010.02.17.19.21.16;	author nijtmans;	state Exp;
branches;
next	1.25;

1.25
date	2010.01.18.20.43.38;	author nijtmans;	state Exp;
branches;
next	1.24;

1.24
date	2009.01.06.21.58.15;	author nijtmans;	state Exp;
branches;
next	1.23;

1.23
date	2008.11.09.21.53.39;	author nijtmans;	state Exp;
branches;
next	1.22;

1.22
date	2008.11.09.20.51.28;	author nijtmans;	state Exp;
branches;
next	1.21;

1.21
date	2008.11.01.16.14.30;	author dkf;	state Exp;
branches;
next	1.20;

1.20
date	2008.10.30.23.18.59;	author nijtmans;	state Exp;
branches;
next	1.19;

1.19
date	2008.04.27.22.38.55;	author dkf;	state Exp;
branches;
next	1.18;

1.18
date	2007.12.13.15.24.13;	author dgp;	state Exp;
branches;
next	1.17;

1.17
date	2007.09.07.00.34.51;	author dgp;	state Exp;
branches;
next	1.16;

1.16
date	2006.10.16.15.35.28;	author das;	state Exp;
branches
	1.16.2.1;
next	1.15;

1.15
date	2005.11.17.10.57.35;	author dkf;	state Exp;
branches;
next	1.14;

1.14
date	2005.11.04.15.23.05;	author dkf;	state Exp;
branches;
next	1.13;

1.13
date	2005.08.10.22.02.22;	author dkf;	state Exp;
branches;
next	1.12;

1.12
date	2004.01.13.02.06.00;	author davygrvy;	state Exp;
branches;
next	1.11;

1.11
date	2003.05.11.00.52.41;	author hobbs;	state Exp;
branches;
next	1.10;

1.10
date	2003.02.09.07.48.22;	author hobbs;	state Exp;
branches
	1.10.2.1;
next	1.9;

1.9
date	2002.08.05.04.30.38;	author dgp;	state Exp;
branches;
next	1.8;

1.8
date	2001.07.04.00.40.11;	author hobbs;	state Exp;
branches
	1.8.2.1;
next	1.7;

1.7
date	2001.07.03.06.03.44;	author hobbs;	state Exp;
branches;
next	1.6;

1.6
date	2000.06.03.08.38.12;	author hobbs;	state Exp;
branches
	1.6.2.1
	1.6.4.1;
next	1.5;

1.5
date	2000.02.01.11.41.09;	author hobbs;	state Exp;
branches
	1.5.2.1;
next	1.4;

1.4
date	99.12.14.06.52.26;	author hobbs;	state Exp;
branches;
next	1.3;

1.3
date	99.04.16.01.51.11;	author stanton;	state Exp;
branches;
next	1.2;

1.2
date	98.09.14.18.23.05;	author stanton;	state Exp;
branches;
next	1.1;

1.1
date	98.04.01.09.51.52;	author rjohnson;	state Exp;
branches
	1.1.4.1;
next	;

1.1.4.1
date	98.09.29.00.25.13;	author stanton;	state Exp;
branches;
next	1.1.4.2;

1.1.4.2
date	98.09.30.02.16.44;	author stanton;	state Exp;
branches;
next	;

1.5.2.1
date	2000.08.05.23.53.11;	author hobbs;	state Exp;
branches;
next	1.5.2.2;

1.5.2.2
date	2001.08.24.23.59.11;	author hobbs;	state Exp;
branches;
next	;

1.6.2.1
date	2002.04.02.21.00.46;	author hobbs;	state Exp;
branches;
next	;

1.6.4.1
date	2001.07.03.20.01.07;	author dgp;	state Exp;
branches;
next	1.6.4.2;

1.6.4.2
date	2001.07.18.16.15.27;	author dgp;	state Exp;
branches;
next	1.6.4.3;

1.6.4.3
date	2001.07.18.16.16.53;	author dgp;	state Exp;
branches;
next	;

1.8.2.1
date	2002.08.20.20.27.01;	author das;	state Exp;
branches;
next	;

1.10.2.1
date	2003.05.11.00.57.09;	author hobbs;	state Exp;
branches;
next	1.10.2.2;

1.10.2.2
date	2005.08.11.12.17.09;	author dkf;	state Exp;
branches;
next	1.10.2.3;

1.10.2.3
date	2006.10.16.15.35.50;	author das;	state Exp;
branches;
next	;

1.16.2.1
date	2007.09.07.01.25.34;	author dgp;	state Exp;
branches;
next	;


desc
@@


1.28
log
@Revise Tcl_Panic() calls ending with a newline removing the newline, because Tcl_Panic() outputs a final newline already
@
text
@/*
 * tkCanvPoly.c --
 *
 *	This file implements polygon items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 Ajuba Solutions.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.27 2010/06/15 11:16:03 nijtmans Exp $
 */

#include "tkInt.h"
#include "tkCanvas.h"

/*
 * The structure below defines the record for each polygon item.
 */

typedef struct PolygonItem  {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_Outline outline;		/* Outline structure */
    int numPoints;		/* Number of points in polygon. Polygon is
				 * always closed. */
    int pointsAllocated;	/* Number of points for which space is
				 * allocated at *coordPtr. */
    double *coordPtr;		/* Pointer to malloc-ed array containing x-
				 * and y-coords of all points in polygon.
				 * X-coords are even-valued indices, y-coords
				 * are corresponding odd-valued indices. */
    int joinStyle;		/* Join style for outline */
    Tk_TSOffset tsoffset;
    XColor *fillColor;		/* Foreground color for polygon. */
    XColor *activeFillColor;	/* Foreground color for polygon if state is
				 * active. */
    XColor *disabledFillColor;	/* Foreground color for polygon if state is
				 * disabled. */
    Pixmap fillStipple;		/* Stipple bitmap for filling polygon. */
    Pixmap activeFillStipple;	/* Stipple bitmap for filling polygon if state
				 * is active. */
    Pixmap disabledFillStipple;	/* Stipple bitmap for filling polygon if state
				 * is disabled. */
    GC fillGC;			/* Graphics context for filling polygon. */
    const Tk_SmoothMethod *smooth; /* Non-zero means draw shape smoothed (i.e.
				 * with Bezier splines). */
    int splineSteps;		/* Number of steps in each spline segment. */
    int autoClosed;		/* Zero means the given polygon was closed,
				   one means that we auto closed it. */
} PolygonItem;

/*
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", Tk_Offset(PolygonItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(PolygonItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(PolygonItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	"black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(PolygonItem, tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(PolygonItem, outline.tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", Tk_Offset(PolygonItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", Tk_Offset(PolygonItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputePolygonBbox(Tk_Canvas canvas,
			    PolygonItem *polyPtr);
static int		ConfigurePolygon(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreatePolygon(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeletePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr,  Display *display);
static void		DisplayPolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetPolygonIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, int *indexPtr);
static int		PolygonCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		PolygonDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int first, int last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj);
static int		PolygonToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		PolygonToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		PolygonToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ScalePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslatePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
 * The structures below defines the polygon item type by means of functions
 * that can be invoked by generic item code.
 */

Tk_ItemType tkPolygonType = {
    "polygon",				/* name */
    sizeof(PolygonItem),		/* itemSize */
    CreatePolygon,			/* createProc */
    configSpecs,			/* configSpecs */
    ConfigurePolygon,			/* configureProc */
    PolygonCoords,			/* coordProc */
    DeletePolygon,			/* deleteProc */
    DisplayPolygon,			/* displayProc */
    TK_CONFIG_OBJS | TK_MOVABLE_POINTS,	/* flags */
    PolygonToPoint,			/* pointProc */
    PolygonToArea,			/* areaProc */
    PolygonToPostscript,		/* postscriptProc */
    ScalePolygon,			/* scaleProc */
    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    PolygonInsert,		/* insertProc */
    PolygonDeleteCoords,		/* dTextProc */
    NULL,				/* nextPtr */
    NULL, 0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */

#define MAX_STATIC_POINTS 200

/*
 *--------------------------------------------------------------
 *
 * CreatePolygon --
 *
 *	This function is invoked to create a new polygon item in a canvas.
 *
 * Results:
 *	A standard Tcl return value. If an error occurred in creating the
 *	item, then an error message is left in the interp's result; in this
 *	case itemPtr is left uninitialized, so it can be safely freed by the
 *	caller.
 *
 * Side effects:
 *	A new polygon item is created.
 *
 *--------------------------------------------------------------
 */

static int
CreatePolygon(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing polygon. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
     * errors during the the remainder of this function.
     */

    Tk_CreateOutline(&polyPtr->outline);
    polyPtr->numPoints = 0;
    polyPtr->pointsAllocated = 0;
    polyPtr->coordPtr = NULL;
    polyPtr->joinStyle = JoinRound;
    polyPtr->tsoffset.flags = 0;
    polyPtr->tsoffset.xoffset = 0;
    polyPtr->tsoffset.yoffset = 0;
    polyPtr->fillColor = NULL;
    polyPtr->activeFillColor = NULL;
    polyPtr->disabledFillColor = NULL;
    polyPtr->fillStipple = None;
    polyPtr->activeFillStipple = None;
    polyPtr->disabledFillStipple = None;
    polyPtr->fillGC = None;
    polyPtr->smooth = NULL;
    polyPtr->splineSteps = 12;
    polyPtr->autoClosed = 0;

    /*
     * Count the number of points and then parse them into a point array.
     * Leading arguments are assumed to be points if they start with a digit
     * or a minus sign followed by a digit.
     */

    for (i = 0; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);

	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    break;
	}
    }
    if (i && PolygonCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
    }

    if (ConfigurePolygon(interp, canvas, itemPtr, objc-i, objv+i, 0)
	    == TCL_OK) {
	return TCL_OK;
    }

  error:
    DeletePolygon(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * PolygonCoords --
 *
 *	This function is invoked to process the "coords" widget command on
 *	polygons. See the user documentation for details on what it does.
 *
 * Results:
 *	Returns TCL_OK or TCL_ERROR, and sets the interp's result.
 *
 * Side effects:
 *	The coordinates for the given item may be changed.
 *
 *--------------------------------------------------------------
 */

static int
PolygonCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int i, numPoints;

    if (objc == 0) {
	/*
	 * Print the coords used to create the polygon. If we auto closed the
	 * polygon then we don't report the last point.
	 */

	Tcl_Obj *subobj, *obj = Tcl_NewObj();

	for (i = 0; i < 2*(polyPtr->numPoints - polyPtr->autoClosed); i++) {
	    subobj = Tcl_NewDoubleObj(polyPtr->coordPtr[i]);
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	}
	Tcl_SetObjResult(interp, obj);
	return TCL_OK;
    }
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %d",
		objc));
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (polyPtr->pointsAllocated <= numPoints) {
	if (polyPtr->coordPtr != NULL) {
	    ckfree((char *) polyPtr->coordPtr);
	}

	/*
	 * One extra point gets allocated here, because we always add
	 * another point to close the polygon.
	 */

	polyPtr->coordPtr = (double *)
		ckalloc(sizeof(double) * (unsigned)(objc+2));
	polyPtr->pointsAllocated = numPoints+1;
    }
    for (i = objc-1; i >= 0; i--) {
	if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
		&polyPtr->coordPtr[i]) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    polyPtr->numPoints = numPoints;
    polyPtr->autoClosed = 0;

    /*
     * Close the polygon if it isn't already closed.
     */

    if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0])
	    || (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) {
	polyPtr->autoClosed = 1;
	polyPtr->numPoints++;
	polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
    }

    ComputePolygonBbox(canvas, polyPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ConfigurePolygon --
 *
 *	This function is invoked to configure various aspects of a polygon
 *	item such as its background color.
 *
 * Results:
 *	A standard Tcl result code. If an error occurs, then an error message
 *	is left in the interp's result.
 *
 * Side effects:
 *	Configuration information, such as colors and stipple patterns, may be
 *	set for itemPtr.
 *
 *--------------------------------------------------------------
 */

static int
ConfigurePolygon(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Polygon item to reconfigure. */
    int objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */

    state = itemPtr->state;

    if (polyPtr->outline.activeWidth > polyPtr->outline.width ||
	    polyPtr->outline.activeDash.number != 0 ||
	    polyPtr->outline.activeColor != NULL ||
	    polyPtr->outline.activeStipple != None ||
	    polyPtr->activeFillColor != NULL ||
	    polyPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (state == TK_STATE_HIDDEN) {
	ComputePolygonBbox(canvas, polyPtr);
	return TCL_OK;
    }

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &polyPtr->outline);
    if (mask) {
	gcValues.cap_style = CapRound;
	gcValues.join_style = polyPtr->joinStyle;
	mask |= GCCapStyle|GCJoinStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = None;
    }
    if (polyPtr->outline.gc != None) {
	Tk_FreeGC(Tk_Display(tkwin), polyPtr->outline.gc);
    }
    polyPtr->outline.gc = newGC;

    color = polyPtr->fillColor;
    stipple = polyPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->activeFillColor != NULL) {
	    color = polyPtr->activeFillColor;
	}
	if (polyPtr->activeFillStipple != None) {
	    stipple = polyPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->disabledFillColor != NULL) {
	    color = polyPtr->disabledFillColor;
	}
	if (polyPtr->disabledFillStipple != None) {
	    stipple = polyPtr->disabledFillStipple;
	}
    }

    if (color == NULL) {
	newGC = None;
    } else {
	gcValues.foreground = color->pixel;
	mask = GCForeground;
	if (stipple != None) {
	    gcValues.stipple = stipple;
	    gcValues.fill_style = FillStippled;
	    mask |= GCStipple|GCFillStyle;
	}
#ifdef MAC_OSX_TK
	/*
	 * Mac OS X CG drawing needs access to the outline linewidth
	 * even for fills (as linewidth controls antialiasing).
	 */
	gcValues.line_width = polyPtr->outline.gc != None ?
		polyPtr->outline.gc->line_width : 0;
	mask |= GCLineWidth;
#endif
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    }
    if (polyPtr->fillGC != None) {
	Tk_FreeGC(Tk_Display(tkwin), polyPtr->fillGC);
    }
    polyPtr->fillGC = newGC;

    /*
     * Keep spline parameters within reasonable limits.
     */

    if (polyPtr->splineSteps < 1) {
	polyPtr->splineSteps = 1;
    } else if (polyPtr->splineSteps > 100) {
	polyPtr->splineSteps = 100;
    }

    ComputePolygonBbox(canvas, polyPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * DeletePolygon --
 *
 *	This function is called to clean up the data structure associated with
 *	a polygon item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeletePolygon(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;

    Tk_DeleteOutline(display, &polyPtr->outline);
    if (polyPtr->coordPtr != NULL) {
	ckfree((char *) polyPtr->coordPtr);
    }
    if (polyPtr->fillColor != NULL) {
	Tk_FreeColor(polyPtr->fillColor);
    }
    if (polyPtr->activeFillColor != NULL) {
	Tk_FreeColor(polyPtr->activeFillColor);
    }
    if (polyPtr->disabledFillColor != NULL) {
	Tk_FreeColor(polyPtr->disabledFillColor);
    }
    if (polyPtr->fillStipple != None) {
	Tk_FreeBitmap(display, polyPtr->fillStipple);
    }
    if (polyPtr->activeFillStipple != None) {
	Tk_FreeBitmap(display, polyPtr->activeFillStipple);
    }
    if (polyPtr->disabledFillStipple != None) {
	Tk_FreeBitmap(display, polyPtr->disabledFillStipple);
    }
    if (polyPtr->fillGC != None) {
	Tk_FreeGC(display, polyPtr->fillGC);
    }
}

/*
 *--------------------------------------------------------------
 *
 * ComputePolygonBbox --
 *
 *	This function is invoked to compute the bounding box of all the pixels
 *	that may be drawn as part of a polygon.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

static void
ComputePolygonBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    PolygonItem *polyPtr)	/* Item whose bbox is to be recomputed. */
{
    double *coordPtr;
    int i;
    double width;
    Tk_State state = polyPtr->header.state;
    Tk_TSOffset *tsoffset;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    if (polyPtr->coordPtr == NULL || (polyPtr->numPoints < 1)
	    || (state == TK_STATE_HIDDEN)) {
	polyPtr->header.x1 = polyPtr->header.x2 =
		polyPtr->header.y1 = polyPtr->header.y2 = -1;
	return;
    }
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *) polyPtr) {
	if (polyPtr->outline.activeWidth > width) {
	    width = polyPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    width = polyPtr->outline.disabledWidth;
	}
    }

    coordPtr = polyPtr->coordPtr;
    polyPtr->header.x1 = polyPtr->header.x2 = (int) *coordPtr;
    polyPtr->header.y1 = polyPtr->header.y2 = (int) coordPtr[1];

    /*
     * Compute the bounding box of all the points in the polygon, then expand
     * in all directions by the outline's width to take care of butting or
     * rounded corners and projecting or rounded caps. This expansion is an
     * overestimate (worst-case is square root of two over two) but it's
     * simple. Don't do anything special for curves. This causes an additional
     * overestimate in the bounding box, but is faster.
     */

    for (i = 1, coordPtr = polyPtr->coordPtr+2; i < polyPtr->numPoints-1;
	    i++, coordPtr += 2) {
	TkIncludePoint((Tk_Item *) polyPtr, coordPtr);
    }

    tsoffset = &polyPtr->tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	int index = tsoffset->flags & ~TK_OFFSET_INDEX;

	if (tsoffset->flags == INT_MAX) {
	    index = (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	    if (index < 0) {
		index = 0;
	    }
	}
	index %= (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	if (index < 0) {
	    index += (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	}
 	tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
	tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {
	    tsoffset->xoffset = polyPtr->header.x1;
	} else if (tsoffset->flags & TK_OFFSET_CENTER) {
	    tsoffset->xoffset = (polyPtr->header.x1 + polyPtr->header.x2)/2;
	} else if (tsoffset->flags & TK_OFFSET_RIGHT) {
	    tsoffset->xoffset = polyPtr->header.x2;
	}
	if (tsoffset->flags & TK_OFFSET_TOP) {
	    tsoffset->yoffset = polyPtr->header.y1;
	} else if (tsoffset->flags & TK_OFFSET_MIDDLE) {
	    tsoffset->yoffset = (polyPtr->header.y1 + polyPtr->header.y2)/2;
	} else if (tsoffset->flags & TK_OFFSET_BOTTOM) {
	    tsoffset->yoffset = polyPtr->header.y2;
	}
    }

    if (polyPtr->outline.gc != None) {
	tsoffset = &polyPtr->outline.tsoffset;
	if (tsoffset) {
	    if (tsoffset->flags & TK_OFFSET_INDEX) {
		int index = tsoffset->flags & ~TK_OFFSET_INDEX;

		if (tsoffset->flags == INT_MAX) {
		    index = (polyPtr->numPoints - 1) * 2;
		}
		index %= (polyPtr->numPoints - 1) * 2;
		if (index < 0) {
		    index += (polyPtr->numPoints - 1) * 2;
		}
		tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
		tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
	    } else {
		if (tsoffset->flags & TK_OFFSET_LEFT) {
		    tsoffset->xoffset = polyPtr->header.x1;
		} else if (tsoffset->flags & TK_OFFSET_CENTER) {
		    tsoffset->xoffset =
			    (polyPtr->header.x1 + polyPtr->header.x2) / 2;
		} else if (tsoffset->flags & TK_OFFSET_RIGHT) {
		    tsoffset->xoffset = polyPtr->header.x2;
		}
		if (tsoffset->flags & TK_OFFSET_TOP) {
		    tsoffset->yoffset = polyPtr->header.y1;
		} else if (tsoffset->flags & TK_OFFSET_MIDDLE) {
		    tsoffset->yoffset =
			    (polyPtr->header.y1 + polyPtr->header.y2) / 2;
		} else if (tsoffset->flags & TK_OFFSET_BOTTOM) {
		    tsoffset->yoffset = polyPtr->header.y2;
		}
	    }
	}

	i = (int) ((width+1.5) / 2.0);
	polyPtr->header.x1 -= i;
	polyPtr->header.x2 += i;
	polyPtr->header.y1 -= i;
	polyPtr->header.y2 += i;

	/*
	 * For mitered lines, make a second pass through all the points.
	 * Compute the locations of the two miter vertex points and add those
	 * into the bounding box.
	 */

	if (polyPtr->joinStyle == JoinMiter) {
	    double miter[4];
	    int j;

	    coordPtr = polyPtr->coordPtr;
	    if (polyPtr->numPoints > 3) {
		if (TkGetMiterPoints(coordPtr+2*(polyPtr->numPoints-2),
			coordPtr, coordPtr+2, width, miter, miter+2)) {
		    for (j = 0; j < 4; j += 2) {
			TkIncludePoint((Tk_Item *) polyPtr, miter+j);
		    }
		}
	    }
	    for (i = polyPtr->numPoints ; i >= 3; i--, coordPtr += 2) {
		if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, width,
			miter, miter+2)) {
		    for (j = 0; j < 4; j += 2) {
			TkIncludePoint((Tk_Item *) polyPtr, miter+j);
		    }
		}
	    }
	}
    }

    /*
     * Add one more pixel of fudge factor just to be safe (e.g. X may round
     * differently than we do).
     */

    polyPtr->header.x1 -= 1;
    polyPtr->header.x2 += 1;
    polyPtr->header.y1 -= 1;
    polyPtr->header.y2 += 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkFillPolygon --
 *
 *	This function is invoked to convert a polygon to screen coordinates
 *	and display it using a particular GC.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	ItemPtr is drawn in drawable using the transformation information in
 *	canvas.
 *
 *--------------------------------------------------------------
 */

void
TkFillPolygon(
    Tk_Canvas canvas,		/* Canvas whose coordinate system is to be
				 * used for drawing. */
    double *coordPtr,		/* Array of coordinates for polygon: x1, y1,
				 * x2, y2, .... */
    int numPoints,		/* Twice this many coordinates are present at
				 * *coordPtr. */
    Display *display,		/* Display on which to draw polygon. */
    Drawable drawable,		/* Pixmap or window in which to draw
				 * polygon. */
    GC gc,			/* Graphics context for drawing. */
    GC outlineGC)		/* If not None, use this to draw an outline
				 * around the polygon after filling it. */
{
    XPoint staticPoints[MAX_STATIC_POINTS];
    XPoint *pointPtr;
    XPoint *pPtr;
    int i;

    /*
     * Build up an array of points in screen coordinates. Use a static array
     * unless the polygon has an enormous number of points; in this case,
     * dynamically allocate an array.
     */

    if (numPoints <= MAX_STATIC_POINTS) {
	pointPtr = staticPoints;
    } else {
	pointPtr = (XPoint *) ckalloc((unsigned) numPoints * sizeof(XPoint));
    }

    for (i=0, pPtr=pointPtr ; i<numPoints; i+=1, coordPtr+=2, pPtr++) {
	Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], &pPtr->x,
		&pPtr->y);
    }

    /*
     * Display polygon, then free up polygon storage if it was dynamically
     * allocated.
     */

    if (gc != None && numPoints > 3) {
	XFillPolygon(display, drawable, gc, pointPtr, numPoints, Complex,
		CoordModeOrigin);
    }
    if (outlineGC != None) {
	XDrawLines(display, drawable, outlineGC, pointPtr, numPoints,
		CoordModeOrigin);
    }
    if (pointPtr != staticPoints) {
	ckfree((char *) pointPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * DisplayPolygon --
 *
 *	This function is invoked to draw a polygon item in a given drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	ItemPtr is drawn in drawable using the transformation information in
 *	canvas.
 *
 *--------------------------------------------------------------
 */

static void
DisplayPolygon(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y, int width, int height)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    Tk_State state = itemPtr->state;
    Pixmap stipple = polyPtr->fillStipple;
    double linewidth = polyPtr->outline.width;

    if (((polyPtr->fillGC == None) && (polyPtr->outline.gc == None)) ||
	    (polyPtr->numPoints < 1) ||
	    (polyPtr->numPoints < 3 && polyPtr->outline.gc == None)) {
	return;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth > linewidth) {
	    linewidth = polyPtr->outline.activeWidth;
	}
	if (polyPtr->activeFillStipple != None) {
	    stipple = polyPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    linewidth = polyPtr->outline.disabledWidth;
	}
	if (polyPtr->disabledFillStipple != None) {
	    stipple = polyPtr->disabledFillStipple;
	}
    }

    /*
     * If we're stippling then modify the stipple offset in the GC. Be sure to
     * reset the offset when done, since the GC is supposed to be read-only.
     */

    if ((stipple != None) && (polyPtr->fillGC != None)) {
	Tk_TSOffset *tsoffset = &polyPtr->tsoffset;
	int w = 0, h = 0;
	int flags = tsoffset->flags;

	if (!(flags & TK_OFFSET_INDEX)
		&& (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {
	    Tk_SizeOfBitmap(display, stipple, &w, &h);
	    if (flags & TK_OFFSET_CENTER) {
		w /= 2;
	    } else {
		w = 0;
	    }
	    if (flags & TK_OFFSET_MIDDLE) {
		h /= 2;
	    } else {
		h = 0;
	    }
	}
	tsoffset->xoffset -= w;
	tsoffset->yoffset -= h;
	Tk_CanvasSetOffset(canvas, polyPtr->fillGC, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
    }
    Tk_ChangeOutlineGC(canvas, itemPtr, &polyPtr->outline);

    if (polyPtr->numPoints < 3) {
	short x, y;
	int intLineWidth = (int) (linewidth + 0.5);

	if (intLineWidth < 1) {
	    intLineWidth = 1;
	}
	Tk_CanvasDrawableCoords(canvas, polyPtr->coordPtr[0],
		polyPtr->coordPtr[1], &x, &y);
	XFillArc(display, drawable, polyPtr->outline.gc,
		x - intLineWidth/2, y - intLineWidth/2,
		(unsigned) intLineWidth+1, (unsigned) intLineWidth+1,
		0, 64*360);
    } else if (!polyPtr->smooth || polyPtr->numPoints < 4) {
	TkFillPolygon(canvas, polyPtr->coordPtr, polyPtr->numPoints,
		    display, drawable, polyPtr->fillGC, polyPtr->outline.gc);
    } else {
	int numPoints;
	XPoint staticPoints[MAX_STATIC_POINTS];
	XPoint *pointPtr;

	/*
	 * This is a smoothed polygon. Display using a set of generated spline
	 * points rather than the original points.
	 */

	numPoints = polyPtr->smooth->coordProc(canvas, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    pointPtr = staticPoints;
	} else {
	    pointPtr = (XPoint *)
		    ckalloc((unsigned) numPoints * sizeof(XPoint));
	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, pointPtr, NULL);
	if (polyPtr->fillGC != None) {
	    XFillPolygon(display, drawable, polyPtr->fillGC, pointPtr,
		    numPoints, Complex, CoordModeOrigin);
	}
	if (polyPtr->outline.gc != None) {
	    XDrawLines(display, drawable, polyPtr->outline.gc, pointPtr,
		    numPoints, CoordModeOrigin);
	}
	if (pointPtr != staticPoints) {
	    ckfree((char *) pointPtr);
	}
    }
    Tk_ResetOutlineGC(canvas, itemPtr, &polyPtr->outline);
    if ((stipple != None) && (polyPtr->fillGC != None)) {
	XSetTSOrigin(display, polyPtr->fillGC, 0, 0);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PolygonInsert --
 *
 *	Insert coords into a polugon item at a given index.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The coords in the given item is modified.
 *
 *--------------------------------------------------------------
 */

static void
PolygonInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    int beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length, objc, i;
    Tcl_Obj **objv;
    double *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    while (beforeThis > length) {
	beforeThis -= length;
    }
    while (beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)
	    ckalloc(sizeof(double) * (unsigned)(length + 2 + objc));
    for (i=0; i<beforeThis; i++) {
	newCoordPtr[i] = polyPtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i+beforeThis]) != TCL_OK){
	    ckfree((char *) newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = polyPtr->coordPtr[i];
    }
    if (polyPtr->coordPtr) {
	ckfree((char *) polyPtr->coordPtr);
    }
    length += objc;
    polyPtr->coordPtr = newCoordPtr;
    polyPtr->numPoints = (length/2) + polyPtr->autoClosed;

    /*
     * Close the polygon if it isn't already closed, or remove autoclosing if
     * the user's coordinates are now closed.
     */

    if (polyPtr->autoClosed) {
	if ((newCoordPtr[length-2] == newCoordPtr[0])
		&& (newCoordPtr[length-1] == newCoordPtr[1])) {
	    polyPtr->autoClosed = 0;
	    polyPtr->numPoints--;
	}
    } else {
	if ((newCoordPtr[length-2] != newCoordPtr[0])
		|| (newCoordPtr[length-1] != newCoordPtr[1])) {
	    polyPtr->autoClosed = 1;
	    polyPtr->numPoints++;
	}
    }

    newCoordPtr[length] = newCoordPtr[0];
    newCoordPtr[length+1] = newCoordPtr[1];
    if ((length-objc > 3) && (state != TK_STATE_HIDDEN)) {
	/*
	 * This is some optimizing code that will result that only the part of
	 * the polygon that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.
	 */

    	double width;
	int j;

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;

	/*
	 * The header elements that normally are used for the bounding box,
	 * are now used to calculate the bounding box for only the part that
	 * has to be redrawn. That doesn't matter, because afterwards the
	 * bounding box has to be re-calculated anyway.
	 */

	itemPtr->x1 = itemPtr->x2 = (int) polyPtr->coordPtr[beforeThis];
	itemPtr->y1 = itemPtr->y2 = (int) polyPtr->coordPtr[beforeThis+1];
	beforeThis -= 2;
	objc += 4;
	if (polyPtr->smooth) {
	    beforeThis -= 2;
	    objc += 4;
	}

	/*
	 * Be careful; beforeThis could now be negative
	 */

	for (i=beforeThis; i<beforeThis+objc; i+=2) {
	    j = i;
	    if (j < 0) {
		j += length;
	    } else if (j >= length) {
		j -= length;
	    }
	    TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
	}
	width = polyPtr->outline.width;
	if (Canvas(canvas)->currentItemPtr == itemPtr) {
	    if (polyPtr->outline.activeWidth > width) {
		width = polyPtr->outline.activeWidth;
	    }
	} else if (state == TK_STATE_DISABLED) {
	    if (polyPtr->outline.disabledWidth > 0.0) {
		width = polyPtr->outline.disabledWidth;
	    }
	}
	itemPtr->x1 -= (int) width;
	itemPtr->y1 -= (int) width;
	itemPtr->x2 += (int) width;
	itemPtr->y2 += (int) width;
	Tk_CanvasEventuallyRedraw(canvas,
		itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2);
    }

    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *
 * PolygonDeleteCoords --
 *
 *	Delete one or more coordinates from a polygon item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Characters between "first" and "last", inclusive, get deleted from
 *	itemPtr.
 *
 *--------------------------------------------------------------
 */

static void
PolygonDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    int first,			/* Index of first character to delete. */
    int last)			/* Index of last character to delete. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int count, i;
    int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while (first >= length) {
	first -= length;
    }
    while (first < 0) {
	first += length;
    }
    while (last >= length) {
	last -= length;
    }
    while (last < 0) {
	last += length;
    }

    first &= -2;
    last &= -2;

    count = last + 2 - first;
    if (count <= 0) {
	count += length;
    }

    if (count >= length) {
	polyPtr->numPoints = 0;
	if (polyPtr->coordPtr != NULL) {
	    ckfree((char *) polyPtr->coordPtr);
	}
	ComputePolygonBbox(canvas, polyPtr);
	return;
    }

    if (last >= first) {
	for (i=last+2; i<length; i++) {
	    polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i];
	}
    } else {
	for (i=last; i<=first; i++) {
	    polyPtr->coordPtr[i-last] = polyPtr->coordPtr[i];
	}
    }
    polyPtr->coordPtr[length-count] = polyPtr->coordPtr[0];
    polyPtr->coordPtr[length-count+1] = polyPtr->coordPtr[1];
    polyPtr->numPoints -= count/2;
    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *
 * PolygonToPoint --
 *
 *	Computes the distance from a given point to a given polygon, in canvas
 *	units.
 *
 * Results:
 *	The return value is 0 if the point whose x and y coordinates are
 *	pointPtr[0] and pointPtr[1] is inside the polygon. If the point isn't
 *	inside the polygon then the return value is the distance from the
 *	point to the polygon.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
PolygonToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *pointPtr)		/* Pointer to x and y coordinates. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr, *polyPoints;
    double staticSpace[2*MAX_STATIC_POINTS];
    double poly[10];
    double radius;
    double bestDist, dist;
    int numPoints, count;
    int changedMiterToBevel;	/* Non-zero means that a mitered corner had to
				 * be treated as beveled after all because the
				 * angle was < 11 degrees. */
    double width;
    Tk_State state = itemPtr->state;

    bestDist = 1.0e36;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth > width) {
	    width = polyPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    width = polyPtr->outline.disabledWidth;
	}
    }
    radius = width/2.0;

    /*
     * Handle smoothed polygons by generating an expanded set of points
     * against which to do the check.
     */

    if ((polyPtr->smooth) && (polyPtr->numPoints > 2)) {
	numPoints = polyPtr->smooth->coordProc(canvas, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    polyPoints = staticSpace;
	} else {
	    polyPoints = (double *)
		    ckalloc((unsigned) 2*numPoints*sizeof(double));
	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, polyPoints);
    } else {
	numPoints = polyPtr->numPoints;
	polyPoints = polyPtr->coordPtr;
    }

    bestDist = TkPolygonToPoint(polyPoints, numPoints, pointPtr);
    if (bestDist <= 0.0) {
	goto donepoint;
    }
    if ((polyPtr->outline.gc != None) && (polyPtr->joinStyle == JoinRound)) {
	dist = bestDist - radius;
	if (dist <= 0.0) {
	    bestDist = 0.0;
	    goto donepoint;
	} else {
	    bestDist = dist;
	}
    }

    if ((polyPtr->outline.gc == None) || (width <= 1)) {
	goto donepoint;
    }

    /*
     * The overall idea is to iterate through all of the edges of the line,
     * computing a polygon for each edge and testing the point against that
     * polygon. In addition, there are additional tests to deal with rounded
     * joints and caps.
     */

    changedMiterToBevel = 0;
    for (count = numPoints, coordPtr = polyPoints; count >= 2;
	    count--, coordPtr += 2) {
	/*
	 * If rounding is done around the first point then compute the
	 * distance between the point and the point.
	 */

	if (polyPtr->joinStyle == JoinRound) {
	    dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1])
		    - radius;
	    if (dist <= 0.0) {
		bestDist = 0.0;
		goto donepoint;
	    } else if (dist < bestDist) {
		bestDist = dist;
	    }
	}

	/*
	 * Compute the polygonal shape corresponding to this edge, consisting
	 * of two points for the first point of the edge and two points for
	 * the last point of the edge.
	 */

	if (count == numPoints) {
	    TkGetButtPoints(coordPtr+2, coordPtr, (double) width, 0, poly,
		    poly+2);
	} else if ((polyPtr->joinStyle == JoinMiter) && !changedMiterToBevel) {
	    poly[0] = poly[6];
	    poly[1] = poly[7];
	    poly[2] = poly[4];
	    poly[3] = poly[5];
	} else {
	    TkGetButtPoints(coordPtr+2, coordPtr, (double) width, 0, poly,
		    poly+2);

	    /*
	     * If this line uses beveled joints, then check the distance to a
	     * polygon comprising the last two points of the previous polygon
	     * and the first two from this polygon; this checks the wedges
	     * that fill the mitered joint.
	     */

	    if ((polyPtr->joinStyle == JoinBevel) || changedMiterToBevel) {
		poly[8] = poly[0];
		poly[9] = poly[1];
		dist = TkPolygonToPoint(poly, 5, pointPtr);
		if (dist <= 0.0) {
		    bestDist = 0.0;
		    goto donepoint;
		} else if (dist < bestDist) {
		    bestDist = dist;
		}
		changedMiterToBevel = 0;
	    }
	}
	if (count == 2) {
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, poly+4,
		    poly+6);
	} else if (polyPtr->joinStyle == JoinMiter) {
	    if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
		    (double) width, poly+4, poly+6) == 0) {
		changedMiterToBevel = 1;
		TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0,
			poly+4, poly+6);
	    }
	} else {
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, poly+4,
		    poly+6);
	}
	poly[8] = poly[0];
	poly[9] = poly[1];
	dist = TkPolygonToPoint(poly, 5, pointPtr);
	if (dist <= 0.0) {
	    bestDist = 0.0;
	    goto donepoint;
	} else if (dist < bestDist) {
	    bestDist = dist;
	}
    }

  donepoint:
    if (polyPoints != staticSpace && polyPoints != polyPtr->coordPtr) {
	ckfree((char *) polyPoints);
    }
    return bestDist;
}

/*
 *--------------------------------------------------------------
 *
 * PolygonToArea --
 *
 *	This function is called to determine whether an item lies entirely
 *	inside, entirely outside, or overlapping a given rectangular area.
 *
 * Results:
 *	-1 is returned if the item is entirely outside the area given by
 *	rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
 *	area.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
PolygonToArea(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against polygon. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    double staticSpace[2*MAX_STATIC_POINTS];
    double *polyPoints, poly[10];
    double radius;
    int numPoints, count;
    int changedMiterToBevel;	/* Non-zero means that a mitered corner had to
				 * be treated as beveled after all because the
				 * angle was < 11 degrees. */
    int inside;			/* Tentative guess about what to return, based
				 * on all points seen so far: one means
				 * everything seen so far was inside the area;
				 * -1 means everything was outside the area. 0
				 * means overlap has been found. */
    double width;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = polyPtr->outline.width;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth > width) {
	    width = polyPtr->outline.activeWidth;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    width = polyPtr->outline.disabledWidth;
	}
    }

    radius = width/2.0;
    inside = -1;

    if ((state == TK_STATE_HIDDEN) || polyPtr->numPoints < 2) {
	return -1;
    } else if (polyPtr->numPoints < 3) {
	double oval[4];

	oval[0] = polyPtr->coordPtr[0]-radius;
	oval[1] = polyPtr->coordPtr[1]-radius;
	oval[2] = polyPtr->coordPtr[0]+radius;
	oval[3] = polyPtr->coordPtr[1]+radius;
	return TkOvalToArea(oval, rectPtr);
    }

    /*
     * Handle smoothed polygons by generating an expanded set of points
     * against which to do the check.
     */

    if (polyPtr->smooth) {
	numPoints = polyPtr->smooth->coordProc(canvas, NULL,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
	if (numPoints <= MAX_STATIC_POINTS) {
	    polyPoints = staticSpace;
	} else {
	    polyPoints = (double *)
		    ckalloc((unsigned) 2*numPoints*sizeof(double));
	}
	numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
		polyPtr->numPoints, polyPtr->splineSteps, NULL, polyPoints);
    } else {
	numPoints = polyPtr->numPoints;
	polyPoints = polyPtr->coordPtr;
    }

    /*
     * Simple test to see if we are in the polygon. Polygons are different
     * from othe canvas items in that they register points being inside even
     * if it isn't filled.
     */

    inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
    if (inside == 0) {
	goto donearea;
    }

    if (polyPtr->outline.gc == None) {
	goto donearea;
    }

    /*
     * Iterate through all of the edges of the line, computing a polygon for
     * each edge and testing the area against that polygon. In addition, there
     * are additional tests to deal with rounded joints and caps.
     */

    changedMiterToBevel = 0;
    for (count = numPoints, coordPtr = polyPoints; count >= 2;
	    count--, coordPtr += 2) {
	/*
	 * If rounding is done around the first point of the edge then test a
	 * circular region around the point with the area.
	 */

	if (polyPtr->joinStyle == JoinRound) {
	    poly[0] = coordPtr[0] - radius;
	    poly[1] = coordPtr[1] - radius;
	    poly[2] = coordPtr[0] + radius;
	    poly[3] = coordPtr[1] + radius;
	    if (TkOvalToArea(poly, rectPtr) != inside) {
		inside = 0;
		goto donearea;
	    }
	}

	/*
	 * Compute the polygonal shape corresponding to this edge, consisting
	 * of two points for the first point of the edge and two points for
	 * the last point of the edge.
	 */

	if (count == numPoints) {
	    TkGetButtPoints(coordPtr+2, coordPtr, width, 0, poly, poly+2);
	} else if ((polyPtr->joinStyle == JoinMiter) && !changedMiterToBevel) {
	    poly[0] = poly[6];
	    poly[1] = poly[7];
	    poly[2] = poly[4];
	    poly[3] = poly[5];
	} else {
	    TkGetButtPoints(coordPtr+2, coordPtr, width, 0, poly, poly+2);

	    /*
	     * If the last joint was beveled, then also check a polygon
	     * comprising the last two points of the previous polygon and the
	     * first two from this polygon; this checks the wedges that fill
	     * the beveled joint.
	     */

	    if ((polyPtr->joinStyle == JoinBevel) || changedMiterToBevel) {
		poly[8] = poly[0];
		poly[9] = poly[1];
		if (TkPolygonToArea(poly, 5, rectPtr) != inside) {
		    inside = 0;
		    goto donearea;
		}
		changedMiterToBevel = 0;
	    }
	}
	if (count == 2) {
	    TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6);
	} else if (polyPtr->joinStyle == JoinMiter) {
	    if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, width,
		    poly+4, poly+6) == 0) {
		changedMiterToBevel = 1;
		TkGetButtPoints(coordPtr, coordPtr+2, width,0, poly+4, poly+6);
	    }
	} else {
	    TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6);
	}
	poly[8] = poly[0];
	poly[9] = poly[1];
	if (TkPolygonToArea(poly, 5, rectPtr) != inside) {
	    inside = 0;
	    goto donearea;
	}
    }

  donearea:
    if ((polyPoints != staticSpace) && (polyPoints != polyPtr->coordPtr)) {
	ckfree((char *) polyPoints);
    }
    return inside;
}

/*
 *--------------------------------------------------------------
 *
 * ScalePolygon --
 *
 *	This function is invoked to rescale a polygon item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The polygon referred to by itemPtr is rescaled so that the following
 *	transformation is applied to all point coordinates:
 *		x' = originX + scaleX*(x-originX)
 *		y' = originY + scaleY*(y-originY)
 *
 *--------------------------------------------------------------
 */

static void
ScalePolygon(
    Tk_Canvas canvas,		/* Canvas containing polygon. */
    Tk_Item *itemPtr,		/* Polygon to be scaled. */
    double originX, double originY,
				/* Origin about which to scale rect. */
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    int i;

    for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
	    i++, coordPtr += 2) {
	*coordPtr = originX + scaleX*(*coordPtr - originX);
	coordPtr[1] = originY + scaleY*(coordPtr[1] - originY);
    }
    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *
 * GetPolygonIndex --
 *
 *	Parse an index into a polygon item and return either its value or an
 *	error.
 *
 * Results:
 *	A standard Tcl result. If all went well, then *indexPtr is filled in
 *	with the index (into itemPtr) corresponding to string. Otherwise an
 *	error message is left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
GetPolygonIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    int *indexPtr)		/* Where to store converted index. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length;
    const char *string = Tcl_GetStringFromObj(obj, &length);

    if (string[0] == 'e') {
	if (strncmp(string, "end", (unsigned)length) != 0) {
	    goto badIndex;
	}
	*indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    } else if (string[0] == '@@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	p = end+1;
	y = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = polyPtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<polyPtr->numPoints-1; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	int count = 2*(polyPtr->numPoints - polyPtr->autoClosed);

	if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	*indexPtr &= -2; /* if odd, make it even */
	if (!count) {
	    *indexPtr = 0;
	} else if (*indexPtr > 0) {
	    *indexPtr = ((*indexPtr - 2) % count) + 2;
	} else {
	    *indexPtr = -((-(*indexPtr)) % count);
	}
    }
    return TCL_OK;

    /*
     * Some of the paths here leave messages in interp->result, so we have to
     * clear it out before storing our own message.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * TranslatePolygon --
 *
 *	This function is called to move a polygon by a given amount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the polygon is offset by (xDelta, yDelta), and the
 *	bounding box is updated in the generic part of the item structure.
 *
 *--------------------------------------------------------------
 */

static void
TranslatePolygon(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double deltaX, double deltaY)
				/* Amount by which item is to be moved. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    int i;

    for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
	    i++, coordPtr += 2) {
	*coordPtr += deltaX;
	coordPtr[1] += deltaY;
    }
    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *
 * PolygonToPostscript --
 *
 *	This function is called to generate Postscript for polygon items.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs in
 *	generating Postscript then an error message is left in the interp's
 *	result, replacing whatever used to be there. If no error occurs, then
 *	Postscript for the item is appended to the result.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
PolygonToPostscript(
    Tcl_Interp *interp,		/* Leave Postscript or error message here. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    int prepass)		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    const char *style;
    XColor *color;
    XColor *fillColor;
    Pixmap stipple;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    double width;

    if (polyPtr->numPoints < 2 || polyPtr->coordPtr == NULL) {
	return TCL_OK;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    width = polyPtr->outline.width;
    color = polyPtr->outline.color;
    stipple = polyPtr->fillStipple;
    fillColor = polyPtr->fillColor;
    fillStipple = polyPtr->fillStipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (polyPtr->outline.activeWidth > width) {
	    width = polyPtr->outline.activeWidth;
	}
	if (polyPtr->outline.activeColor != NULL) {
	    color = polyPtr->outline.activeColor;
	}
	if (polyPtr->outline.activeStipple != None) {
	    stipple = polyPtr->outline.activeStipple;
	}
	if (polyPtr->activeFillColor != NULL) {
	    fillColor = polyPtr->activeFillColor;
	}
	if (polyPtr->activeFillStipple != None) {
	    fillStipple = polyPtr->activeFillStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth > 0.0) {
	    width = polyPtr->outline.disabledWidth;
	}
	if (polyPtr->outline.disabledColor != NULL) {
	    color = polyPtr->outline.disabledColor;
	}
	if (polyPtr->outline.disabledStipple != None) {
	    stipple = polyPtr->outline.disabledStipple;
	}
	if (polyPtr->disabledFillColor != NULL) {
	    fillColor = polyPtr->disabledFillColor;
	}
	if (polyPtr->disabledFillStipple != None) {
	    fillStipple = polyPtr->disabledFillStipple;
	}
    }
    if (polyPtr->numPoints == 2) {
	if (color == NULL) {
	    return TCL_OK;
	}

	/*
	 * Create a point by using a small circle. (Printer pixels are too
	 * tiny to be used directly...)
	 */

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"matrix currentmatrix\n"	/* save state */
		"%.15g %.15g translate "	/* go to drawing location */
		"%.15g %.15g scale "		/* scale the drawing */
		"1 0 moveto "			/* correct for origin */
		"0 0 1 0 360 arc\n"		/* make the circle */
		"setmatrix\n",			/* restore state */
		polyPtr->coordPtr[0],
		Tk_CanvasPsY(canvas, polyPtr->coordPtr[1]),
		width/2.0, width/2.0));

	/*
	 * Color it in.
	 */

	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (stipple != None) {
	    Tcl_AppendResult(interp, "clip ", NULL);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		return TCL_ERROR;
	    }
	} else {
	    Tcl_AppendResult(interp, "fill\n", NULL);
	}
	return TCL_OK;
    }

    /*
     * Fill the area of the polygon.
     */

    if (fillColor != NULL && polyPtr->numPoints > 3) {
	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (fillStipple != None) {
	    Tcl_AppendResult(interp, "eoclip ", NULL);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (color != NULL) {
		Tcl_AppendResult(interp, "grestore gsave\n", NULL);
	    }
	} else {
	    Tcl_AppendResult(interp, "eofill\n", NULL);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {
	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}

	if (polyPtr->joinStyle == JoinRound) {
	    style = "1";
	} else if (polyPtr->joinStyle == JoinBevel) {
	    style = "2";
	} else {
	    style = "0";
	}
	Tcl_AppendResult(interp, style, " setlinejoin 1 setlinecap\n", NULL);
	if (Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline) != TCL_OK){
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
@


1.27
log
@Eliminate many unnecessary (ClientData) type casts.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.26 2010/02/17 19:21:16 nijtmans Exp $
d256 1
a256 1
	Tcl_Panic("canvas did not pass any coords\n");
@


1.26
log
@CONSTify everything related to Tk_ConfigSpec
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.25 2010/01/18 20:43:38 nijtmans Exp $
d60 1
a60 1
    TkSmoothParseProc, TkSmoothPrintProc, (ClientData) NULL
d63 1
a63 1
    TkStateParseProc, TkStatePrintProc, (ClientData) 2
d66 1
a66 1
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, (ClientData) NULL
d69 1
a69 1
    TkCanvasDashParseProc, TkCanvasDashPrintProc, (ClientData) NULL
d73 1
a73 1
    (ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
d76 1
a76 1
    TkPixelParseProc, TkPixelPrintProc, (ClientData) NULL
@


1.25
log
@fix more gcc warnings: missing initializer
Apply patch [#2932808]: Canvas items
not updating on widget state change
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.24 2009/01/06 21:58:15 nijtmans Exp $
d79 1
a79 1
static Tk_ConfigSpec configSpecs[] = {
@


1.24
log
@A few const -> CONST86 modifications, improving
backwards compatibility. Change Tk_ItemIndexProc
and Tk_ItemInsertProc signature to have a Tcl_Obj parameter
in stead of a string parameter. This is binary
and source compatible with previous API, it just prevents
the need for a type cast in the Tk_ItemType table construction.
Bring doc in line with API.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.23 2008/11/09 21:53:39 nijtmans Exp $
a15 1
#include <stdio.h>
d84 1
a84 1
	NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK},
d86 1
a86 1
	NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK},
d89 1
a89 1
	TK_CONFIG_NULL_OK},
d91 1
a91 1
	NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK},
d100 1
a100 1
	TK_CONFIG_DONT_SET_DEFAULT},
d105 1
a105 1
	NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK},
d108 1
a108 1
	TK_CONFIG_NULL_OK},
d111 1
a111 1
	TK_CONFIG_NULL_OK},
d113 1
a113 1
	NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK},
d118 1
a118 1
	"black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK},
d120 1
a120 1
	"round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},
d125 1
a125 1
	NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK},
d130 1
a130 1
	NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK},
d135 1
a135 1
	"12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},
d139 1
a139 1
	NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK},
d145 1
a145 1
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
d213 1
@


1.23
log
@One more (hopefully the last) signature change
in Tk_CreateSmoothMethod.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.22 2008/11/09 20:51:28 nijtmans Exp $
d208 1
a208 1
    (Tk_ItemIndexProc *) GetPolygonIndex,/* indexProc */
d211 1
a211 1
    (Tk_ItemInsertProc *) PolygonInsert,/* insertProc */
d290 1
a290 1
	char *arg = Tcl_GetString(objv[i]);
d1682 1
a1682 1
    char *string = Tcl_GetStringFromObj(obj, &length);
d1692 2
a1693 1
	char *end, *p;
@


1.22
log
@make all Tk_CustomOption tables const and
remove unnecessary type cast
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.21 2008/11/01 16:14:30 dkf Exp $
d49 1
a49 1
    Tk_SmoothMethod *smooth;	/* Non-zero means draw shape smoothed (i.e.
@


1.21
log
@Implementation of TIP 97 - canvas imove and rchars methods.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.20 2008/10/30 23:18:59 nijtmans Exp $
d60 1
a60 1
static Tk_CustomOption smoothOption = {
d63 1
a63 1
static Tk_CustomOption stateOption = {
d66 1
a66 1
static Tk_CustomOption tagsOption = {
d69 1
a69 1
static Tk_CustomOption dashOption = {
d72 1
a72 1
static Tk_CustomOption offsetOption = {
d76 1
a76 1
static Tk_CustomOption pixelOption = {
@


1.20
log
@more internal -Wwrite-strings warning fixes
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.19 2008/04/27 22:38:55 dkf Exp $
d202 1
a202 1
    TK_CONFIG_OBJS,			/* flags */
d264 1
a264 1
    Tk_CreateOutline(&(polyPtr->outline));
d291 1
d361 3
a363 5
	char buf[64 + TCL_INTEGER_SPACE];

	sprintf(buf, "wrong # coordinates: expected an even number, got %d",
		objc);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
d365 1
a365 6
    } else {
	numPoints = objc/2;
	if (polyPtr->pointsAllocated <= numPoints) {
	    if (polyPtr->coordPtr != NULL) {
		ckfree((char *) polyPtr->coordPtr);
	    }
d367 4
a370 14
	    /*
	     * One extra point gets allocated here, because we always add
	     * another point to close the polygon.
	     */

	    polyPtr->coordPtr = (double *) ckalloc((unsigned)
		    (sizeof(double) * (objc+2)));
	    polyPtr->pointsAllocated = numPoints+1;
	}
	for (i = objc-1; i >= 0; i--) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
		    &polyPtr->coordPtr[i]) != TCL_OK) {
		return TCL_ERROR;
	    }
a371 2
	polyPtr->numPoints = numPoints;
	polyPtr->autoClosed = 0;
d374 2
a375 1
	 * Close the polygon if it isn't already closed.
d378 8
a385 6
	if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0])
		|| (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) {
	    polyPtr->autoClosed = 1;
	    polyPtr->numPoints++;
	    polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	    polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
a386 1
	ComputePolygonBbox(canvas, polyPtr);
d388 16
d468 1
a468 1
    if(state == TK_STATE_NULL) {
d471 1
a471 1
    if (state==TK_STATE_HIDDEN) {
d476 1
a476 1
    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(polyPtr->outline));
d493 1
a493 1
	if (polyPtr->activeFillColor!=NULL) {
d496 1
a496 1
	if (polyPtr->activeFillStipple!=None) {
d499 2
a500 2
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->disabledFillColor!=NULL) {
d503 1
a503 1
	if (polyPtr->disabledFillStipple!=None) {
d573 1
a573 1
    Tk_DeleteOutline(display,&(polyPtr->outline));
d628 1
a628 1
    if(state == TK_STATE_NULL) {
d632 2
a633 1
    if (polyPtr->coordPtr == NULL || (polyPtr->numPoints < 1) || (state==TK_STATE_HIDDEN)) {
d635 1
a635 1
	polyPtr->header.y1 = polyPtr->header.y2 = -1;
d638 2
a639 2
    if (Canvas(canvas)->currentItemPtr == (Tk_Item *)polyPtr) {
	if (polyPtr->outline.activeWidth>width) {
d642 2
a643 2
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
d669 1
d677 1
a677 1
	if (index <0) {
d709 1
a709 1
		if (index <0) {
d718 2
a719 1
		    tsoffset->xoffset = (polyPtr->header.x1 + polyPtr->header.x2)/2;
d726 2
a727 1
		    tsoffset->yoffset = (polyPtr->header.y1 + polyPtr->header.y2)/2;
d734 1
a734 1
	i = (int) ((width+1.5)/2.0);
d751 1
a751 1
	    if (polyPtr->numPoints>3) {
d753 1
a753 2
			coordPtr, coordPtr+2, width,
			miter, miter+2)) {
d758 1
a758 1
	     }
d760 2
a761 3

		if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
			width, miter, miter+2)) {
d828 1
a828 1
	pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint)));
d841 1
a841 1
    if (gc != None && numPoints>3) {
d846 2
a847 2
	XDrawLines(display, drawable, outlineGC, pointPtr,
	    numPoints, CoordModeOrigin);
d896 1
a896 1
	if (polyPtr->outline.activeWidth>linewidth) {
d902 2
a903 2
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
d918 1
a918 1
	int w=0; int h=0;
d921 2
a922 1
	if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {
d941 1
a941 1
    Tk_ChangeOutlineGC(canvas, itemPtr, &(polyPtr->outline));
d943 2
a944 2
    if(polyPtr->numPoints < 3) {
	short x,y;
d951 1
a951 1
		    polyPtr->coordPtr[1], &x,&y);
d954 1
a954 1
		(unsigned int)intLineWidth+1, (unsigned int)intLineWidth+1,
d974 2
a975 2
	    pointPtr = (XPoint *) ckalloc((unsigned)
		    (numPoints * sizeof(XPoint)));
d991 1
a991 1
    Tk_ResetOutlineGC(canvas, itemPtr, &(polyPtr->outline));
d1036 1
a1036 1
    while (beforeThis>length) {
d1039 1
a1039 1
    while (beforeThis<0) {
d1086 1
a1086 1
    if (((length-objc)>3) && (state != TK_STATE_HIDDEN)) {
d1098 1
d1110 2
a1111 1
	beforeThis-=2; objc+=4;
d1113 2
a1114 2
	    beforeThis-=2;
	    objc+=4;
d1123 1
a1123 1
	    if (j<0) {
d1125 1
a1125 1
	    } else if (j>=length) {
d1135 1
a1135 1
	} else if (state==TK_STATE_DISABLED) {
d1140 4
a1143 2
	itemPtr->x1 -= (int) width; itemPtr->y1 -= (int) width;
	itemPtr->x2 += (int) width; itemPtr->y2 += (int) width;
d1179 1
a1179 1
    while (first>=length) {
d1182 1
a1182 1
    while (first<0) {
d1185 1
a1185 1
    while (last>=length) {
d1188 1
a1188 1
    while (last<0) {
d1196 1
a1196 1
    if (count<=0) {
d1209 2
a1210 2
    if (last>=first) {
	for(i=last+2; i<length; i++) {
d1214 1
a1214 1
	for(i=last; i<=first; i++) {
d1271 1
a1271 1
	if (polyPtr->outline.activeWidth>width) {
d1274 2
a1275 2
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
d1286 1
a1286 1
    if ((polyPtr->smooth) && (polyPtr->numPoints>2)) {
d1288 1
a1288 2
		polyPtr->numPoints, polyPtr->splineSteps, NULL,
		NULL);
d1292 2
a1293 2
	    polyPoints = (double *) ckalloc((unsigned)
		    (2*numPoints*sizeof(double)));
d1296 1
a1296 2
		polyPtr->numPoints, polyPtr->splineSteps, NULL,
		polyPoints);
d1303 1
a1303 1
    if (bestDist<=0.0) {
d1353 2
a1354 2
	    TkGetButtPoints(coordPtr+2, coordPtr, (double) width,
		    0, poly, poly+2);
d1361 2
a1362 2
	    TkGetButtPoints(coordPtr+2, coordPtr, (double) width, 0,
		    poly, poly+2);
d1385 2
a1386 2
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width,
		    0, poly+4, poly+6);
d1395 2
a1396 2
	    TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0,
		    poly+4, poly+6);
d1410 1
a1410 1
    if ((polyPoints != staticSpace) && polyPoints != polyPtr->coordPtr) {
d1467 1
a1467 1
	if (polyPtr->outline.activeWidth>width) {
d1470 2
a1471 2
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
d1479 1
a1479 1
    if ((state==TK_STATE_HIDDEN) || polyPtr->numPoints<2) {
d1481 1
a1481 1
    } else if (polyPtr->numPoints <3) {
d1503 1
a1503 1
		    ckalloc((unsigned) (2*numPoints*sizeof(double)));
d1519 1
a1519 1
    if (inside==0) {
d1588 2
a1589 2
	    if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
		    width, poly+4, poly+6) == 0) {
d1685 2
a1686 12
	if (strncmp(string, "end", (unsigned)length) == 0) {
	    *indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);
	} else {
	    /*
	     * Some of the paths here leave messages in interp->result, so we
	     * have to clear it out before storing our own message.
	     */

	badIndex:
	    Tcl_SetResult(interp, NULL, TCL_STATIC);
	    Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
	    return TCL_ERROR;
d1688 1
d1691 1
a1691 1
	double x ,y, bestDist, dist, *coordPtr;
d1707 1
a1707 1
	for(i=0; i<(polyPtr->numPoints-1); i++) {
d1709 1
a1709 1
	    if (dist<bestDist) {
d1722 4
a1725 6
	if (count) {
	    if (*indexPtr > 0) {
		*indexPtr = ((*indexPtr - 2) % count) + 2;
	    } else {
		*indexPtr = -((-(*indexPtr)) % count);
	    }
d1727 1
a1727 1
	    *indexPtr = 0;
d1731 9
d1815 1
a1815 1
    if (polyPtr->numPoints<2 || polyPtr->coordPtr==NULL) {
d1819 1
a1819 1
    if(state == TK_STATE_NULL) {
d1828 1
a1828 1
	if (polyPtr->outline.activeWidth>width) {
d1831 1
a1831 1
	if (polyPtr->outline.activeColor!=NULL) {
d1834 1
a1834 1
	if (polyPtr->outline.activeStipple!=None) {
d1837 1
a1837 1
	if (polyPtr->activeFillColor!=NULL) {
d1840 1
a1840 1
	if (polyPtr->activeFillStipple!=None) {
d1843 2
a1844 2
    } else if (state==TK_STATE_DISABLED) {
	if (polyPtr->outline.disabledWidth>0.0) {
d1847 1
a1847 1
	if (polyPtr->outline.disabledColor!=NULL) {
d1850 1
a1850 1
	if (polyPtr->outline.disabledStipple!=None) {
d1853 1
a1853 1
	if (polyPtr->disabledFillColor!=NULL) {
d1856 1
a1856 1
	if (polyPtr->disabledFillStipple!=None) {
d1860 1
a1860 2
    if (polyPtr->numPoints==2) {
	char string[128];
d1865 20
a1884 5
	sprintf(string, "%.15g %.15g translate %.15g %.15g",
		polyPtr->coordPtr[0], Tk_CanvasPsY(canvas, polyPtr->coordPtr[1]),
		width/2.0, width/2.0);
	Tcl_AppendResult(interp, "matrix currentmatrix\n",string,
		" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", NULL);
d1903 1
a1903 1
    if (fillColor != NULL && polyPtr->numPoints>3) {
d1947 2
a1948 3
	Tcl_AppendResult(interp, style," setlinejoin 1 setlinecap\n", NULL);
	if (Tk_CanvasPsOutline(canvas, itemPtr,
		&(polyPtr->outline)) != TCL_OK) {
@


1.19
log
@Get rid of pre-C89-isms (esp. CONST vs const).
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.18 2007/12/13 15:24:13 dgp Exp $
d61 1
a61 2
    (Tk_OptionParseProc *) TkSmoothParseProc,
    TkSmoothPrintProc, (ClientData) NULL
d64 1
a64 2
    (Tk_OptionParseProc *) TkStateParseProc,
    TkStatePrintProc, (ClientData) 2
d67 1
a67 2
    (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, (ClientData) NULL
d70 1
a70 2
    (Tk_OptionParseProc *) TkCanvasDashParseProc,
    TkCanvasDashPrintProc, (ClientData) NULL
d73 1
a73 2
    (Tk_OptionParseProc *) TkOffsetParseProc,
    TkOffsetPrintProc,
d77 1
a77 2
    (Tk_OptionParseProc *) TkPixelParseProc,
    TkPixelPrintProc, (ClientData) NULL
d523 1
a523 1
	gcValues.line_width = polyPtr->outline.gc != None ? 
d1804 1
a1804 1
    char *style;
@


1.18
log
@merge stable branch onto HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.16.2.1 2007/09/07 01:25:34 dgp Exp $
d163 1
a163 1
			    Tcl_Obj *CONST objv[], int flags);
d166 1
a166 1
			    int objc, Tcl_Obj *CONST objv[]);
d177 1
a177 1
			    int objc, Tcl_Obj *CONST objv[]);
d256 1
a256 1
    Tcl_Obj *CONST objv[])	/* Arguments describing polygon. */
d339 1
a339 1
    Tcl_Obj *CONST objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
d438 1
a438 1
    Tcl_Obj *CONST objv[],	/* Arguments describing things to configure. */
d452 1
a452 1
	    (CONST char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) {
d475 1
a475 1
	state = ((TkCanvas *)canvas)->canvas_state;
d498 1
a498 1
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
d635 1
a635 1
	state = ((TkCanvas *)canvas)->canvas_state;
d643 1
a643 1
    if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)polyPtr) {
d897 1
a897 1
	state = ((TkCanvas *)canvas)->canvas_state;
d899 1
a899 1
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
d1031 1
a1031 1
	state = ((TkCanvas *)canvas)->canvas_state;
d1132 1
a1132 1
	if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
d1266 1
a1266 1
	state = ((TkCanvas *)canvas)->canvas_state;
d1269 1
a1269 1
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
d1463 1
a1463 1
	state = ((TkCanvas *)canvas)->canvas_state;
d1467 1
a1467 1
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
d1823 1
a1823 1
	state = ((TkCanvas *)canvas)->canvas_state;
d1830 1
a1830 1
    if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
@


1.17
log
@header cleanup
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.16 2006/10/16 15:35:28 das Exp $
@


1.16
log
@	* changes: updates for 8.5a5 release.

	* macosx/tkMacOSXDraw.c: fix numerous issues in CG and QD drawing procs
	so that they now match X11 drawing much more closely [Bug 1558051];
	use Tiger ellipse drawing API when available; fix comments & whitespace.

	* macosx/tkMacOSXInit.c: set default linewidth limit for CG
	antialiasing to 0 as thin horizontal/vertical lines look good now.

	* generic/tkCanvLine.c (ConfigureLine):     on TkAqua, pass outline
	* generic/tkCanvPoly.c (ConfigurePolygon):  linewidth in gc even for
	* generic/tkRectOval.c (ConfigureRectOval): fills (as it controls AA).
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.15 2005/11/17 10:57:35 dkf Exp $
a17 1
#include "tkPort.h"
@


1.16.2.1
log
@merge updates from HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.16 2006/10/16 15:35:28 das Exp $
d18 1
@


1.15
log
@Lots of ANSIfying of function decls.
Also a few spots where code has been cleaned up more completely.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.14 2005/11/04 15:23:05 dkf Exp $
d525 9
@


1.14
log
@ANSIfy
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.13 2005/08/10 22:02:22 dkf Exp $
d1019 1
a1019 1
    double *new;
d1037 2
a1038 1
    new = (double *) ckalloc((unsigned)(sizeof(double) * (length + 2 + objc)));
d1040 1
a1040 1
	new[i] = polyPtr->coordPtr[i];
d1043 3
a1045 2
	if (Tcl_GetDoubleFromObj(NULL, objv[i], new+(i+beforeThis)) != TCL_OK){
	    ckfree((char *) new);
d1051 1
a1051 1
	new[i+objc] = polyPtr->coordPtr[i];
d1057 1
a1057 1
    polyPtr->coordPtr = new;
d1066 2
a1067 1
	if ((new[length-2] == new[0]) && (new[length-1] == new[1])) {
d1072 2
a1073 1
	if ((new[length-2] != new[0]) || (new[length-1] != new[1])) {
d1079 2
a1080 2
    new[length] = new[0];
    new[length+1] = new[1];
@


1.13
log
@Getting more systematic about style
Also start removing _ANSI_ARGS_; the core's required ANSI C for a while now
Also fix [Bug 1252702]; size_t doesn't mix with Tcl_GetStringFromObj
@
text
@d1 1
a1 1
/* 
d10 2
a11 2
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.12 2004/01/13 02:06:00 davygrvy Exp $
d27 1
a27 1
				 * types.  MUST BE FIRST IN STRUCTURE. */
d29 2
a30 2
    int numPoints;		/* Number of points in polygon.
				 * Polygon is always closed. */
d33 2
a34 2
    double *coordPtr;		/* Pointer to malloc-ed array containing
				 * x- and y-coords of all points in polygon.
d40 4
a43 2
    XColor *activeFillColor;	/* Foreground color for polygon if state is active. */
    XColor *disabledFillColor;	/* Foreground color for polygon if state is disabled. */
d45 4
a48 2
    Pixmap activeFillStipple;	/* Stipple bitmap for filling polygon if state is active. */
    Pixmap disabledFillStipple;	/* Stipple bitmap for filling polygon if state is disabled. */
d88 2
a89 2
    {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.activeDash),
d91 6
a96 8
    {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, activeFillColor),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_COLOR, "-activeoutline", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.activeColor),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.activeStipple),
d98 3
a100 4
    {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, activeFillStipple),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
d103 2
a104 2
    {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.dash),
d106 1
a106 1
    {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
d109 2
a110 2
    {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.disabledDash),
d112 4
a115 5
    {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, disabledFillColor),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_COLOR, "-disabledoutline", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.disabledColor),
d117 2
a118 2
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
d120 3
a122 4
    {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, disabledFillStipple),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,
d125 1
a125 1
    {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
d127 1
a127 1
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL,
d129 1
a129 1
    {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
d132 3
a134 4
    {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.color),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-outlineoffset", (char *) NULL, (char *) NULL,
d137 3
a139 4
    {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, outline.stipple),
	TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-smooth", (char *) NULL, (char *) NULL,
d142 1
a142 1
    {TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,
d144 7
a150 8
    {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
	&stateOption},
    {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
	(char *) NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK},
    {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
	(char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
d153 1
a153 2
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
	(char *) NULL, 0, 0}
d157 1
a157 1
 * Prototypes for procedures defined in this file:
d160 3
a162 3
static void		ComputePolygonBbox _ANSI_ARGS_((Tk_Canvas canvas,
			    PolygonItem *polyPtr));
static int		ConfigurePolygon _ANSI_ARGS_((Tcl_Interp *interp,
d164 2
a165 2
			    Tcl_Obj *CONST objv[], int flags));
static int		CreatePolygon _ANSI_ARGS_((Tcl_Interp *interp,
d167 4
a170 4
			    int objc, Tcl_Obj *CONST objv[]));
static void		DeletePolygon _ANSI_ARGS_((Tk_Canvas canvas,
			    Tk_Item *itemPtr,  Display *display));
static void		DisplayPolygon _ANSI_ARGS_((Tk_Canvas canvas,
d172 2
a173 2
			    int x, int y, int width, int height));
static int		GetPolygonIndex _ANSI_ARGS_((Tcl_Interp *interp,
d175 2
a176 2
			    Tcl_Obj *obj, int *indexPtr));
static int		PolygonCoords _ANSI_ARGS_((Tcl_Interp *interp,
d178 12
a189 12
			    int objc, Tcl_Obj *CONST objv[]));
static void		PolygonDeleteCoords _ANSI_ARGS_((Tk_Canvas canvas,
			    Tk_Item *itemPtr, int first, int last));
static void		PolygonInsert _ANSI_ARGS_((Tk_Canvas canvas,
			    Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj));
static int		PolygonToArea _ANSI_ARGS_((Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr));
static double		PolygonToPoint _ANSI_ARGS_((Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr));
static int		PolygonToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
static void		ScalePolygon _ANSI_ARGS_((Tk_Canvas canvas,
d191 3
a193 3
			    double scaleX, double scaleY));
static void		TranslatePolygon _ANSI_ARGS_((Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY));
d196 2
a197 2
 * The structures below defines the polygon item type by means
 * of procedures that can be invoked by generic item code.
d216 2
a217 2
    (Tk_ItemCursorProc *) NULL,		/* icursorProc */
    (Tk_ItemSelectionProc *) NULL,	/* selectionProc */
d220 1
a220 1
    (Tk_ItemType *) NULL,		/* nextPtr */
d224 3
a226 3
 * The definition below determines how large are static arrays
 * used to hold spline points (splines larger than this have to
 * have their arrays malloc-ed).
d236 1
a236 2
 *	This procedure is invoked to create a new polygon item in
 *	a canvas.
d239 3
a241 4
 *	A standard Tcl return value.  If an error occurred in
 *	creating the item, then an error message is left in
 *	the interp's result;  in this case itemPtr is
 *	left uninitialized, so it can be safely freed by the
d251 7
a257 7
CreatePolygon(interp, canvas, itemPtr, objc, objv)
    Tcl_Interp *interp;			/* Interpreter for error reporting. */
    Tk_Canvas canvas;			/* Canvas to hold new item. */
    Tk_Item *itemPtr;			/* Record to hold new item;  header
					 * has been initialized by caller. */
    int objc;				/* Number of arguments in objv. */
    Tcl_Obj *CONST objv[];		/* Arguments describing polygon. */
d267 2
a268 2
     * Carry out initialization that is needed in order to clean
     * up after errors during the the remainder of this procedure.
d286 1
a286 1
    polyPtr->smooth = (Tk_SmoothMethod *) NULL;
d291 3
a293 3
     * Count the number of points and then parse them into a point
     * array.  Leading arguments are assumed to be points if they
     * start with a digit or a minus sign followed by a digit.
d311 1
a311 1
    error:
d321 2
a322 3
 *	This procedure is invoked to process the "coords" widget
 *	command on polygons.  See the user documentation for details
 *	on what it does.
d334 7
a340 9
PolygonCoords(interp, canvas, itemPtr, objc, objv)
    Tcl_Interp *interp;			/* Used for error reporting. */
    Tk_Canvas canvas;			/* Canvas containing item. */
    Tk_Item *itemPtr;			/* Item whose coordinates are to be
					 * read or modified. */
    int objc;				/* Number of coordinates supplied in
					 * objv. */
    Tcl_Obj *CONST objv[];		/* Array of coordinates: x1, y1,
					 * x2, y2, ... */
d347 2
a348 2
	 * Print the coords used to create the polygon.  If we auto
	 * closed the polygon then we don't report the last point.
d350 1
d352 1
d368 1
d381 2
a382 2
	     * One extra point gets allocated here, because we always
	     * add another point to close the polygon.
d401 1
a401 1
    
d419 2
a420 2
 *	This procedure is invoked to configure various aspects
 *	of a polygon item such as its background color.
d423 2
a424 2
 *	A standard Tcl result code.  If an error occurs, then
 *	an error message is left in the interp's result.
d427 2
a428 2
 *	Configuration information, such as colors and stipple
 *	patterns, may be set for itemPtr.
d434 7
a440 7
ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    Tk_Canvas canvas;		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr;		/* Polygon item to reconfigure. */
    int objc;			/* Number of elements in objv.  */
    Tcl_Obj *CONST objv[];	/* Arguments describing things to configure. */
    int flags;			/* Flags to pass to Tk_ConfigureWidget. */
d458 2
a459 2
     * A few of the options require additional processing, such as
     * graphics contexts.
d551 2
a552 2
 *	This procedure is called to clean up the data structure
 *	associated with a polygon item.
d564 4
a567 5
DeletePolygon(canvas, itemPtr, display)
    Tk_Canvas canvas;			/* Info about overall canvas widget. */
    Tk_Item *itemPtr;			/* Item that is being deleted. */
    Display *display;			/* Display containing window for
					 * canvas. */
d603 2
a604 2
 *	This procedure is invoked to compute the bounding box of
 *	all the pixels that may be drawn as part of a polygon.
d610 1
a610 2
 *	The fields x1, y1, x2, and y2 are updated in the header
 *	for itemPtr.
d616 3
a618 4
ComputePolygonBbox(canvas, polyPtr)
    Tk_Canvas canvas;			/* Canvas that contains item. */
    PolygonItem *polyPtr;		/* Item whose bbox is to be
					 * recomputed. */
d650 5
a654 6
     * Compute the bounding box of all the points in the polygon,
     * then expand in all directions by the outline's width to take
     * care of butting or rounded corners and projecting or
     * rounded caps.  This expansion is an overestimate (worst-case
     * is square root of two over two) but it's simple.  Don't do
     * anything special for curves.  This causes an additional
d700 1
d736 2
a737 2
	 * Compute the locations of the two miter vertex points and add
	 * those into the bounding box.
d743 1
d754 2
a755 3
	    for (i = polyPtr->numPoints ; i >= 3;
		    i--, coordPtr += 2) {
    
d767 2
a768 2
     * Add one more pixel of fudge factor just to be safe (e.g.
     * X may round differently than we do).
d782 2
a783 2
 *	This procedure is invoked to convert a polygon to screen
 *	coordinates and display it using a particular GC.
d789 2
a790 2
 *	ItemPtr is drawn in drawable using the transformation
 *	information in canvas.
d796 13
a808 14
TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC)
    Tk_Canvas canvas;			/* Canvas whose coordinate system
					 * is to be used for drawing. */
    double *coordPtr;			/* Array of coordinates for polygon:
					 * x1, y1, x2, y2, .... */
    int numPoints;			/* Twice this many coordinates are
					 * present at *coordPtr. */
    Display *display;			/* Display on which to draw polygon. */
    Drawable drawable;			/* Pixmap or window in which to draw
					 * polygon. */
    GC gc;				/* Graphics context for drawing. */
    GC outlineGC;			/* If not None, use this to draw an
					 * outline around the polygon after
					 * filling it. */
d816 3
a818 3
     * Build up an array of points in screen coordinates.  Use a
     * static array unless the polygon has an enormous number of points;
     * in this case, dynamically allocate an array.
d827 1
a827 1
    for (i = 0, pPtr = pointPtr; i < numPoints; i += 1, coordPtr += 2, pPtr++) {
d855 1
a855 2
 *	This procedure is invoked to draw a polygon item in a given
 *	drawable.
d861 2
a862 2
 *	ItemPtr is drawn in drawable using the transformation
 *	information in canvas.
d868 8
a875 8
DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
    Tk_Canvas canvas;			/* Canvas that contains item. */
    Tk_Item *itemPtr;			/* Item to be displayed. */
    Display *display;			/* Display on which to draw item. */
    Drawable drawable;			/* Pixmap or window in which to draw
					 * item. */
    int x, y, width, height;		/* Describes region of canvas that
					 * must be redisplayed (not used). */
d888 1
a888 1
    if(state == TK_STATE_NULL) {
d906 1
d908 2
a909 3
     * If we're stippling then modify the stipple offset in the GC.  Be
     * sure to reset the offset when done, since the GC is supposed to be
     * read-only.
d916 1
d941 1
d960 2
a961 2
	 * This is a smoothed polygon.  Display using a set of generated
	 * spline points rather than the original points.
d964 2
a965 3
	numPoints = polyPtr->smooth->coordProc(canvas, (double *) NULL,
		polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
		(double *) NULL);
d973 1
a973 2
		polyPtr->numPoints, polyPtr->splineSteps, pointPtr,
		(double *) NULL);
d1009 6
a1014 6
PolygonInsert(canvas, itemPtr, beforeThis, obj)
    Tk_Canvas canvas;		/* Canvas containing text item. */
    Tk_Item *itemPtr;		/* Line item to be modified. */
    int beforeThis;		/* Index before which new coordinates
				 * are to be inserted. */
    Tcl_Obj *obj;		/* New coordinates to be inserted. */
d1026 1
a1026 1
    if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &objc, &objv) != TCL_OK)
d1031 6
a1036 2
    while(beforeThis>length) beforeThis-=length;
    while(beforeThis<0) beforeThis+=length;
d1042 1
a1042 2
	if (Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,objv[i],
		new+(i+beforeThis))!=TCL_OK) {
d1048 1
a1048 1
    for(i=beforeThis; i<length; i++) {
d1051 4
a1054 2
    if(polyPtr->coordPtr) ckfree((char *) polyPtr->coordPtr);
    length+=objc;
d1059 2
a1060 2
     * Close the polygon if it isn't already closed, or remove autoclosing
     * if the user's coordinates are now closed.
d1068 1
a1068 2
    }
    else {
d1079 6
a1084 6
	 * This is some optimizing code that will result that only the part
	 * of the polygon that changed (and the objects that are overlapping
	 * with that part) need to be redrawn. A special flag is set that
	 * instructs the general canvas code not to redraw the whole
	 * object. If this flag is not set, the canvas will do the redrawing,
	 * otherwise I have to do it here.
d1086 1
d1092 4
a1095 5
	 * The header elements that normally are used for the
	 * bounding box, are now used to calculate the bounding
	 * box for only the part that has to be redrawn. That
	 * doesn't matter, because afterwards the bounding
	 * box has to be re-calculated anyway.
d1101 17
a1117 8
	if(polyPtr->smooth) {
	    beforeThis-=2; objc+=4;
	} /* be carefull; beforeThis could now be negative */
	for(i=beforeThis; i<beforeThis+objc; i+=2) {
		j=i;
		if(j<0) j+=length;
		if(j>=length) j-=length;
		TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
d1121 3
a1123 3
		if (polyPtr->outline.activeWidth>width) {
		    width = polyPtr->outline.activeWidth;
		}
d1125 3
a1127 3
		if (polyPtr->outline.disabledWidth>0.0) {
		    width = polyPtr->outline.disabledWidth;
		}
d1132 1
a1132 2
		itemPtr->x1, itemPtr->y1,
		itemPtr->x2, itemPtr->y2);
d1149 2
a1150 2
 *	Characters between "first" and "last", inclusive, get
 *	deleted from itemPtr.
d1156 5
a1160 5
PolygonDeleteCoords(canvas, itemPtr, first, last)
    Tk_Canvas canvas;		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr;		/* Item in which to delete characters. */
    int first;			/* Index of first character to delete. */
    int last;			/* Index of last character to delete. */
d1166 12
a1177 4
    while(first>=length) first-=length;
    while(first<0)	 first+=length;
    while(last>=length)	 last-=length;
    while(last<0)	 last+=length;
d1183 3
a1185 1
    if(count<=0) count +=length;
d1187 1
a1187 1
    if(count >= length) {
d1189 1
a1189 1
	if(polyPtr->coordPtr != NULL) {
d1196 1
a1196 1
    if(last>=first) {
d1216 2
a1217 2
 *	Computes the distance from a given point to a given
 *	polygon, in canvas units.
d1220 4
a1223 4
 *	The return value is 0 if the point whose x and y coordinates
 *	are pointPtr[0] and pointPtr[1] is inside the polygon.  If the
 *	point isn't inside the polygon then the return value is the
 *	distance from the point to the polygon.
d1233 4
a1236 4
PolygonToPoint(canvas, itemPtr, pointPtr)
    Tk_Canvas canvas;		/* Canvas containing item. */
    Tk_Item *itemPtr;		/* Item to check against point. */
    double *pointPtr;		/* Pointer to x and y coordinates. */
d1245 3
a1247 3
    int changedMiterToBevel;	/* Non-zero means that a mitered corner
				 * had to be treated as beveled after all
				 * because the angle was < 11 degrees. */
d1253 1
a1253 1
    if(state == TK_STATE_NULL) {
d1274 3
a1276 3
	numPoints = polyPtr->smooth->coordProc(canvas, (double *) NULL,
		polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
		(double *) NULL);
d1284 1
a1284 1
		polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
d1305 3
a1307 1
    if ((polyPtr->outline.gc == None) || (width <= 1)) goto donepoint;
d1310 4
a1313 4
     * The overall idea is to iterate through all of the edges of
     * the line, computing a polygon for each edge and testing the
     * point against that polygon.  In addition, there are additional
     * tests to deal with rounded joints and caps.
a1318 1

d1320 2
a1321 2
	 * If rounding is done around the first point then compute
	 * the distance between the point and the point.
d1336 3
a1338 3
	 * Compute the polygonal shape corresponding to this edge,
	 * consisting of two points for the first point of the edge
	 * and two points for the last point of the edge.
d1354 4
a1357 4
	     * If this line uses beveled joints, then check the distance
	     * to a polygon comprising the last two points of the previous
	     * polygon and the first two from this polygon;  this checks
	     * the wedges that fill the mitered joint.
d1380 2
a1381 2
		TkGetButtPoints(coordPtr, coordPtr+2, (double) width,
			0, poly+4, poly+6);
d1398 1
a1398 1
    donepoint:
d1410 2
a1411 3
 *	This procedure is called to determine whether an item
 *	lies entirely inside, entirely outside, or overlapping
 *	a given rectangular area.
d1414 3
a1416 3
 *	-1 is returned if the item is entirely outside the area
 *	given by rectPtr, 0 if it overlaps, and 1 if it is entirely
 *	inside the given area.
d1426 6
a1431 6
PolygonToArea(canvas, itemPtr, rectPtr)
    Tk_Canvas canvas;		/* Canvas containing item. */
    Tk_Item *itemPtr;		/* Item to check against polygon. */
    double *rectPtr;		/* Pointer to array of four coordinates
				 * (x1, y1, x2, y2) describing rectangular
				 * area.  */
d1439 8
a1446 9
    int changedMiterToBevel;	/* Non-zero means that a mitered corner
				 * had to be treated as beveled after all
				 * because the angle was < 11 degrees. */
    int inside;			/* Tentative guess about what to return,
				 * based on all points seen so far:  one
				 * means everything seen so far was
				 * inside the area;  -1 means everything
				 * was outside the area.  0 means overlap
				 * has been found. */ 
d1450 1
a1450 1
    if(state == TK_STATE_NULL) {
d1472 1
d1479 1
d1486 2
a1487 3
	numPoints = polyPtr->smooth->coordProc(canvas, (double *) NULL,
		polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
		(double *) NULL);
d1491 2
a1492 2
	    polyPoints = (double *) ckalloc((unsigned)
		    (2*numPoints*sizeof(double)));
d1495 1
a1495 2
		polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
		polyPoints);
d1502 3
a1504 3
     * Simple test to see if we are in the polygon.  Polygons are
     * different from othe canvas items in that they register points
     * being inside even if it isn't filled.
d1506 1
d1508 3
a1510 1
    if (inside==0) goto donearea;
d1512 3
a1514 1
    if (polyPtr->outline.gc == None) goto donearea ;
d1517 3
a1519 4
     * Iterate through all of the edges of the line, computing a polygon
     * for each edge and testing the area against that polygon.  In
     * addition, there are additional tests to deal with rounded joints
     * and caps.
a1524 1
 
d1526 2
a1527 3
	 * If rounding is done around the first point of the edge
	 * then test a circular region around the point with the
	 * area.
d1542 3
a1544 3
	 * Compute the polygonal shape corresponding to this edge,
	 * consisting of two points for the first point of the edge
	 * and two points for the last point of the edge.
d1548 1
a1548 2
	    TkGetButtPoints(coordPtr+2, coordPtr, width,
		    0, poly, poly+2);
d1555 1
a1555 2
	    TkGetButtPoints(coordPtr+2, coordPtr, width, 0,
		    poly, poly+2);
d1558 4
a1561 4
	     * If the last joint was beveled, then also check a
	     * polygon comprising the last two points of the previous
	     * polygon and the first two from this polygon;  this checks
	     * the wedges that fill the beveled joint.
d1575 1
a1575 2
	    TkGetButtPoints(coordPtr, coordPtr+2, width,
		    0, poly+4, poly+6);
d1580 1
a1580 2
		TkGetButtPoints(coordPtr, coordPtr+2, width,
			0, poly+4, poly+6);
d1583 1
a1583 2
	    TkGetButtPoints(coordPtr, coordPtr+2, width, 0,
		    poly+4, poly+6);
d1593 1
a1593 1
    donearea:
d1605 1
a1605 1
 *	This procedure is invoked to rescale a polygon item.
d1611 2
a1612 3
 *	The polygon referred to by itemPtr is rescaled so that the
 *	following transformation is applied to all point
 *	coordinates:
d1620 7
a1626 6
ScalePolygon(canvas, itemPtr, originX, originY, scaleX, scaleY)
    Tk_Canvas canvas;			/* Canvas containing polygon. */
    Tk_Item *itemPtr;			/* Polygon to be scaled. */
    double originX, originY;		/* Origin about which to scale rect. */
    double scaleX;			/* Amount to scale in X direction. */
    double scaleY;			/* Amount to scale in Y direction. */
d1645 2
a1646 2
 *	Parse an index into a polygon item and return either its value
 *	or an error.
d1649 3
a1651 4
 *	A standard Tcl result.  If all went well, then *indexPtr is
 *	filled in with the index (into itemPtr) corresponding to
 *	string.  Otherwise an error message is left in
 *	interp->result.
d1660 4
a1663 4
GetPolygonIndex(interp, canvas, itemPtr, obj, indexPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tk_Canvas canvas;		/* Canvas containing item. */
    Tk_Item *itemPtr;		/* Item for which the index is being
d1665 3
a1667 3
    Tcl_Obj *obj;		/* Specification of a particular coord
				 * in itemPtr's line. */
    int *indexPtr;		/* Where to store converted index. */
a1676 2
	    badIndex:

d1678 2
a1679 2
	     * Some of the paths here leave messages in interp->result,
	     * so we have to clear it out before storing our own message.
d1682 3
a1684 3
	    Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
	    Tcl_AppendResult(interp, "bad index \"", string, "\"",
		    (char *) NULL);
d1715 1
d1738 1
a1738 2
 *	This procedure is called to move a polygon by a given
 *	amount.
d1744 2
a1745 3
 *	The position of the polygon is offset by (xDelta, yDelta),
 *	and the bounding box is updated in the generic part of the
 *	item structure.
d1751 5
a1755 5
TranslatePolygon(canvas, itemPtr, deltaX, deltaY)
    Tk_Canvas canvas;			/* Canvas containing item. */
    Tk_Item *itemPtr;			/* Item that is being moved. */
    double deltaX, deltaY;		/* Amount by which item is to be
					 * moved. */
d1774 1
a1774 2
 *	This procedure is called to generate Postscript for
 *	polygon items.
d1777 4
a1780 5
 *	The return value is a standard Tcl result.  If an error
 *	occurs in generating Postscript then an error message is
 *	left in the interp's result, replacing whatever used
 *	to be there.  If no error occurs, then Postscript for the
 *	item is appended to the result.
d1789 7
a1795 9
PolygonToPostscript(interp, canvas, itemPtr, prepass)
    Tcl_Interp *interp;			/* Leave Postscript or error message
					 * here. */
    Tk_Canvas canvas;			/* Information about overall canvas. */
    Tk_Item *itemPtr;			/* Item for which Postscript is
					 * wanted. */
    int prepass;			/* 1 means this is a prepass to
					 * collect font information;  0 means
					 * final Postscript is being created. */
d1861 1
a1861 1
		" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", (char *) NULL);
d1866 1
a1866 1
	    Tcl_AppendResult(interp, "clip ", (char *) NULL);
d1871 1
a1871 1
	    Tcl_AppendResult(interp, "fill\n", (char *) NULL);
d1892 2
a1893 3
	    Tcl_AppendResult(interp, "eoclip ", (char *) NULL);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple)
		    != TCL_OK) {
d1897 1
a1897 1
		Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
d1900 1
a1900 1
	    Tcl_AppendResult(interp, "eofill\n", (char *) NULL);
a1908 1

d1911 1
a1911 1
		polyPtr->numPoints);
d1914 1
a1914 1
		polyPtr->numPoints, polyPtr->splineSteps);
d1924 1
a1924 2
	Tcl_AppendResult(interp, style," setlinejoin 1 setlinecap\n",
		(char *) NULL);
d1932 8
@


1.12
log
@	* generic/tk3d.c:	All uses of 'panic' (the macro) changed
	* generic/tkBind.c:	to 'Tcl_Panic' (the function).  The #define
	* generic/tkBitmap.c:	of panic in tcl.h clearly states it is
	* generic/tkCanvArc.c:	deprecated in the comments.
	* generic/tkCanvBmap.c: [Tcl Patch 865264]
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkColor.c:
	* generic/tkConfig.c:
	* generic/tkCursor.c:
	* generic/tkError.c:
	* generic/tkEvent.c:
	* generic/tkFocus.c:
	* generic/tkFont.c:
	* generic/tkFrame.c:
	* generic/tkGC.c:
	* generic/tkGrid.c:
	* generic/tkImgBmap.c:
	* generic/tkImgPhoto.c:
	* generic/tkImgUtil.c:
	* generic/tkMenu.c:
	* generic/tkObj.c:
	* generic/tkPack.c:
	* generic/tkPlace.c:
	* generic/tkRectOval.c:
	* generic/tkSelect.c:
	* generic/tkText.c:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextIndex.c:
	* generic/tkTextMark.c:
	* generic/tkTextWind.c:
	* generic/tkVisual.c:
	* generic/tkWindow.c:
	* mac/tkMacAppInit.c:
	* mac/tkMacAppearanceStubs.c:
	* mac/tkMacButton.c:
	* mac/tkMacDraw.c:
	* mac/tkMacEmbed.c:
	* mac/tkMacFont.c:
	* mac/tkMacInit.c:
	* mac/tkMacMenus.c:
	* mac/tkMacPort.h:
	* mac/tkMacSubwindows.c:
	* mac/tkMacWm.c:
	* mac/tkMacXStubs.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXPort.h:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnix3d.c:
	* unix/tkUnixColor.c:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixEvent.c:
	* unix/tkUnixFocus.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixSelect.c:
	* unix/tkUnixSend.c:
	* unix/tkUnixWm.c:
	* win/tkWin3d.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinDialog.c:
	* win/tkWinDraw.c:
	* win/tkWinEmbed.c:
	* win/tkWinFont.c:
	* win/tkWinPixmap.c:
	* win/tkWinPointer.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.11 2003/05/11 00:52:41 hobbs Exp $
d1665 2
a1666 2
    size_t length;
    char *string = Tcl_GetStringFromObj(obj, (int *) &length);
d1669 1
a1669 1
	if (strncmp(string, "end", length) == 0) {
@


1.11
log
@	* generic/tkCanvPoly.c (PolygonToPostscript):
	* tests/canvPs.test: correct crash when generating postscript for
	a single-line polygon (point) with no color. [Bug #734498] (wilm)
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.10 2003/02/09 07:48:22 hobbs Exp $
d270 1
a270 1
	panic("canvas did not pass any coords\n");
@


1.10
log
@	* generic/tkCanvArc.c (CreateArc):       Rework canvas create item
	* generic/tkCanvBmap.c (CreateBitmap):   type coords handling to be
	* generic/tkCanvImg.c (CreateImage):     consistent across types
	* generic/tkCanvPoly.c (CreatePolygon):  and not pass empty coords
	* generic/tkCanvLine.c (CreateLine):     to item creation procs.
	* generic/tkCanvText.c (CreateText):
	* generic/tkCanvWind.c (CreateWinItem):
	* generic/tkCanvas.c (CanvasWidgetCmd CANV_CREATE):
	* generic/tkRectOval.c (CreateRectOval):
	* tests/canvRect.test:
	* tests/canvText.test:
	* tests/canvas.test:
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.9 2002/08/05 04:30:38 dgp Exp $
d1855 4
d1864 1
a1864 2
	if (Tk_CanvasPsColor(interp, canvas, color)
		!= TCL_OK) {
@


1.10.2.1
log
@	* generic/tkCanvPoly.c (PolygonToPostscript):
	* tests/canvPs.test: correct crash when generating postscript for
	a single-line polygon (point) with no color. [Bug #734498] (wilm)
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.11 2003/05/11 00:52:41 hobbs Exp $
a1854 4
	if (color == NULL) {
	    return TCL_OK;
	}

d1860 2
a1861 1
	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
@


1.10.2.2
log
@Fix [Bug 1252702]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.10.2.1 2003/05/11 00:57:09 hobbs Exp $
d1665 2
a1666 2
    int length;
    char *string = Tcl_GetStringFromObj(obj, &length);
d1669 1
a1669 1
	if (strncmp(string, "end", (unsigned) length) == 0) {
@


1.10.2.3
log
@	* changes: updates for 8.4.14 release.

	* macosx/tkMacOSXDraw.c: fix numerous issues in CG and QD drawing procs
	so that they now match X11 drawing much more closely [Bug 1558051];
	use Tiger ellipse drawing API when available; fix comments & whitespace.

	* macosx/tkMacOSXInit.c: set default linewidth limit for CG
	antialiasing to 0 as thin horizontal/vertical lines look good now.

	* generic/tkCanvLine.c (ConfigureLine):     on TkAqua, pass outline
	* generic/tkCanvPoly.c (ConfigurePolygon):  linewidth in gc even for
	* generic/tkRectOval.c (ConfigureRectOval): fills (as it controls AA).
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.10.2.2 2005/08/11 12:17:09 dkf Exp $
a531 9
#ifdef MAC_OSX_TK
	/*
	 * Mac OS X CG drawing needs access to the outline linewidth
	 * even for fills (as linewidth controls antialiasing).
	 */
	gcValues.line_width = polyPtr->outline.gc != None ? 
		polyPtr->outline.gc->line_width : 0;
	mask |= GCLineWidth;
#endif
@


1.9
log
@Applied companion patch for Tcl Patch 585105,
updating Tk to use Tcl 8.4's fully CONST-ified
interface, and fully CONSTifying Tk at the
same time.

This patch includes purging Tk of its last
direct access to interp->result.  [Bug 589853]

The substantial changes include copying
event sequence strings into Tcl_DStrings
in tkBind.c, and copying [text] indices into
Tcl_DStrings because parsing them involved
overwriting them.  If this causes performance
trouble, that can be resolved by further
converting them to Tcl_Obj's.

The #defines USE_NON_CONST and USE_COMPAT_CONST
have the same effect for Tk as they do for Tcl.
(They actually change tcl.h)
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.8 2001/07/04 00:40:11 hobbs Exp $
d269 4
d375 4
a378 3
	Tcl_AppendResult(interp,
		"odd number of coordinates specified for polygon",
		(char *) NULL);
@


1.8
log
@	* tests/canvas.test:
	* generic/tkCanvPoly.c (PolygonToArea): Added patch that respects
	the polygon difference of including points in the polygon even
	when fill is empty.  [Bug #226357]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.7 2001/07/03 06:03:44 hobbs Exp $
d454 2
a455 2
    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, (char **) objv,
	    (char *) polyPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
@


1.8.2.1
log
@merged with trunk at tag macosx-8-4-merge-2002-08-20-trunk
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d454 2
a455 2
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (CONST char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) {
@


1.7
log
@	* generic/tkCanvArc.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkRectOval.c: corrected argument handling in
	Create<Item> functions that could lead to ABRs or FMRs and
	corrected names of argc/argv to objc/objv.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.6 2000/06/03 08:38:12 hobbs Exp $
d1487 7
a1493 11
    if (polyPtr->fillGC != None) {
	inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
	if (inside==0) goto donearea;
    } else {
	if ((polyPoints[0] >= rectPtr[0])
		&& (polyPoints[0] <= rectPtr[2])
		&& (polyPoints[1] >= rectPtr[1])
		&& (polyPoints[1] <= rectPtr[3])) {
	    inside = 1;
	}
    }
a1495 1

@


1.6
log
@	* canvas.test: added test for 5783.
	* generic/tkCanvPoly.c (DisplayPolygon): added checks for the
	polygon fillGC not being empty to prevent segfault. [Bug: 5783]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.5 2000/02/01 11:41:09 hobbs Exp $
d168 2
a169 2
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *CONST argv[], int flags));
d172 1
a172 1
			    int argc, Tcl_Obj *CONST argv[]));
d183 1
a183 1
			    int argc, Tcl_Obj *CONST argv[]));
d258 1
a258 1
CreatePolygon(interp, canvas, itemPtr, argc, argv)
d263 2
a264 2
    int argc;				/* Number of arguments in argv. */
    Tcl_Obj *CONST argv[];		/* Arguments describing polygon. */
d299 3
a301 4
    for (i = 0; i < argc; i++) {
	char *arg = Tcl_GetStringFromObj((Tcl_Obj *) argv[i], NULL);
	if ((arg[0] == '-') && (arg[1] >= 'a')
		&& (arg[1] <= 'z')) {
d305 1
a305 1
    if (i && PolygonCoords(interp, canvas, itemPtr, i, argv) != TCL_OK) {
d309 1
a309 1
    if (ConfigurePolygon(interp, canvas, itemPtr, argc-i, argv+i, 0)
d338 1
a338 1
PolygonCoords(interp, canvas, itemPtr, argc, argv)
d343 3
a345 3
    int argc;				/* Number of coordinates supplied in
					 * argv. */
    Tcl_Obj *CONST argv[];		/* Array of coordinates: x1, y1,
d351 1
a351 1
    if (argc == 0) {
d364 3
a366 3
    if (argc == 1) {
	if (Tcl_ListObjGetElements(interp, argv[0], &argc,
		(Tcl_Obj ***) &argv) != TCL_OK) {
d370 1
a370 1
    if (argc & 1) {
d376 1
a376 1
	numPoints = argc/2;
d388 1
a388 1
		    (sizeof(double) * (argc+2)));
d391 2
a392 2
	for (i = argc-1; i >= 0; i--) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, argv[i],
d404 2
a405 2
	if (argc>2 && ((polyPtr->coordPtr[argc-2] != polyPtr->coordPtr[0])
		|| (polyPtr->coordPtr[argc-1] != polyPtr->coordPtr[1]))) {
d408 2
a409 2
	    polyPtr->coordPtr[argc] = polyPtr->coordPtr[0];
	    polyPtr->coordPtr[argc+1] = polyPtr->coordPtr[1];
d436 1
a436 1
ConfigurePolygon(interp, canvas, itemPtr, argc, argv, flags)
d440 2
a441 2
    int argc;			/* Number of elements in argv.  */
    Tcl_Obj *CONST argv[];	/* Arguments describing things to configure. */
d454 1
a454 1
    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv,
d1024 1
a1024 1
    int length, argc, i;
d1033 2
a1034 2
    if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &argc, &objv) != TCL_OK)
	    || !argc || argc&1) {
d1040 1
a1040 1
    new = (double *) ckalloc((unsigned)(sizeof(double) * (length + 2 + argc)));
d1044 1
a1044 1
    for (i=0; i<argc; i++) {
d1053 1
a1053 1
	new[i+argc] = polyPtr->coordPtr[i];
d1056 1
a1056 1
    length+=argc;
d1080 1
a1080 1
    if (((length-argc)>3) && (state != TK_STATE_HIDDEN)) {
d1103 1
a1103 1
	beforeThis-=2; argc+=4;
d1105 1
a1105 1
	    beforeThis-=2; argc+=4;
d1107 1
a1107 1
	for(i=beforeThis; i<beforeThis+argc; i+=2) {
@


1.6.2.1
log
@sync with head
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.8 2001/07/04 00:40:11 hobbs Exp $
d168 2
a169 2
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *CONST objv[], int flags));
d172 1
a172 1
			    int objc, Tcl_Obj *CONST objv[]));
d183 1
a183 1
			    int objc, Tcl_Obj *CONST objv[]));
d258 1
a258 1
CreatePolygon(interp, canvas, itemPtr, objc, objv)
d263 2
a264 2
    int objc;				/* Number of arguments in objv. */
    Tcl_Obj *CONST objv[];		/* Arguments describing polygon. */
d299 4
a302 3
    for (i = 0; i < objc; i++) {
	char *arg = Tcl_GetString(objv[i]);
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
d306 1
a306 1
    if (i && PolygonCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
d310 1
a310 1
    if (ConfigurePolygon(interp, canvas, itemPtr, objc-i, objv+i, 0)
d339 1
a339 1
PolygonCoords(interp, canvas, itemPtr, objc, objv)
d344 3
a346 3
    int objc;				/* Number of coordinates supplied in
					 * objv. */
    Tcl_Obj *CONST objv[];		/* Array of coordinates: x1, y1,
d352 1
a352 1
    if (objc == 0) {
d365 3
a367 3
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
d371 1
a371 1
    if (objc & 1) {
d377 1
a377 1
	numPoints = objc/2;
d389 1
a389 1
		    (sizeof(double) * (objc+2)));
d392 2
a393 2
	for (i = objc-1; i >= 0; i--) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
d405 2
a406 2
	if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0])
		|| (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) {
d409 2
a410 2
	    polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	    polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
d437 1
a437 1
ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
d441 2
a442 2
    int objc;			/* Number of elements in objv.  */
    Tcl_Obj *CONST objv[];	/* Arguments describing things to configure. */
d455 1
a455 1
    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, (char **) objv,
d1025 1
a1025 1
    int length, objc, i;
d1034 2
a1035 2
    if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
d1041 1
a1041 1
    new = (double *) ckalloc((unsigned)(sizeof(double) * (length + 2 + objc)));
d1045 1
a1045 1
    for (i=0; i<objc; i++) {
d1054 1
a1054 1
	new[i+objc] = polyPtr->coordPtr[i];
d1057 1
a1057 1
    length+=objc;
d1081 1
a1081 1
    if (((length-objc)>3) && (state != TK_STATE_HIDDEN)) {
d1104 1
a1104 1
	beforeThis-=2; objc+=4;
d1106 1
a1106 1
	    beforeThis-=2; objc+=4;
d1108 1
a1108 1
	for(i=beforeThis; i<beforeThis+objc; i+=2) {
d1488 11
a1498 7
    /*
     * Simple test to see if we are in the polygon.  Polygons are
     * different from othe canvas items in that they register points
     * being inside even if it isn't filled.
     */
    inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
    if (inside==0) goto donearea;
d1501 1
@


1.6.4.1
log
@        * Merged in updates from HEAD branch.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.7 2001/07/03 06:03:44 hobbs Exp $
d168 2
a169 2
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *CONST objv[], int flags));
d172 1
a172 1
			    int objc, Tcl_Obj *CONST objv[]));
d183 1
a183 1
			    int objc, Tcl_Obj *CONST objv[]));
d258 1
a258 1
CreatePolygon(interp, canvas, itemPtr, objc, objv)
d263 2
a264 2
    int objc;				/* Number of arguments in objv. */
    Tcl_Obj *CONST objv[];		/* Arguments describing polygon. */
d299 4
a302 3
    for (i = 0; i < objc; i++) {
	char *arg = Tcl_GetString(objv[i]);
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
d306 1
a306 1
    if (i && PolygonCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
d310 1
a310 1
    if (ConfigurePolygon(interp, canvas, itemPtr, objc-i, objv+i, 0)
d339 1
a339 1
PolygonCoords(interp, canvas, itemPtr, objc, objv)
d344 3
a346 3
    int objc;				/* Number of coordinates supplied in
					 * objv. */
    Tcl_Obj *CONST objv[];		/* Array of coordinates: x1, y1,
d352 1
a352 1
    if (objc == 0) {
d365 3
a367 3
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
d371 1
a371 1
    if (objc & 1) {
d377 1
a377 1
	numPoints = objc/2;
d389 1
a389 1
		    (sizeof(double) * (objc+2)));
d392 2
a393 2
	for (i = objc-1; i >= 0; i--) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
d405 2
a406 2
	if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0])
		|| (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) {
d409 2
a410 2
	    polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	    polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
d437 1
a437 1
ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
d441 2
a442 2
    int objc;			/* Number of elements in objv.  */
    Tcl_Obj *CONST objv[];	/* Arguments describing things to configure. */
d455 1
a455 1
    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, (char **) objv,
d1025 1
a1025 1
    int length, objc, i;
d1034 2
a1035 2
    if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
d1041 1
a1041 1
    new = (double *) ckalloc((unsigned)(sizeof(double) * (length + 2 + objc)));
d1045 1
a1045 1
    for (i=0; i<objc; i++) {
d1054 1
a1054 1
	new[i+objc] = polyPtr->coordPtr[i];
d1057 1
a1057 1
    length+=objc;
d1081 1
a1081 1
    if (((length-objc)>3) && (state != TK_STATE_HIDDEN)) {
d1104 1
a1104 1
	beforeThis-=2; objc+=4;
d1106 1
a1106 1
	    beforeThis-=2; objc+=4;
d1108 1
a1108 1
	for(i=beforeThis; i<beforeThis+objc; i+=2) {
@


1.6.4.2
log
@	* Correction in merge from HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.6.4.1 2001/07/03 20:01:07 dgp Exp $
d1487 12
a1498 8
    /*
     * Simple test to see if we are in the polygon.  Polygons are
     * different from othe canvas items in that they register points
     * being inside even if it isn't filled.
     */
    inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
    if (inside==0) goto donearea;
	    
@


1.6.4.3
log
@	* Correction to merge from HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.6.4.2 2001/07/18 16:15:27 dgp Exp $
d1494 2
a1496 1
    if (polyPtr->outline.gc == None) goto donearea ;
@


1.5
log
@	* generic/tkRectOval.c (ConfigureRectOval):
	* generic/tkCanvLine.c (ConfigureLine):
	* generic/tkCanvPoly.c (ConfigurePoly):
	* generic/tkCanvArc.c (Configure/DisplayArc): fixed handling for
	negative dash values [Bug: 4104]

	* generic/tkScale.c (TkRoundToResolution): fixed incorrect
	assumption that (N+1)*delta = N*delta + delta with floating point
	math [Bug: 3689, 4099]
	(DestroyScale) Fixed check for cancelling TkpDisplayScale (was
	REDRAW_ALL, is now REDRAW_PENDING)
@
text
@d8 1
d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.4 1999/12/14 06:52:26 hobbs Exp $
d920 1
a920 1
    if (stipple != None) {
d995 1
a995 1
    if (stipple != None) {
@


1.5.2.1
log
@	* BACKPORTED FROM 8.4 (HEAD) BRANCH:

	* tests/button.test:
	* generic/tkButton.c: Added -activeforeground, -activebackground
	for labels, for the -state option.

	* doc/label.n: Added -disabledforeground to list of options [Bug:
	6053].

	* tests/focus.test (focusSetupAlt): removed wm withdraw from proc
	as it would cause a hang for tkwait visibility

	* tests/menu.test:
	* generic/tk3d.c:
	* generic/tkColor.c:
	* generic/tkCursor.c: corrected handling of 3DBorder, Cursor and
	Color objects on multiple screens. [Bug: 5454]

	* generic/tkCursor.c: Added initialization for nextPtr field of
	TkCursor, patch from Nijtmans/Howlett.

	* canvas.test: added test for 5783.
	* generic/tkCanvPoly.c (DisplayPolygon): added checks for the
	polygon fillGC not being empty to prevent segfault. [Bug: 5783]

	* generic/tkImgGIF.c: Applied patch from Jan Nijtmans to fix a
	problem with the GIF writing code [Bug:	5823].
	* generic/tkImgGIF.c: Changed defines for GIF87a/GIF89a to be
	static char arrays with integer initialization, to address EBCIDIC
	vs. ASCII encoding issues and to handle compilers that don't deal
	with "\xAB" syntax for specifying hex values in strings.

	* generic/tkMenu.c (DeleteMenuCloneEntries): Applied fix from
	[Bug: 5275], which corrected a segfault-causing indexing problem
	when deleting entries from torn-off menus.

	* generic/tkPlace.c (Tk_PlaceCmd): reworked place master/slave
	table init'n to prevent seg fault when using place on multiple
	displays.

	* tests/text.test: Added tests for -regexp -nocase searches with
	backslash character classes.
	* tests/text.test: Added tests for searching when text is elided.
	* generic/tkText.c (TextSearchCmd): Text search did not work
	properly when -regexp and -nocase were used, in combination with
	backslash character classes represented by capital letters (ie,
	\W, \M); altered implementation of -regexp -nocase searches to use
	new regexp interfaces to fix this problem.  [Bug: 5988].
	* generic/tkText.c (TextSearchCmd): Text search was not returning
	the correct index when the search covered (but did not search)
	elided characters; corrected this by adjusting the match index by
	the number of elided characters preceeding the start of the match,
	just as is done with embedded windows, etc. [Bug: 5470].
	* generic/tkText.c (TextSearchCmd): Added a test for a NULL
	segment pointer when doing backwards searches for "" on an empty
	text widget. [Bug: 6007].

	* library/focus.tcl: fixed calling of takeFocus proc [Bug: 5372]

	* win/tkWinMenu.c (ReconfigureWindowsMenu): Added MF_GRAYED bit
	for disabled menu entries, to ensure that those which are drawn by
	the system are shown grayed (such as entries on menubars) [Bug: 4372].
	* win/tkWinMenu.c (ReconfigureWindowsMenu): Added code to add the
	MF_SEPARATOR bit for SEPARATOR_ENTRY menu items.  This causes
	separator entries on the system menu to be drawn correctly [Bug: 5451].
	* win/tkWinMenu.c (GetMenuSeparatorGeometry): Tweaked height
	requested for separator bars to be (linespace - (2*descent))
	instead of just (linespace); this makes the separator occupy a
	more correct amount of vertical space. [Bug: 5303].
@
text
@a7 1
 * Copyright (c) 1998-2000 Ajuba Solutions.
d12 1
a12 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.6 2000/06/03 08:38:12 hobbs Exp $
d919 1
a919 1
    if ((stipple != None) && (polyPtr->fillGC != None)) {
d994 1
a994 1
    if ((stipple != None) && (polyPtr->fillGC != None)) {
@


1.5.2.2
log
@	* generic/tkCanvArc.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkRectOval.c: corrected argument handling in
	Create<Item> functions that could lead to ABRs or FMRs and
	corrected names of argc/argv to objc/objv.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.7 2001/07/03 06:03:44 hobbs Exp $
d168 2
a169 2
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *CONST objv[], int flags));
d172 1
a172 1
			    int objc, Tcl_Obj *CONST objv[]));
d183 1
a183 1
			    int objc, Tcl_Obj *CONST objv[]));
d258 1
a258 1
CreatePolygon(interp, canvas, itemPtr, objc, objv)
d263 2
a264 2
    int objc;				/* Number of arguments in objv. */
    Tcl_Obj *CONST objv[];		/* Arguments describing polygon. */
d299 4
a302 3
    for (i = 0; i < objc; i++) {
	char *arg = Tcl_GetString(objv[i]);
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
d306 1
a306 1
    if (i && PolygonCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
d310 1
a310 1
    if (ConfigurePolygon(interp, canvas, itemPtr, objc-i, objv+i, 0)
d339 1
a339 1
PolygonCoords(interp, canvas, itemPtr, objc, objv)
d344 3
a346 3
    int objc;				/* Number of coordinates supplied in
					 * objv. */
    Tcl_Obj *CONST objv[];		/* Array of coordinates: x1, y1,
d352 1
a352 1
    if (objc == 0) {
d365 3
a367 3
    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
d371 1
a371 1
    if (objc & 1) {
d377 1
a377 1
	numPoints = objc/2;
d389 1
a389 1
		    (sizeof(double) * (objc+2)));
d392 2
a393 2
	for (i = objc-1; i >= 0; i--) {
	    if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i],
d405 2
a406 2
	if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0])
		|| (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) {
d409 2
a410 2
	    polyPtr->coordPtr[objc] = polyPtr->coordPtr[0];
	    polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1];
d437 1
a437 1
ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
d441 2
a442 2
    int objc;			/* Number of elements in objv.  */
    Tcl_Obj *CONST objv[];	/* Arguments describing things to configure. */
d455 1
a455 1
    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, (char **) objv,
d1025 1
a1025 1
    int length, objc, i;
d1034 2
a1035 2
    if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
d1041 1
a1041 1
    new = (double *) ckalloc((unsigned)(sizeof(double) * (length + 2 + objc)));
d1045 1
a1045 1
    for (i=0; i<objc; i++) {
d1054 1
a1054 1
	new[i+objc] = polyPtr->coordPtr[i];
d1057 1
a1057 1
    length+=objc;
d1081 1
a1081 1
    if (((length-objc)>3) && (state != TK_STATE_HIDDEN)) {
d1104 1
a1104 1
	beforeThis-=2; objc+=4;
d1106 1
a1106 1
	    beforeThis-=2; objc+=4;
d1108 1
a1108 1
	for(i=beforeThis; i<beforeThis+objc; i+=2) {
@


1.4
log
@	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkInt.decls: added XSetDashes and XWarpPointer
	* generic/tk.decls: added Tk_CreateSmoothMethod, and reserved
	two spots
	* generic/tk.h: added Tk_SmoothMethod struct,
	state item to canvas record, #defines for item state,
	support for using old char*-based canvas item C creation
	procedures with -DUSE_OLD_CANVAS,
	Tk_Dash, Tk_TSOffset (-offsets) & Tk_Outline structs and #defs,
	decls for dash, outline and postscript routines
	* generic/tkBind.c: added support for Quadruple clicks, and added
	the -warp option to 'event' with pointer warping routines
	* xlib/xgc.c:
	* generic/tkRectOval.c:
	* generic/tkCanvArc.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvPs.c:
	* generic/tkCanvText.c:
	* generic/tkCanvUtil.c:
	* generic/tkCanvWind.c:
	* generic/tkCanvas.c:
	* generic/tkCanvas.h: Canvas and items received overhaul to with
	the addition of the dash patch (Nijtmans, et al)  This includes
	objectification of the 'canvas' command, as well as support for
	(where appropriate) dashes in items, extended stipple support,
	state for all items, and postscript generation of images and
	windows.  See the new canvas man page for related docs.
	* generic/tkEntry.c: added entry widget validation, see entry.n
	* generic/tkEvent.c: on simulated events, ButtonPress should
	be matched with ButtonRelease to be correct
	* generic/tkFont.c: corrected possible null reference
	* generic/tkFrame.c: made frame a Tcl_Obj based command
	* generic/tkGet.c: added TkGetDoublePixels
	* generic/tkImage.c: bug fixes from Img patch and new
	Tk_PostscriptImage and Tk_SetTSOrigin functions
	* generic/tkImgBmap.c: new ImgBmapPostscript function
	* generic/tkImgPhoto.c: new Tk_CreatePhotoOption, Tk_DitherPhoto
	* generic/tkInt.h: declarations for some new functions
	* generic/tkMessage.c: reworked relief drawing
	* generic/tkOldConfig.c: added TK_CONFIG_OBJS so old style
	ConfigureWidget calls can pass in Tcl_Obj arrays
	* generic/tkScrollbar.c:
	* generic/tkScrollbar.h: made -orient use an option table
	* generic/tkText.c:
	* generic/tkText.h: made -wrap and -state use option tables
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextMark.c:
	* generic/tkTextTag.c:
	* generic/tkTextWind.c: added support for -elide and -state hidden
	* generic/tkTrig.c: changed TkMakeBezierCurve to support returning
	the upper limit of points needed for spline
	* generic/tkUtil.c: new option table parsing routines
	* generic/tkWindow.c: init'ing of warp stuff, mouseButtonState
@
text
@d12 1
a12 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.3 1999/04/16 01:51:11 stanton Exp $
d467 1
a467 1
	    polyPtr->outline.activeDash.number > 0 ||
@


1.3
log
@* Merged 8.1 branch into the main trunk
@
text
@d12 1
a12 1
 * RCS: @@(#) $Id$
d18 1
d27 2
a28 1
    int numPoints;		/* Number of points in polygon (always >= 3).
d36 2
a37 3
    int width;			/* Width of outline. */
    XColor *outlineColor;	/* Color for outline. */
    GC outlineGC;		/* Graphics context for drawing outline. */
d39 2
d42 2
d45 1
a45 1
    int smooth;			/* Non-zero means draw shape smoothed (i.e.
d56 10
a65 1
static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
d68 13
d83 42
d127 5
d133 11
a143 3
	(char *) NULL, Tk_Offset(PolygonItem, outlineColor), TK_CONFIG_NULL_OK},
    {TK_CONFIG_BOOLEAN, "-smooth", (char *) NULL, (char *) NULL,
	"0", Tk_Offset(PolygonItem, smooth), TK_CONFIG_DONT_SET_DEFAULT},
d146 3
d153 3
a155 2
    {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
	"1", Tk_Offset(PolygonItem, width), TK_CONFIG_DONT_SET_DEFAULT},
d168 1
a168 1
			    char **argv, int flags));
d171 1
a171 1
			    int argc, char **argv));
d177 3
d182 5
a186 1
			    int argc, char **argv));
d213 1
a213 1
    0,					/* alwaysRedraw */
d219 1
a219 1
    (Tk_ItemIndexProc *) NULL,		/* indexProc */
d222 3
a224 3
    (Tk_ItemInsertProc *) NULL,		/* insertProc */
    (Tk_ItemDCharsProc *) NULL,		/* dTextProc */
    (Tk_ItemType *) NULL		/* nextPtr */
d263 1
a263 1
    char **argv;			/* Arguments describing polygon. */
a267 8
    if (argc < 6) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",
		itemPtr->typePtr->name,
		" x1 y1 x2 y2 x3 y3 ?x4 y4 ...? ?options?\"", (char *) NULL);
	return TCL_ERROR;
    }

d273 1
d277 4
a280 3
    polyPtr->width = 1;
    polyPtr->outlineColor = NULL;
    polyPtr->outlineGC = None;
d282 2
d285 2
d288 1
a288 1
    polyPtr->smooth = 0;
d298 4
a301 3
    for (i = 4; i < (argc-1); i+=2) {
	if ((!isdigit(UCHAR(argv[i][0]))) &&
		((argv[i][0] != '-') || (!isdigit(UCHAR(argv[i][1]))))) {
d305 1
a305 1
    if (PolygonCoords(interp, canvas, itemPtr, i, argv) != TCL_OK) {
d345 1
a345 1
    char **argv;			/* Array of coordinates: x1, y1,
a348 1
    char buffer[TCL_DOUBLE_SPACE];
d356 1
d358 2
a359 2
	    Tcl_PrintDouble(interp, polyPtr->coordPtr[i], buffer);
	    Tcl_AppendElement(interp, buffer);
d361 10
a370 6
    } else if (argc < 6) {
	Tcl_AppendResult(interp,
		"too few coordinates for polygon: must have at least 6",
		(char *) NULL);
	return TCL_ERROR;
    } else if (argc & 1) {
d383 2
a384 2
	     * One extra point gets allocated here, just in case we have
	     * to add another point to close the polygon.
d392 1
a392 1
	    if (Tk_CanvasGetCoord(interp, canvas, argv[i],
d399 1
a399 1
    
d404 2
a405 2
	if ((polyPtr->coordPtr[argc-2] != polyPtr->coordPtr[0])
		|| (polyPtr->coordPtr[argc-1] != polyPtr->coordPtr[1])) {
d441 1
a441 1
    char **argv;		/* Arguments describing things to configure. */
d449 3
d454 2
a455 2
    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv,
	    (char *) polyPtr, flags) != TCL_OK) {
d464 15
a478 2
    if (polyPtr->width < 1) {
	polyPtr->width = 1;
d480 7
a486 5
    if (polyPtr->outlineColor == NULL) {
	newGC = None;
    } else {
	gcValues.foreground = polyPtr->outlineColor->pixel;
	gcValues.line_width = polyPtr->width;
d488 2
a489 2
	gcValues.join_style = JoinRound;
	mask = GCForeground|GCLineWidth|GCCapStyle|GCJoinStyle;
d491 5
d497 18
a514 2
    if (polyPtr->outlineGC != None) {
	Tk_FreeGC(Tk_Display(tkwin), polyPtr->outlineGC);
a515 1
    polyPtr->outlineGC = newGC;
d517 1
a517 1
    if (polyPtr->fillColor == NULL) {
d520 1
a520 1
	gcValues.foreground = polyPtr->fillColor->pixel;
d522 2
a523 2
	if (polyPtr->fillStipple != None) {
	    gcValues.stipple = polyPtr->fillStipple;
d574 1
d581 6
d590 2
a591 2
    if (polyPtr->outlineColor != NULL) {
	Tk_FreeColor(polyPtr->outlineColor);
d593 2
a594 2
    if (polyPtr->outlineGC != None) {
	Tk_FreeGC(display, polyPtr->outlineGC);
d627 22
d654 11
a664 1
    for (i = 1, coordPtr = polyPtr->coordPtr+2; i < polyPtr->numPoints;
d669 102
d772 2
a773 3
     * Expand bounding box in all directions to account for the outline,
     * which can stick out beyond the polygon.  Add one extra pixel of
     * fudge, just in case X rounds differently than we do.
d776 4
a779 5
    i = (polyPtr->width+1)/2 + 1;
    polyPtr->header.x1 -= i;
    polyPtr->header.x2 += i;
    polyPtr->header.y1 -= i;
    polyPtr->header.y2 += i;
d843 1
a843 1
    if (gc != None) {
d885 7
a891 2

    if ((polyPtr->fillGC == None) && (polyPtr->outlineGC == None)) {
d895 18
d919 38
a956 5
    if ((polyPtr->fillStipple != None) && (polyPtr->fillGC != None)) {
	Tk_CanvasSetStippleOrigin(canvas, polyPtr->fillGC);
    }

    if (!polyPtr->smooth) {
d958 1
a958 1
		display, drawable, polyPtr->fillGC, polyPtr->outlineGC);
d969 3
a971 1
	numPoints = 1 + polyPtr->numPoints*polyPtr->splineSteps;
d978 1
a978 1
	numPoints = TkMakeBezierCurve(canvas, polyPtr->coordPtr,
d985 2
a986 2
	if (polyPtr->outlineGC != None) {
	    XDrawLines(display, drawable, polyPtr->outlineGC, pointPtr,
d993 2
a994 1
    if ((polyPtr->fillStipple != None) && (polyPtr->fillGC != None)) {
d1002 197
d1224 1
a1224 1
    double *coordPtr, distance;
d1226 26
a1251 1
    int numPoints;
d1253 9
a1261 10
    if (!polyPtr->smooth) {
	distance = TkPolygonToPoint(polyPtr->coordPtr, polyPtr->numPoints,
		pointPtr);
    } else {
	/*
	 * Smoothed polygon.  Generate a new set of points and use them
	 * for comparison.
	 */
    
	numPoints = 1 + polyPtr->numPoints*polyPtr->splineSteps;
d1263 1
a1263 1
	    coordPtr = staticSpace;
d1265 1
a1265 1
	    coordPtr = (double *) ckalloc((unsigned)
d1268 1
a1268 1
	numPoints = TkMakeBezierCurve(canvas, polyPtr->coordPtr,
d1270 17
a1286 4
		coordPtr);
	distance = TkPolygonToPoint(coordPtr, numPoints, pointPtr);
	if (coordPtr != staticSpace) {
	    ckfree((char *) coordPtr);
d1289 90
a1378 4
    if (polyPtr->outlineColor != NULL) {
	distance -= polyPtr->width/2.0;
	if (distance < 0) {
	    distance = 0;
d1381 6
a1386 1
    return distance;
d1419 1
a1419 1
    double *coordPtr, rect2[4], halfWidth;
d1421 29
a1449 1
    int numPoints, result;
d1451 13
d1470 3
a1472 1
	numPoints = 1 + polyPtr->numPoints*polyPtr->splineSteps;
d1474 1
a1474 1
	    coordPtr = staticSpace;
d1476 1
a1476 1
	    coordPtr = (double *) ckalloc((unsigned)
d1479 1
a1479 1
	numPoints = TkMakeBezierCurve(canvas, polyPtr->coordPtr,
d1481 1
a1481 1
		coordPtr);
d1484 13
a1496 1
	coordPtr = polyPtr->coordPtr;
d1499 9
a1507 5
    if (polyPtr->width <= 1) {
	/*
	 * The outline of the polygon doesn't stick out, so we can
	 * do a simple check.
	 */
d1509 4
a1512 2
	result = TkPolygonToArea(coordPtr, numPoints, rectPtr);
    } else {
d1514 3
a1516 2
	 * The polygon has a wide outline, so the check is more complicated.
	 * First, check the line segments to see if they overlap the area.
d1519 9
a1527 4
	result = TkThickPolyLineToArea(coordPtr, numPoints, 
	    (double) polyPtr->width, CapRound, JoinRound, rectPtr);
	if (result >= 0) {
	    goto done;
d1531 3
a1533 5
	 * There is no overlap between the polygon's outline and the
	 * rectangle.  This means either the rectangle is entirely outside
	 * the polygon or entirely inside.  To tell the difference,
	 * see whether the polygon (with 0 outline width) overlaps the
	 * rectangle bloated by half the outline width.
d1536 39
a1574 7
	halfWidth = polyPtr->width/2.0;
	rect2[0] = rectPtr[0] - halfWidth;
	rect2[1] = rectPtr[1] - halfWidth;
	rect2[2] = rectPtr[2] + halfWidth;
	rect2[3] = rectPtr[3] + halfWidth;
	if (TkPolygonToArea(coordPtr, numPoints, rect2) == -1) {
	    result = -1;
d1576 8
a1583 1
	    result = 0;
d1587 3
a1589 3
    done:
    if ((coordPtr != staticSpace) && (coordPtr != polyPtr->coordPtr)) {
	ckfree((char *) coordPtr);
d1591 1
a1591 1
    return result;
d1637 95
d1800 74
d1879 2
a1880 2
    if (polyPtr->fillColor != NULL) {
	if (!polyPtr->smooth) {
d1884 2
a1885 2
	    TkMakeBezierPostscript(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
d1887 1
a1887 1
	if (Tk_CanvasPsColor(interp, canvas, polyPtr->fillColor) != TCL_OK) {
d1890 1
a1890 1
	if (polyPtr->fillStipple != None) {
d1892 1
a1892 1
	    if (Tk_CanvasPsStipple(interp, canvas, polyPtr->fillStipple)
d1896 1
a1896 1
	    if (polyPtr->outlineColor != NULL) {
d1908 1
a1908 2
    if (polyPtr->outlineColor != NULL) {
	char string[32 + TCL_INTEGER_SPACE];
d1910 1
a1910 1
	if (!polyPtr->smooth) {
d1914 2
a1915 2
	    TkMakeBezierPostscript(interp, canvas, polyPtr->coordPtr,
		polyPtr->numPoints);
d1918 11
a1928 5
	sprintf(string, "%d setlinewidth\n", polyPtr->width);
	Tcl_AppendResult(interp, string,
		"1 setlinecap\n1 setlinejoin\n", (char *) NULL);
	if (Tk_CanvasPsColor(interp, canvas, polyPtr->outlineColor)
		!= TCL_OK) {
a1930 1
	Tcl_AppendResult(interp, "stroke\n", (char *) NULL);
@


1.2
log
@Replaced SCCS strings, fixed binary files
@
text
@d153 1
a153 1
 *	interp->result;  in this case itemPtr is
d237 1
a237 1
 *	Returns TCL_OK or TCL_ERROR, and sets interp->result.
d330 1
a330 1
 *	an error message is left in interp->result.
d922 1
a922 1
 *	left in interp->result, replacing whatever used
a942 1
    char string[100];
d979 2
@


1.1
log
@Initial revision
@
text
@d12 1
a12 1
 * SCCS: @@(#) tkCanvPoly.c 1.37 97/04/29 15:39:16
@


1.1.4.1
log
@initial tk8.1a2 version
@
text
@d12 1
a12 1
 * SCCS: @@(#) tkCanvPoly.c 1.38 97/11/07 21:15:07
d153 1
a153 1
 *	the interp's result;  in this case itemPtr is
d237 1
a237 1
 *	Returns TCL_OK or TCL_ERROR, and sets the interp's result.
d330 1
a330 1
 *	an error message is left in the interp's result.
d922 1
a922 1
 *	left in the interp's result, replacing whatever used
d943 1
a979 2
	char string[32 + TCL_INTEGER_SPACE];

@


1.1.4.2
log
@Merged 8.0.3 changes into 8.1
@
text
@d12 1
a12 1
 * RCS: @@(#) $Id: tkCanvPoly.c,v 1.2 1998/09/14 18:23:05 stanton Exp $
@


