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

📄 tkcanvline.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
    char *value;		/* Textual specification of arrow shape. */    char *recordPtr;		/* Pointer to item record in which to				 * store arrow information. */    int offset;			/* Offset of shape information in widget				 * record. */{    LineItem *linePtr = (LineItem *) recordPtr;    double a, b, c;    int argc;    char **argv = NULL;    if (offset != Tk_Offset(LineItem, arrowShapeA)) {	panic("ParseArrowShape received bogus offset");    }    if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {	syntaxError:	Tcl_ResetResult(interp);	Tcl_AppendResult(interp, "bad arrow shape \"", value,		"\": must be list with three numbers", (char *) NULL);	if (argv != NULL) {	    ckfree((char *) argv);	}	return TCL_ERROR;    }    if (argc != 3) {	goto syntaxError;    }    if ((Tk_CanvasGetCoord(interp, linePtr->canvas, argv[0], &a) != TCL_OK)	    || (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[1], &b)		!= TCL_OK)	    || (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[2], &c)		!= TCL_OK)) {	goto syntaxError;    }    linePtr->arrowShapeA = (float)a;    linePtr->arrowShapeB = (float)b;    linePtr->arrowShapeC = (float)c;    ckfree((char *) argv);    return TCL_OK;}/* *-------------------------------------------------------------- * * PrintArrowShape -- * *	This procedure is a callback invoked by the configuration *	code to return a printable value describing an arrow shape. * * Results: *	None. * * Side effects: *	None. * *-------------------------------------------------------------- */    /* ARGSUSED */static char *PrintArrowShape(clientData, tkwin, recordPtr, offset, freeProcPtr)    ClientData clientData;	/* Not used. */    Tk_Window tkwin;		/* Window associated with linePtr's widget. */    char *recordPtr;		/* Pointer to item record containing current				 * shape information. */    int offset;			/* Offset of arrow information in record. */    Tcl_FreeProc **freeProcPtr;	/* Store address of procedure to call to				 * free string here. */{    LineItem *linePtr = (LineItem *) recordPtr;    char *buffer;    buffer = (char *) ckalloc(120);    sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA,	    linePtr->arrowShapeB, linePtr->arrowShapeC);    *freeProcPtr = TCL_DYNAMIC;    return buffer;}/* *-------------------------------------------------------------- * * ConfigureArrows -- * *	If arrowheads have been requested for a line, this *	procedure makes arrangements for the arrowheads. * * Results: *	Always returns TCL_OK. * * Side effects: *	Information in linePtr is set up for one or two arrowheads. *	the firstArrowPtr and lastArrowPtr polygons are allocated *	and initialized, if need be, and the end points of the line *	are adjusted so that a thick line doesn't stick out past *	the arrowheads. * *-------------------------------------------------------------- */	/* ARGSUSED */static intConfigureArrows(canvas, linePtr)    Tk_Canvas canvas;			/* Canvas in which arrows will be					 * displayed (interp and tkwin					 * fields are needed). */    LineItem *linePtr;			/* Item to configure for arrows. */{    double *poly, *coordPtr;    double dx, dy, length, sinTheta, cosTheta, temp;    double fracHeight;			/* Line width as fraction of					 * arrowhead width. */    double backup;			/* Distance to backup end points					 * so the line ends in the middle					 * of the arrowhead. */    double vertX, vertY;		/* Position of arrowhead vertex. */    double shapeA, shapeB, shapeC;	/* Adjusted coordinates (see					 * explanation below). */    /*     * The code below makes a tiny increase in the shape parameters     * for the line.  This is a bit of a hack, but it seems to result     * in displays that more closely approximate the specified parameters.     * Without the adjustment, the arrows come out smaller than expected.     */    shapeA = linePtr->arrowShapeA + 0.001;    shapeB = linePtr->arrowShapeB + 0.001;    shapeC = linePtr->arrowShapeC + linePtr->width/2.0 + 0.001;    /*     * If there's an arrowhead on the first point of the line, compute     * its polygon and adjust the first point of the line so that the     * line doesn't stick out past the leading edge of the arrowhead.     */    fracHeight = (linePtr->width/2.0)/shapeC;    backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0;    if (linePtr->arrow != lastUid) {	poly = linePtr->firstArrowPtr;	if (poly == NULL) {	    poly = (double *) ckalloc((unsigned)		    (2*PTS_IN_ARROW*sizeof(double)));	    poly[0] = poly[10] = linePtr->coordPtr[0];	    poly[1] = poly[11] = linePtr->coordPtr[1];	    linePtr->firstArrowPtr = poly;	}	dx = poly[0] - linePtr->coordPtr[2];	dy = poly[1] - linePtr->coordPtr[3];	length = hypot(dx, dy);	if (length == 0) {	    sinTheta = cosTheta = 0.0;	} else {	    sinTheta = dy/length;	    cosTheta = dx/length;	}	vertX = poly[0] - shapeA*cosTheta;	vertY = poly[1] - shapeA*sinTheta;	temp = shapeC*sinTheta;	poly[2] = poly[0] - shapeB*cosTheta + temp;	poly[8] = poly[2] - 2*temp;	temp = shapeC*cosTheta;	poly[3] = poly[1] - shapeB*sinTheta - temp;	poly[9] = poly[3] + 2*temp;	poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight);	poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight);	poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight);	poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight);	/*	 * Polygon done.  Now move the first point towards the second so	 * that the corners at the end of the line are inside the	 * arrowhead.	 */	linePtr->coordPtr[0] = poly[0] - backup*cosTheta;	linePtr->coordPtr[1] = poly[1] - backup*sinTheta;    }    /*     * Similar arrowhead calculation for the last point of the line.     */    if (linePtr->arrow != firstUid) {	coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2);	poly = linePtr->lastArrowPtr;	if (poly == NULL) {	    poly = (double *) ckalloc((unsigned)		    (2*PTS_IN_ARROW*sizeof(double)));	    poly[0] = poly[10] = coordPtr[2];	    poly[1] = poly[11] = coordPtr[3];	    linePtr->lastArrowPtr = poly;	}	dx = poly[0] - coordPtr[0];	dy = poly[1] - coordPtr[1];	length = hypot(dx, dy);	if (length == 0) {	    sinTheta = cosTheta = 0.0;	} else {	    sinTheta = dy/length;	    cosTheta = dx/length;	}	vertX = poly[0] - shapeA*cosTheta;	vertY = poly[1] - shapeA*sinTheta;	temp = shapeC*sinTheta;	poly[2] = poly[0] - shapeB*cosTheta + temp;	poly[8] = poly[2] - 2*temp;	temp = shapeC*cosTheta;	poly[3] = poly[1] - shapeB*sinTheta - temp;	poly[9] = poly[3] + 2*temp;	poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight);	poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight);	poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight);	poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight);	coordPtr[2] = poly[0] - backup*cosTheta;	coordPtr[3] = poly[1] - backup*sinTheta;    }    return TCL_OK;}/* *-------------------------------------------------------------- * * LineToPostscript -- * *	This procedure is called to generate Postscript for *	line items. * * Results: *	The return value is a standard Tcl result.  If an error *	occurs in generating Postscript then an error message is *	left in interp->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 intLineToPostscript(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. */{    LineItem *linePtr = (LineItem *) itemPtr;    char buffer[200];    char *style;    if (linePtr->fg == NULL) {	return TCL_OK;    }    /*     * Generate a path for the line's center-line (do this differently     * for straight lines and smoothed lines).     */    if ((!linePtr->smooth) || (linePtr->numPoints <= 2)) {	Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints);    } else {	if (linePtr->fillStipple == None) {	    TkMakeBezierPostscript(interp, canvas, linePtr->coordPtr,		    linePtr->numPoints);	} else {	    /*	     * Special hack: Postscript printers don't appear to be able	     * to turn a path drawn with "curveto"s into a clipping path	     * without exceeding resource limits, so TkMakeBezierPostscript	     * won't work for stippled curves.  Instead, generate all of	     * the intermediate points here and output them into the	     * Postscript file with "lineto"s instead.	     */	    double staticPoints[2*MAX_STATIC_POINTS];	    double *pointPtr;	    int numPoints;	    numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;	    pointPtr = staticPoints;	    if (numPoints > MAX_STATIC_POINTS) {		pointPtr = (double *) ckalloc((unsigned)			(numPoints * 2 * sizeof(double)));	    }	    numPoints = TkMakeBezierCurve(canvas, linePtr->coordPtr,		    linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,		    pointPtr);	    Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints);	    if (pointPtr != staticPoints) {		ckfree((char *) pointPtr);	    }	}    }    /*     * Set other line-drawing parameters and stroke out the line.     */    sprintf(buffer, "%d setlinewidth\n", linePtr->width);    Tcl_AppendResult(interp, buffer, (char *) NULL);    style = "0 setlinecap\n";    if (linePtr->capStyle == CapRound) {	style = "1 setlinecap\n";    } else if (linePtr->capStyle == CapProjecting) {	style = "2 setlinecap\n";    }    Tcl_AppendResult(interp, style, (char *) NULL);    style = "0 setlinejoin\n";    if (linePtr->joinStyle == JoinRound) {	style = "1 setlinejoin\n";    } else if (linePtr->joinStyle == JoinBevel) {	style = "2 setlinejoin\n";    }    Tcl_AppendResult(interp, style, (char *) NULL);    if (Tk_CanvasPsColor(interp, canvas, linePtr->fg) != TCL_OK) {	return TCL_ERROR;    };    if (linePtr->fillStipple != None) {	Tcl_AppendResult(interp, "StrokeClip ", (char *) NULL);	if (Tk_CanvasPsStipple(interp, canvas, linePtr->fillStipple)		!= TCL_OK) {	    return TCL_ERROR;	}    } else {	Tcl_AppendResult(interp, "stroke\n", (char *) NULL);    }    /*     * Output polygons for the arrowheads, if there are any.     */    if (linePtr->firstArrowPtr != NULL) {	if (linePtr->fillStipple != None) {	    Tcl_AppendResult(interp, "grestore gsave\n",		    (char *) NULL);	}	if (ArrowheadPostscript(interp, canvas, linePtr,		linePtr->firstArrowPtr) != TCL_OK) {	    return TCL_ERROR;	}    }    if (linePtr->lastArrowPtr != NULL) {	if (linePtr->fillStipple != None) {	    Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);	}	if (ArrowheadPostscript(interp, canvas, linePtr,		linePtr->lastArrowPtr) != TCL_OK) {	    return TCL_ERROR;	}    }    return TCL_OK;}/* *-------------------------------------------------------------- * * ArrowheadPostscript -- * *	This procedure is called to generate Postscript for *	an arrowhead for a line item. * * Results: *	The return value is a standard Tcl result.  If an error *	occurs in generating Postscript then an error message is *	left in interp->result, replacing whatever used *	to be there.  If no error occurs, then Postscript for the *	arrowhead is appended to the result. * * Side effects: *	None. * *-------------------------------------------------------------- */static intArrowheadPostscript(interp, canvas, linePtr, arrowPtr)    Tcl_Interp *interp;			/* Leave Postscript or error message					 * here. */    Tk_Canvas canvas;			/* Information about overall canvas. */    LineItem *linePtr;			/* Line item for which Postscript is					 * being generated. */    double *arrowPtr;			/* Pointer to first of five points					 * describing arrowhead polygon. */{    Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);    if (linePtr->fillStipple != None) {	Tcl_AppendResult(interp, "clip ", (char *) NULL);	if (Tk_CanvasPsStipple(interp, canvas, linePtr->fillStipple)		!= TCL_OK) {	    return TCL_ERROR;	}    } else {	Tcl_AppendResult(interp, "fill\n", (char *) NULL);    }    return TCL_OK;}

⌨️ 快捷键说明

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