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

📄 tkcanvline.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * tkCanvLine.c -- * *	This file implements line items for canvas widgets. * * Copyright (c) 1991-1993 The Regents of the University of California. * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */#include <stdio.h>#include "tkInt.h"#include "tkCanvas.h"#include "tkConfig.h"/* * The structure below defines the record for each line item. */typedef struct LineItem  {    Tk_Item header;		/* Generic stuff that's the same for all				 * types.  MUST BE FIRST IN STRUCTURE. */    Tk_Canvas *canvasPtr;	/* Canvas containing item.  Needed for				 * parsing arrow shapes. */    int numPoints;		/* Number of points in line (always >= 2). */    double *coordPtr;		/* Pointer to malloc-ed array containing				 * x- and y-coords of all points in line.				 * X-coords are even-valued indices, y-coords				 * are corresponding odd-valued indices. If				 * the line has arrowheads then the first				 * and last points have been adjusted to refer				 * to the necks of the arrowheads rather than				 * their tips.  The actual endpoints are				 * stored in the *firstArrowPtr and				 * *lastArrowPtr, if they exist. */    int width;			/* Width of line. */    XColor *fg;			/* Foreground color for line. */    Pixmap fillStipple;		/* Stipple bitmap for filling line. */    int capStyle;		/* Cap style for line. */    int joinStyle;		/* Join style for line. */    GC gc;			/* Graphics context for filling line. */    Tk_Uid arrow;		/* Indicates whether or not to draw arrowheads:				 * "none", "first", "last", or "both". */    float arrowShapeA;		/* Distance from tip of arrowhead to center. */    float arrowShapeB;		/* Distance from tip of arrowhead to trailing				 * point, measured along shaft. */    float arrowShapeC;		/* Distance of trailing points from outside				 * edge of shaft. */    double *firstArrowPtr;	/* Points to array of PTS_IN_ARROW points				 * describing polygon for arrowhead at first				 * point in line.  First point of arrowhead				 * is tip.  Malloc'ed.  NULL means no arrowhead				 * at first point. */    double *lastArrowPtr;	/* Points to polygon for arrowhead at last				 * point in line (PTS_IN_ARROW points, first				 * of which is tip).  Malloc'ed.  NULL means				 * no arrowhead at last point. */    int smooth;			/* Non-zero means draw line smoothed (i.e.				 * with Bezier splines). */    int splineSteps;		/* Number of steps in each spline segment. */} LineItem;/* * Number of points in an arrowHead: */#define PTS_IN_ARROW 6/* * Prototypes for procedures defined in this file: */static int		ArrowheadPostscript _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    LineItem *linePtr, double *arrowPtr,			    Tk_PostscriptInfo *psInfoPtr));static void		ComputeLineBbox _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    LineItem *linePtr));static int		ConfigureLine _ANSI_ARGS_((			    Tk_Canvas *canvasPtr, Tk_Item *itemPtr, int argc,			    char **argv, int flags));static int		ConfigureArrows _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    LineItem *linePtr));static int		CreateLine _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    struct Tk_Item *itemPtr, int argc, char **argv));static void		DeleteLine _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr));static void		DisplayLine _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, Drawable dst));static int		LineCoords _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, int argc, char **argv));static int		LineToArea _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, double *rectPtr));static double		LineToPoint _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, double *coordPtr));static int		LineToPostscript _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, Tk_PostscriptInfo *psInfoPtr));static int		ParseArrowShape _ANSI_ARGS_((ClientData clientData,			    Tcl_Interp *interp, Tk_Window tkwin, char *value,			    char *recordPtr, int offset));static char *		PrintArrowShape _ANSI_ARGS_((ClientData clientData,			    Tk_Window tkwin, char *recordPtr, int offset,			    Tcl_FreeProc **freeProcPtr));static void		ScaleLine _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, double originX, double originY,			    double scaleX, double scaleY));static void		TranslateLine _ANSI_ARGS_((Tk_Canvas *canvasPtr,			    Tk_Item *itemPtr, double deltaX, double deltaY));/* * Information used for parsing configuration specs.  If you change any * of the default strings, be sure to change the corresponding default * values in CreateLine. */static Tk_CustomOption arrowShapeOption = {ParseArrowShape,	PrintArrowShape, (ClientData) NULL};static Tk_ConfigSpec configSpecs[] = {    {TK_CONFIG_UID, "-arrow", (char *) NULL, (char *) NULL,	"none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_CUSTOM, "-arrowshape", (char *) NULL, (char *) NULL,	"8 10 3", Tk_Offset(LineItem, arrowShapeA),	TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},    {TK_CONFIG_CAP_STYLE, "-capstyle", (char *) NULL, (char *) NULL,	"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,	"black", Tk_Offset(LineItem, fg), TK_CONFIG_NULL_OK},    {TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL,	"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_BOOLEAN, "-smooth", (char *) NULL, (char *) NULL,	"0", Tk_Offset(LineItem, smooth), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,	"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,	(char *) NULL, Tk_Offset(LineItem, fillStipple), TK_CONFIG_NULL_OK},    {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,	(char *) NULL, 0, TK_CONFIG_NULL_OK, &tkCanvasTagsOption},    {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,	"1", Tk_Offset(LineItem, width), TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,	(char *) NULL, 0, 0}};/* * The structures below defines the line item type by means * of procedures that can be invoked by generic item code. */Tk_ItemType TkLineType = {    "line",				/* name */    sizeof(LineItem),			/* itemSize */    CreateLine,				/* createProc */    configSpecs,			/* configSpecs */    ConfigureLine,			/* configureProc */    LineCoords,				/* coordProc */    DeleteLine,				/* deleteProc */    DisplayLine,			/* displayProc */    0,					/* alwaysRedraw */    LineToPoint,			/* pointProc */    LineToArea,				/* areaProc */    LineToPostscript,			/* postscriptProc */    ScaleLine,				/* scaleProc */    TranslateLine,			/* 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 Tk_Uid's below refer to uids for the various arrow types: */static Tk_Uid noneUid = NULL;static Tk_Uid firstUid = NULL;static Tk_Uid lastUid = NULL;static Tk_Uid bothUid = 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/* *-------------------------------------------------------------- * * CreateLine -- * *	This procedure is invoked to create a new line 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 *	canvasPtr->interp->result;  in this case itemPtr is *	left uninitialized, so it can be safely freed by the *	caller. * * Side effects: *	A new line item is created. * *-------------------------------------------------------------- */static intCreateLine(canvasPtr, itemPtr, argc, argv)    register Tk_Canvas *canvasPtr;	/* 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 line. */{    register LineItem *linePtr = (LineItem *) itemPtr;    int i;    if (argc < 4) {	Tcl_AppendResult(canvasPtr->interp, "wrong # args:  should be \"",		Tk_PathName(canvasPtr->tkwin), "\" create ",		itemPtr->typePtr->name, " x1 y1 x2 y2 ?x3 y3 ...? ?options?",		(char *) NULL);	return TCL_ERROR;    }    /*     * Carry out initialization that is needed to set defaults and to     * allow proper cleanup after errors during the the remainder of     * this procedure.     */    linePtr->canvasPtr = canvasPtr;    linePtr->numPoints = 0;    linePtr->coordPtr = NULL;    linePtr->width = 1;    linePtr->fg = None;    linePtr->fillStipple = None;    linePtr->capStyle = CapButt;    linePtr->joinStyle = JoinRound;    linePtr->gc = None;    if (noneUid == NULL) {	noneUid = Tk_GetUid("none");	firstUid = Tk_GetUid("first");	lastUid = Tk_GetUid("last");	bothUid = Tk_GetUid("both");    }    linePtr->arrow = noneUid;    linePtr->arrowShapeA = 8.0;    linePtr->arrowShapeB = 10.0;    linePtr->arrowShapeC = 3.0;    linePtr->firstArrowPtr = NULL;    linePtr->lastArrowPtr = NULL;    linePtr->smooth = 0;    linePtr->splineSteps = 12;    /*     * 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 (LineCoords(canvasPtr, itemPtr, i, argv) != TCL_OK) {	goto error;    }    if (ConfigureLine(canvasPtr, itemPtr, argc-i, argv+i, 0) == TCL_OK) {	return TCL_OK;    }    error:    DeleteLine(canvasPtr, itemPtr);    return TCL_ERROR;}/* *-------------------------------------------------------------- * * LineCoords -- * *	This procedure is invoked to process the "coords" widget *	command on lines.  See the user documentation for details *	on what it does. * * Results: *	Returns TCL_OK or TCL_ERROR, and sets canvasPtr->interp->result. * * Side effects: *	The coordinates for the given item may be changed. * *-------------------------------------------------------------- */static intLineCoords(canvasPtr, itemPtr, argc, argv)    register Tk_Canvas *canvasPtr;	/* 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, ... */{    register LineItem *linePtr = (LineItem *) itemPtr;    char buffer[TCL_DOUBLE_SPACE];    int i, numPoints;    if (argc == 0) {	double *coordPtr;	int numCoords;	numCoords = 2*linePtr->numPoints;	if (linePtr->firstArrowPtr != NULL) {	    coordPtr = linePtr->firstArrowPtr;	} else {	    coordPtr = linePtr->coordPtr;	}	for (i = 0; i < numCoords; i++, coordPtr++) {	    if (i == 2) {		coordPtr = linePtr->coordPtr+2;	    }	    if ((linePtr->lastArrowPtr != NULL) && (i == (numCoords-2))) {		coordPtr = linePtr->lastArrowPtr;	    }	    Tcl_PrintDouble(canvasPtr->interp, *coordPtr, buffer);	    Tcl_AppendElement(canvasPtr->interp, buffer);	}    } else if (argc < 4) {	Tcl_AppendResult(canvasPtr->interp,		"too few coordinates for line:  must have at least 4",		(char *) NULL);	return TCL_ERROR;    } else if (argc & 1) {	Tcl_AppendResult(canvasPtr->interp,		"odd number of coordinates specified for line",		(char *) NULL);	return TCL_ERROR;    } else {	numPoints = argc/2;	if (linePtr->numPoints != numPoints) {	    if (linePtr->coordPtr != NULL) {		ckfree((char *) linePtr->coordPtr);	    }	    linePtr->coordPtr = (double *) ckalloc((unsigned)		    (sizeof(double) * argc));	    linePtr->numPoints = numPoints;	}	for (i = argc-1; i >= 0; i--) {	    if (TkGetCanvasCoord(canvasPtr, argv[i], &linePtr->coordPtr[i])		    != TCL_OK) {		return TCL_ERROR;	    }	}	/*	 * Update arrowheads by throwing away any existing arrow-head	 * information and calling ConfigureArrows to recompute it.	 */	if (linePtr->firstArrowPtr != NULL) {	    ckfree((char *) linePtr->firstArrowPtr);	    linePtr->firstArrowPtr = NULL;	}	if (linePtr->lastArrowPtr != NULL) {	    ckfree((char *) linePtr->lastArrowPtr);	    linePtr->lastArrowPtr = NULL;	}	if (linePtr->arrow != noneUid) {	    ConfigureArrows(canvasPtr, linePtr);	}	ComputeLineBbox(canvasPtr, linePtr);    }    return TCL_OK;}/* *-------------------------------------------------------------- * * ConfigureLine -- * *	This procedure is invoked to configure various aspects *	of a line item such as its background color. * * Results: *	A standard Tcl result code.  If an error occurs, then *	an error message is left in canvasPtr->interp->result. * * Side effects: *	Configuration information, such as colors and stipple *	patterns, may be set for itemPtr. * *-------------------------------------------------------------- */static intConfigureLine(canvasPtr, itemPtr, argc, argv, flags)    Tk_Canvas *canvasPtr;	/* Canvas containing itemPtr. */    Tk_Item *itemPtr;		/* Line 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. */{    register LineItem *linePtr = (LineItem *) itemPtr;    XGCValues gcValues;    GC newGC;    unsigned long mask;    if (Tk_ConfigureWidget(canvasPtr->interp, canvasPtr->tkwin,	    configSpecs, argc, argv, (char *) linePtr, flags) != TCL_OK) {	return TCL_ERROR;    }    /*     * A few of the options require additional processing, such as     * graphics contexts.     */    if (linePtr->fg == NULL) {	newGC = None;    } else {	gcValues.foreground = linePtr->fg->pixel;	gcValues.join_style = linePtr->joinStyle;	if (linePtr->width < 0) {	    linePtr->width = 1;	}	gcValues.line_width = linePtr->width;	mask = GCForeground|GCJoinStyle|GCLineWidth;	if (linePtr->fillStipple != None) {	    gcValues.stipple = linePtr->fillStipple;	    gcValues.fill_style = FillStippled;	    mask |= GCStipple|GCFillStyle;	}	if (linePtr->arrow == noneUid) {	    gcValues.cap_style = linePtr->capStyle;	    mask |= GCCapStyle;	}	newGC = Tk_GetGC(canvasPtr->tkwin, mask, &gcValues);    }    if (linePtr->gc != None) {	Tk_FreeGC(canvasPtr->display, linePtr->gc);    }    linePtr->gc = newGC;    /*     * Keep spline parameters within reasonable limits.     */    if (linePtr->splineSteps < 1) {	linePtr->splineSteps = 1;    } else if (linePtr->splineSteps > 100) {	linePtr->splineSteps = 100;    }    /*     * Setup arrowheads, if needed.  If arrowheads are turned off,     * restore the line's endpoints (they were shortened when the     * arrowheads were added).     */    if ((linePtr->firstArrowPtr != NULL) && (linePtr->arrow != firstUid)	    && (linePtr->arrow != bothUid)) {	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];

⌨️ 快捷键说明

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