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

📄 tkcanvline.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 4 页
字号:
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];	ckfree((char *) linePtr->firstArrowPtr);	linePtr->firstArrowPtr = NULL;    }    if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != lastUid)	    && (linePtr->arrow != bothUid)) {	int index;	index = 2*(linePtr->numPoints-1);	linePtr->coordPtr[index] = linePtr->lastArrowPtr[0];	linePtr->coordPtr[index+1] = linePtr->lastArrowPtr[1];	ckfree((char *) linePtr->lastArrowPtr);	linePtr->lastArrowPtr = NULL;    }    if (linePtr->arrow != noneUid) {	if ((linePtr->arrow != firstUid) && (linePtr->arrow != lastUid)		&& (linePtr->arrow != bothUid)) {	    Tcl_AppendResult(canvasPtr->interp, "bad arrow spec \"",		    linePtr->arrow, "\": must be none, first, last, or both",		    (char *) NULL);	    linePtr->arrow = noneUid;	    return TCL_ERROR;	}	ConfigureArrows(canvasPtr, linePtr);    }    /*     * Recompute bounding box for line.     */    ComputeLineBbox(canvasPtr, linePtr);    return TCL_OK;}/* *-------------------------------------------------------------- * * DeleteLine -- * *	This procedure is called to clean up the data structure *	associated with a line item. * * Results: *	None. * * Side effects: *	Resources associated with itemPtr are released. * *-------------------------------------------------------------- */static voidDeleteLine(canvasPtr, itemPtr)    Tk_Canvas *canvasPtr;		/* Info about overall canvas widget. */    Tk_Item *itemPtr;			/* Item that is being deleted. */{    register LineItem *linePtr = (LineItem *) itemPtr;    if (linePtr->coordPtr != NULL) {	ckfree((char *) linePtr->coordPtr);    }    if (linePtr->fg != NULL) {	Tk_FreeColor(linePtr->fg);    }    if (linePtr->fillStipple != None) {	Tk_FreeBitmap(canvasPtr->display, linePtr->fillStipple);    }    if (linePtr->gc != None) {	Tk_FreeGC(canvasPtr->display, linePtr->gc);    }    if (linePtr->firstArrowPtr != NULL) {	ckfree((char *) linePtr->firstArrowPtr);    }    if (linePtr->lastArrowPtr != NULL) {	ckfree((char *) linePtr->lastArrowPtr);    }}/* *-------------------------------------------------------------- * * ComputeLineBbox -- * *	This procedure is invoked to compute the bounding box of *	all the pixels that may be drawn as part of a line. * * Results: *	None. * * Side effects: *	The fields x1, y1, x2, and y2 are updated in the header *	for itemPtr. * *-------------------------------------------------------------- */static voidComputeLineBbox(canvasPtr, linePtr)    register Tk_Canvas *canvasPtr;	/* Canvas that contains item. */    LineItem *linePtr;			/* Item whose bbos is to be					 * recomputed. */{    register double *coordPtr;    int i;    coordPtr = linePtr->coordPtr;    linePtr->header.x1 = linePtr->header.x2 = *coordPtr;    linePtr->header.y1 = linePtr->header.y2 = coordPtr[1];    /*     * Compute the bounding box of all the points in the line,     * then expand in all directions by the line'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 = linePtr->coordPtr+2; i < linePtr->numPoints;	    i++, coordPtr += 2) {	TkIncludePoint(canvasPtr, (Tk_Item *) linePtr, coordPtr);    }    linePtr->header.x1 -= linePtr->width;    linePtr->header.x2 += linePtr->width;    linePtr->header.y1 -= linePtr->width;    linePtr->header.y2 += linePtr->width;    /*     * 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 (linePtr->joinStyle == JoinMiter) {	for (i = linePtr->numPoints, coordPtr = linePtr->coordPtr; i >= 3;		i--, coordPtr += 2) {	    double miter[4];	    int j;    	    if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,		    (double) linePtr->width, miter, miter+2)) {		for (j = 0; j < 4; j += 2) {		    TkIncludePoint(canvasPtr, (Tk_Item *) linePtr, miter+j);		}	    }	}    }    /*     * Add in the sizes of arrowheads, if any.     */    if (linePtr->arrow != noneUid) {	if (linePtr->arrow != lastUid) {	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;		    i++, coordPtr += 2) {		TkIncludePoint(canvasPtr, (Tk_Item *) linePtr, coordPtr);	    }	}	if (linePtr->arrow != firstUid) {	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;		    i++, coordPtr += 2) {		TkIncludePoint(canvasPtr, (Tk_Item *) linePtr, coordPtr);	    }	}    }    /*     * Add one more pixel of fudge factor just to be safe (e.g.     * X may round differently than we do).     */    linePtr->header.x1 -= 1;    linePtr->header.x2 += 1;    linePtr->header.y1 -= 1;    linePtr->header.y2 += 1;}/* *-------------------------------------------------------------- * * DisplayLine -- * *	This procedure is invoked to draw a line item in a given *	drawable. * * Results: *	None. * * Side effects: *	ItemPtr is drawn in drawable using the transformation *	information in canvasPtr. * *-------------------------------------------------------------- */static voidDisplayLine(canvasPtr, itemPtr, drawable)    register Tk_Canvas *canvasPtr;	/* Canvas that contains item. */    Tk_Item *itemPtr;			/* Item to be displayed. */    Drawable drawable;			/* Pixmap or window in which to draw					 * item. */{    register LineItem *linePtr = (LineItem *) itemPtr;    XPoint staticPoints[MAX_STATIC_POINTS];    XPoint *pointPtr;    register XPoint *pPtr;    register double *coordPtr;    int i, numPoints;    if (linePtr->gc == None) {	return;    }    /*     * Build up an array of points in screen coordinates.  Use a     * static array unless the line has an enormous number of points;     * in this case, dynamically allocate an array.  For smoothed lines,     * generate the curve points on each redisplay.     */    if ((linePtr->smooth) && (linePtr->numPoints > 2)) {	numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;    } else {	numPoints = linePtr->numPoints;    }    if (numPoints <= MAX_STATIC_POINTS) {	pointPtr = staticPoints;    } else {	pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint)));    }    if (linePtr->smooth) {	numPoints = TkMakeBezierCurve(canvasPtr, linePtr->coordPtr,		linePtr->numPoints, linePtr->splineSteps, pointPtr,		(double *) NULL);    } else {	for (i = 0, coordPtr = linePtr->coordPtr, pPtr = pointPtr;		i < linePtr->numPoints;  i += 1, coordPtr += 2, pPtr++) {	    pPtr->x = SCREEN_X(canvasPtr, *coordPtr);	    pPtr->y = SCREEN_Y(canvasPtr, coordPtr[1]);	}    }    /*     * Display line, the free up line storage if it was dynamically     * allocated.  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 (linePtr->fillStipple != None) {	XSetTSOrigin(Tk_Display(canvasPtr->tkwin), linePtr->gc,		-canvasPtr->drawableXOrigin, -canvasPtr->drawableYOrigin);    }    XDrawLines(Tk_Display(canvasPtr->tkwin), drawable, linePtr->gc,	    pointPtr, numPoints, CoordModeOrigin);    if (pointPtr != staticPoints) {	ckfree((char *) pointPtr);    }    /*     * Display arrowheads, if they are wanted.     */    if (linePtr->arrow != noneUid) {	if (linePtr->arrow != lastUid) {	    TkFillPolygon(canvasPtr, linePtr->firstArrowPtr, PTS_IN_ARROW,		    drawable, linePtr->gc);	}	if (linePtr->arrow != firstUid) {	    TkFillPolygon(canvasPtr, linePtr->lastArrowPtr, PTS_IN_ARROW,		    drawable, linePtr->gc);	}    }    if (linePtr->fillStipple != None) {	XSetTSOrigin(Tk_Display(canvasPtr->tkwin), linePtr->gc, 0, 0);    }}/* *-------------------------------------------------------------- * * LineToPoint -- * *	Computes the distance from a given point to a given *	line, 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 line.  If the *	point isn't inside the line then the return value is the *	distance from the point to the line. * * Side effects: *	None. * *-------------------------------------------------------------- */	/* ARGSUSED */static doubleLineToPoint(canvasPtr, itemPtr, pointPtr)    Tk_Canvas *canvasPtr;	/* Canvas containing item. */    Tk_Item *itemPtr;		/* Item to check against point. */    double *pointPtr;		/* Pointer to x and y coordinates. */{    register LineItem *linePtr = (LineItem *) itemPtr;    register double *coordPtr, *linePoints;    double staticSpace[2*MAX_STATIC_POINTS];    double poly[10];    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. */    bestDist = 1.0e40;    /*     * Handle smoothed lines by generating an expanded set of points     * against which to do the check.     */    if ((linePtr->smooth) && (linePtr->numPoints > 2)) {	numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;	if (numPoints <= MAX_STATIC_POINTS) {	    linePoints = staticSpace;	} else {	    linePoints = (double *) ckalloc((unsigned)		    (2*numPoints*sizeof(double)));	}	numPoints = TkMakeBezierCurve(canvasPtr, linePtr->coordPtr,		linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,		linePoints);    } else {	numPoints = linePtr->numPoints;	linePoints = linePtr->coordPtr;    }    /*     * 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 = linePoints; count >= 2;	    count--, coordPtr += 2) {	/*	 * If rounding is done around the first point then compute	 * the distance between the point and the point.	 */	if (((linePtr->capStyle == CapRound) && (count == numPoints))		|| ((linePtr->joinStyle == JoinRound)			&& (count != numPoints))) {	    dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1])		    - linePtr->width/2.0;	    if (dist <= 0.0) {		bestDist = 0.0;		goto done;	    } 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) linePtr->width,		    linePtr->capStyle == CapProjecting, poly, poly+2);	} else if ((linePtr->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) linePtr->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 ((linePtr->joinStyle == JoinBevel) || changedMiterToBevel) {		poly[8] = poly[0];		poly[9] = poly[1];		dist = TkPolygonToPoint(poly, 5, pointPtr);		if (dist <= 0.0) {		    bestDist = 0.0;		    goto done;		} else if (dist < bestDist) {		    bestDist = dist;		}		changedMiterToBevel = 0;	    }	}	if (count == 2) {	    TkGetButtPoints(coordPtr, coordPtr+2, (double) linePtr->width,		    linePtr->capStyle == CapProjecting, poly+4, poly+6);	} else if (linePtr->joinStyle == JoinMiter) {	    if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,		    (double) linePtr->width, poly+4, poly+6) == 0) {		changedMiterToBevel = 1;		TkGetButtPoints(coordPtr, coordPtr+2, (double) linePtr->width,			0, poly+4, poly+6);	    }	} else {	    TkGetButtPoints(coordPtr, coordPtr+2, (double) linePtr->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 done;	} else if (dist < bestDist) {	    bestDist = dist;	}    }    /*     * If caps are rounded, check the distance to the cap around the     * final end point of the line.     */    if (linePtr->capStyle == CapRound) {	dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1])		- linePtr->width/2.0;	if (dist <= 0.0) {	    bestDist = 0.0;	    goto done;	} else if (dist < bestDist) {	    bestDist = dist;	}    }    /*     * If there are arrowheads, check the distance to the arrowheads.     */    if (linePtr->arrow != noneUid) {	if (linePtr->arrow != lastUid) {	    dist = TkPolygonToPoint(linePtr->firstArrowPtr, PTS_IN_ARROW,		    pointPtr);	    if (dist <= 0.0) {		bestDist = 0.0;		goto done;	    } else if (dist < bestDist) {		bestDist = dist;	    }	}	if (linePtr->arrow != firstUid) {	    dist = TkPolygonToPoint(linePtr->lastArrowPtr, PTS_IN_ARROW,		    pointPtr);	    if (dist <= 0.0) {		bestDist = 0.0;		goto done;	    } else if (dist < bestDist) {		bestDist = dist;	    }	}    }    done:    if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {	ckfree((char *) linePoints);    }    return bestDist;}/*

⌨️ 快捷键说明

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