⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tkcanvpoly.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * 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. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkCanvPoly.c 1.37 97/04/29 15:39:16 */#include <stdio.h>#include "tkInt.h"#include "tkPort.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. */    int numPoints;		/* Number of points in polygon (always >= 3).				 * 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 width;			/* Width of outline. */    XColor *outlineColor;	/* Color for outline. */    GC outlineGC;		/* Graphics context for drawing outline. */    XColor *fillColor;		/* Foreground color for polygon. */    Pixmap fillStipple;		/* Stipple bitmap for filling polygon. */    GC fillGC;			/* Graphics context for filling polygon. */    int 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 Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,    Tk_CanvasTagsPrintProc, (ClientData) NULL};static Tk_ConfigSpec configSpecs[] = {    {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,	"black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK},    {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,	(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},    {TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,	"12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},    {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_PIXELS, "-width", (char *) NULL, (char *) NULL,	"1", Tk_Offset(PolygonItem, width), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,	(char *) NULL, 0, 0}};/* * Prototypes for procedures defined in this file: */static void		ComputePolygonBbox _ANSI_ARGS_((Tk_Canvas canvas,			    PolygonItem *polyPtr));static int		ConfigurePolygon _ANSI_ARGS_((Tcl_Interp *interp,			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,			    char **argv, int flags));static int		CreatePolygon _ANSI_ARGS_((Tcl_Interp *interp,			    Tk_Canvas canvas, struct Tk_Item *itemPtr,			    int argc, char **argv));static void		DeletePolygon _ANSI_ARGS_((Tk_Canvas canvas,			    Tk_Item *itemPtr,  Display *display));static void		DisplayPolygon _ANSI_ARGS_((Tk_Canvas canvas,			    Tk_Item *itemPtr, Display *display, Drawable dst,			    int x, int y, int width, int height));static int		PolygonCoords _ANSI_ARGS_((Tcl_Interp *interp,			    Tk_Canvas canvas, Tk_Item *itemPtr,			    int argc, char **argv));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,			    Tk_Item *itemPtr, double originX, double originY,			    double scaleX, double scaleY));static void		TranslatePolygon _ANSI_ARGS_((Tk_Canvas canvas,			    Tk_Item *itemPtr, double deltaX, double deltaY));/* * The structures below defines the polygon item type by means * of procedures 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 */    0,					/* alwaysRedraw */    PolygonToPoint,			/* pointProc */    PolygonToArea,			/* areaProc */    PolygonToPostscript,		/* postscriptProc */    ScalePolygon,			/* scaleProc */    TranslatePolygon,			/* translateProc */    (Tk_ItemIndexProc *) NULL,		/* indexProc */    (Tk_ItemCursorProc *) NULL,		/* icursorProc */    (Tk_ItemSelectionProc *) NULL,	/* selectionProc */    (Tk_ItemInsertProc *) NULL,		/* insertProc */    (Tk_ItemDCharsProc *) NULL,		/* dTextProc */    (Tk_ItemType *) NULL		/* nextPtr */};/* * 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 procedure 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 *	interp->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 intCreatePolygon(interp, canvas, itemPtr, argc, argv)    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 argc;				/* Number of arguments in argv. */    char **argv;			/* Arguments describing polygon. */{    PolygonItem *polyPtr = (PolygonItem *) itemPtr;    int i;    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;    }    /*     * Carry out initialization that is needed in order to clean     * up after errors during the the remainder of this procedure.     */    polyPtr->numPoints = 0;    polyPtr->pointsAllocated = 0;    polyPtr->coordPtr = NULL;    polyPtr->width = 1;    polyPtr->outlineColor = NULL;    polyPtr->outlineGC = None;    polyPtr->fillColor = NULL;    polyPtr->fillStipple = None;    polyPtr->fillGC = None;    polyPtr->smooth = 0;    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 = 4; i < (argc-1); i+=2) {	if ((!isdigit(UCHAR(argv[i][0]))) &&		((argv[i][0] != '-') || (!isdigit(UCHAR(argv[i][1]))))) {	    break;	}    }    if (PolygonCoords(interp, canvas, itemPtr, i, argv) != TCL_OK) {	goto error;    }    if (ConfigurePolygon(interp, canvas, itemPtr, argc-i, argv+i, 0)	    == TCL_OK) {	return TCL_OK;    }    error:    DeletePolygon(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));    return TCL_ERROR;}/* *-------------------------------------------------------------- * * PolygonCoords -- * *	This procedure 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 interp->result. * * Side effects: *	The coordinates for the given item may be changed. * *-------------------------------------------------------------- */static intPolygonCoords(interp, canvas, itemPtr, argc, argv)    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 argc;				/* Number of coordinates supplied in					 * argv. */    char **argv;			/* Array of coordinates: x1, y1,					 * x2, y2, ... */{    PolygonItem *polyPtr = (PolygonItem *) itemPtr;    char buffer[TCL_DOUBLE_SPACE];    int i, numPoints;    if (argc == 0) {	/*	 * Print the coords used to create the polygon.  If we auto	 * closed the polygon then we don't report the last point.	 */	for (i = 0; i < 2*(polyPtr->numPoints - polyPtr->autoClosed); i++) {	    Tcl_PrintDouble(interp, polyPtr->coordPtr[i], buffer);	    Tcl_AppendElement(interp, buffer);	}    } 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) {	Tcl_AppendResult(interp,		"odd number of coordinates specified for polygon",		(char *) NULL);	return TCL_ERROR;    } else {	numPoints = argc/2;	if (polyPtr->pointsAllocated <= numPoints) {	    if (polyPtr->coordPtr != NULL) {		ckfree((char *) polyPtr->coordPtr);	    }	    /*	     * One extra point gets allocated here, just in case we have	     * to add another point to close the polygon.	     */	    polyPtr->coordPtr = (double *) ckalloc((unsigned)		    (sizeof(double) * (argc+2)));	    polyPtr->pointsAllocated = numPoints+1;	}	for (i = argc-1; i >= 0; i--) {	    if (Tk_CanvasGetCoord(interp, canvas, argv[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 ((polyPtr->coordPtr[argc-2] != polyPtr->coordPtr[0])		|| (polyPtr->coordPtr[argc-1] != polyPtr->coordPtr[1])) {	    polyPtr->autoClosed = 1;	    polyPtr->numPoints++;	    polyPtr->coordPtr[argc] = polyPtr->coordPtr[0];	    polyPtr->coordPtr[argc+1] = polyPtr->coordPtr[1];	}	ComputePolygonBbox(canvas, polyPtr);    }    return TCL_OK;}/* *-------------------------------------------------------------- * * ConfigurePolygon -- * *	This procedure 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 interp->result. * * Side effects: *	Configuration information, such as colors and stipple *	patterns, may be set for itemPtr. * *-------------------------------------------------------------- */static intConfigurePolygon(interp, canvas, itemPtr, argc, argv, flags)    Tcl_Interp *interp;		/* Interpreter for error reporting. */    Tk_Canvas canvas;		/* Canvas containing itemPtr. */    Tk_Item *itemPtr;		/* Polygon item to reconfigure. */    int argc;			/* Number of elements in argv.  */    char **argv;		/* 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;    tkwin = Tk_CanvasTkwin(canvas);    if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv,	    (char *) polyPtr, flags) != TCL_OK) {	return TCL_ERROR;    }    /*     * A few of the options require additional processing, such as     * graphics contexts.     */    if (polyPtr->width < 1) {	polyPtr->width = 1;    }    if (polyPtr->outlineColor == NULL) {	newGC = None;    } else {	gcValues.foreground = polyPtr->outlineColor->pixel;	gcValues.line_width = polyPtr->width;	gcValues.cap_style = CapRound;	gcValues.join_style = JoinRound;	mask = GCForeground|GCLineWidth|GCCapStyle|GCJoinStyle;	newGC = Tk_GetGC(tkwin, mask, &gcValues);    }    if (polyPtr->outlineGC != None) {	Tk_FreeGC(Tk_Display(tkwin), polyPtr->outlineGC);    }    polyPtr->outlineGC = newGC;    if (polyPtr->fillColor == NULL) {	newGC = None;    } else {	gcValues.foreground = polyPtr->fillColor->pixel;	mask = GCForeground;	if (polyPtr->fillStipple != None) {	    gcValues.stipple = polyPtr->fillStipple;	    gcValues.fill_style = FillStippled;	    mask |= GCStipple|GCFillStyle;	}	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 procedure is called to clean up the data structure *	associated with a polygon item. * * Results: *	None. * * Side effects: *	Resources associated with itemPtr are released. * *-------------------------------------------------------------- */static voidDeletePolygon(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. */{    PolygonItem *polyPtr = (PolygonItem *) itemPtr;    if (polyPtr->coordPtr != NULL) {	ckfree((char *) polyPtr->coordPtr);    }    if (polyPtr->fillColor != NULL) {	Tk_FreeColor(polyPtr->fillColor);    }    if (polyPtr->fillStipple != None) {	Tk_FreeBitmap(display, polyPtr->fillStipple);    }    if (polyPtr->outlineColor != NULL) {	Tk_FreeColor(polyPtr->outlineColor);    }    if (polyPtr->outlineGC != None) {	Tk_FreeGC(display, polyPtr->outlineGC);    }    if (polyPtr->fillGC != None) {	Tk_FreeGC(display, polyPtr->fillGC);    }}/* *-------------------------------------------------------------- * * ComputePolygonBbox -- * *	This procedure 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 voidComputePolygonBbox(canvas, polyPtr)    Tk_Canvas canvas;			/* Canvas that contains item. */    PolygonItem *polyPtr;		/* Item whose bbox is to be					 * recomputed. */{    double *coordPtr;    int i;    coordPtr = polyPtr->coordPtr;    polyPtr->header.x1 = polyPtr->header.x2 = (int) *coordPtr;    polyPtr->header.y1 = polyPtr->header.y2 = (int) coordPtr[1];    for (i = 1, coordPtr = polyPtr->coordPtr+2; i < polyPtr->numPoints;	    i++, coordPtr += 2) {	TkIncludePoint((Tk_Item *) polyPtr, coordPtr);    }    /*     * 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.     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -