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

📄 tkcanvline.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
    LineItem *linePtr = (LineItem *) itemPtr;    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.0e36;    /*     * 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(canvas, 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;}/* *-------------------------------------------------------------- * * LineToArea -- * *	This procedure 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, 0 if it overlaps, and 1 if it is entirely *	inside the given area. * * Side effects: *	None. * *-------------------------------------------------------------- */	/* ARGSUSED */static intLineToArea(canvas, itemPtr, rectPtr)    Tk_Canvas canvas;		/* Canvas containing item. */    Tk_Item *itemPtr;		/* Item to check against line. */    double *rectPtr;{    LineItem *linePtr = (LineItem *) itemPtr;    double staticSpace[2*MAX_STATIC_POINTS];    double *linePoints;    int numPoints, result;    /*     * 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(canvas, linePtr->coordPtr,		linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,		linePoints);    } else {	numPoints = linePtr->numPoints;	linePoints = linePtr->coordPtr;    }    /*     * Check the segments of the line.     */    result = TkThickPolyLineToArea(linePoints, numPoints, 	    (double) linePtr->width, linePtr->capStyle, linePtr->joinStyle,	    rectPtr);    if (result == 0) {	goto done;    }    /*     * Check arrowheads, if any.     */    if (linePtr->arrow != noneUid) {	if (linePtr->arrow != lastUid) {	    if (TkPolygonToArea(linePtr->firstArrowPtr, PTS_IN_ARROW,		    rectPtr) != result) {		result = 0;		goto done;	    }	}	if (linePtr->arrow != firstUid) {	    if (TkPolygonToArea(linePtr->lastArrowPtr, PTS_IN_ARROW,		    rectPtr) != result) {		result = 0;		goto done;	    }	}    }    done:    if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {	ckfree((char *) linePoints);    }    return result;}/* *-------------------------------------------------------------- * * ScaleLine -- * *	This procedure is invoked to rescale a line item. * * Results: *	None. * * Side effects: *	The line 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 voidScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY)    Tk_Canvas canvas;			/* Canvas containing line. */    Tk_Item *itemPtr;			/* Line 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. */{    LineItem *linePtr = (LineItem *) itemPtr;    double *coordPtr;    int i;    /*     * Delete any arrowheads before scaling all the points (so that     * the end-points of the line get restored).     */    if (linePtr->firstArrowPtr != NULL) {	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];	ckfree((char *) linePtr->firstArrowPtr);	linePtr->firstArrowPtr = NULL;    }    if (linePtr->lastArrowPtr != NULL) {	int i;	i = 2*(linePtr->numPoints-1);	linePtr->coordPtr[i] = linePtr->lastArrowPtr[0];	linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1];	ckfree((char *) linePtr->lastArrowPtr);	linePtr->lastArrowPtr = NULL;    }    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;	    i++, coordPtr += 2) {	coordPtr[0] = originX + scaleX*(*coordPtr - originX);	coordPtr[1] = originY + scaleY*(coordPtr[1] - originY);    }    if (linePtr->arrow != noneUid) {	ConfigureArrows(canvas, linePtr);    }    ComputeLineBbox(canvas, linePtr);}/* *-------------------------------------------------------------- * * TranslateLine -- * *	This procedure is called to move a line by a given amount. * * Results: *	None. * * Side effects: *	The position of the line is offset by (xDelta, yDelta), and *	the bounding box is updated in the generic part of the item *	structure. * *-------------------------------------------------------------- */static voidTranslateLine(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. */{    LineItem *linePtr = (LineItem *) itemPtr;    double *coordPtr;    int i;    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;	    i++, coordPtr += 2) {	coordPtr[0] += deltaX;	coordPtr[1] += deltaY;    }    if (linePtr->firstArrowPtr != NULL) {	for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;		i++, coordPtr += 2) {	    coordPtr[0] += deltaX;	    coordPtr[1] += deltaY;	}    }    if (linePtr->lastArrowPtr != NULL) {	for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;		i++, coordPtr += 2) {	    coordPtr[0] += deltaX;	    coordPtr[1] += deltaY;	}    }    ComputeLineBbox(canvas, linePtr);}/* *-------------------------------------------------------------- * * ParseArrowShape -- * *	This procedure is called back during option parsing to *	parse arrow shape information. * * Results: *	The return value is a standard Tcl result:  TCL_OK means *	that the arrow shape information was parsed ok, and *	TCL_ERROR means it couldn't be parsed. * * Side effects: *	Arrow information in recordPtr is updated. * *-------------------------------------------------------------- */	/* ARGSUSED */static intParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)    ClientData clientData;	/* Not used. */    Tcl_Interp *interp;		/* Used for error reporting. */    Tk_Window tkwin;		/* Not used. */

⌨️ 快捷键说明

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