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

📄 tkcanvarc.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    if (arcPtr->fillGC != None) {	Tk_FreeGC(Tk_Display(tkwin), arcPtr->fillGC);    }    arcPtr->fillGC = newGC;    ComputeArcBbox(canvas, arcPtr);    return TCL_OK;}/* *-------------------------------------------------------------- * * DeleteArc -- * *	This procedure is called to clean up the data structure *	associated with a arc item. * * Results: *	None. * * Side effects: *	Resources associated with itemPtr are released. * *-------------------------------------------------------------- */static voidDeleteArc(canvas, itemPtr, display)    Tk_Canvas canvas;			/* Info about overall canvas. */    Tk_Item *itemPtr;			/* Item that is being deleted. */    Display *display;			/* Display containing window for					 * canvas. */{    ArcItem *arcPtr = (ArcItem *) itemPtr;    if (arcPtr->numOutlinePoints != 0) {	ckfree((char *) arcPtr->outlinePtr);    }    if (arcPtr->outlineColor != NULL) {	Tk_FreeColor(arcPtr->outlineColor);    }    if (arcPtr->fillColor != NULL) {	Tk_FreeColor(arcPtr->fillColor);    }    if (arcPtr->fillStipple != None) {	Tk_FreeBitmap(display, arcPtr->fillStipple);    }    if (arcPtr->outlineStipple != None) {	Tk_FreeBitmap(display, arcPtr->outlineStipple);    }    if (arcPtr->outlineGC != None) {	Tk_FreeGC(display, arcPtr->outlineGC);    }    if (arcPtr->fillGC != None) {	Tk_FreeGC(display, arcPtr->fillGC);    }}/* *-------------------------------------------------------------- * * ComputeArcBbox -- * *	This procedure is invoked to compute the bounding box of *	all the pixels that may be drawn as part of an arc. * * Results: *	None. * * Side effects: *	The fields x1, y1, x2, and y2 are updated in the header *	for itemPtr. * *-------------------------------------------------------------- */	/* ARGSUSED */static voidComputeArcBbox(canvas, arcPtr)    Tk_Canvas canvas;			/* Canvas that contains item. */    ArcItem *arcPtr;			/* Item whose bbox is to be					 * recomputed. */{    double tmp, center[2], point[2];    /*     * Make sure that the first coordinates are the lowest ones.     */    if (arcPtr->bbox[1] > arcPtr->bbox[3]) {	double tmp;	tmp = arcPtr->bbox[3];	arcPtr->bbox[3] = arcPtr->bbox[1];	arcPtr->bbox[1] = tmp;    }    if (arcPtr->bbox[0] > arcPtr->bbox[2]) {	double tmp;	tmp = arcPtr->bbox[2];	arcPtr->bbox[2] = arcPtr->bbox[0];	arcPtr->bbox[0] = tmp;    }    ComputeArcOutline(arcPtr);    /*     * To compute the bounding box, start with the the bbox formed     * by the two endpoints of the arc.  Then add in the center of     * the arc's oval (if relevant) and the 3-o'clock, 6-o'clock,     * 9-o'clock, and 12-o'clock positions, if they are relevant.     */    arcPtr->header.x1 = arcPtr->header.x2 = (int) arcPtr->center1[0];    arcPtr->header.y1 = arcPtr->header.y2 = (int) arcPtr->center1[1];    TkIncludePoint((Tk_Item *) arcPtr, arcPtr->center2);    center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2;    center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2;    if (arcPtr->style == pieSliceUid) {	TkIncludePoint((Tk_Item *) arcPtr, center);    }    tmp = -arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	point[0] = arcPtr->bbox[2];	point[1] = center[1];	TkIncludePoint((Tk_Item *) arcPtr, point);    }    tmp = 90.0 - arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	point[0] = center[0];	point[1] = arcPtr->bbox[1];	TkIncludePoint((Tk_Item *) arcPtr, point);    }    tmp = 180.0 - arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	point[0] = arcPtr->bbox[0];	point[1] = center[1];	TkIncludePoint((Tk_Item *) arcPtr, point);    }    tmp = 270.0 - arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	point[0] = center[0];	point[1] = arcPtr->bbox[3];	TkIncludePoint((Tk_Item *) arcPtr, point);    }    /*     * Lastly, expand by the width of the arc (if the arc's outline is     * being drawn) and add one extra pixel just for safety.     */    if (arcPtr->outlineColor == NULL) {	tmp = 1;    } else {	tmp = (arcPtr->width + 1)/2 + 1;    }    arcPtr->header.x1 -= (int) tmp;    arcPtr->header.y1 -= (int) tmp;    arcPtr->header.x2 += (int) tmp;    arcPtr->header.y2 += (int) tmp;}/* *-------------------------------------------------------------- * * DisplayArc -- * *	This procedure is invoked to draw an arc item in a given *	drawable. * * Results: *	None. * * Side effects: *	ItemPtr is drawn in drawable using the transformation *	information in canvas. * *-------------------------------------------------------------- */static voidDisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)    Tk_Canvas canvas;			/* Canvas that contains item. */    Tk_Item *itemPtr;			/* Item to be displayed. */    Display *display;			/* Display on which to draw item. */    Drawable drawable;			/* Pixmap or window in which to draw					 * item. */    int x, y, width, height;		/* Describes region of canvas that					 * must be redisplayed (not used). */{    ArcItem *arcPtr = (ArcItem *) itemPtr;    short x1, y1, x2, y2;    int start, extent;    /*     * Compute the screen coordinates of the bounding box for the item,     * plus integer values for the angles.     */    Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[0], arcPtr->bbox[1],	    &x1, &y1);    Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[2], arcPtr->bbox[3],	    &x2, &y2);    if (x2 <= x1) {	x2 = x1+1;    }    if (y2 <= y1) {	y2 = y1+1;    }    start = (int) ((64*arcPtr->start) + 0.5);    extent = (int) ((64*arcPtr->extent) + 0.5);    /*     * Display filled arc first (if wanted), then outline.  If the extent     * is zero then don't invoke XFillArc or XDrawArc, since this causes     * some window servers to crash and should be a no-op anyway.     */    if ((arcPtr->fillGC != None) && (extent != 0)) {	if (arcPtr->fillStipple != None) {	    Tk_CanvasSetStippleOrigin(canvas, arcPtr->fillGC);	}	XFillArc(display, drawable, arcPtr->fillGC, x1, y1, (unsigned) (x2-x1),		(unsigned) (y2-y1), start, extent);	if (arcPtr->fillStipple != None) {	    XSetTSOrigin(display, arcPtr->fillGC, 0, 0);	}    }    if (arcPtr->outlineGC != None) {	if (arcPtr->outlineStipple != None) {	    Tk_CanvasSetStippleOrigin(canvas, arcPtr->outlineGC);	}	if (extent != 0) {	    XDrawArc(display, drawable, arcPtr->outlineGC, x1, y1,		    (unsigned) (x2-x1), (unsigned) (y2-y1), start, extent);	}	/*	 * If the outline width is very thin, don't use polygons to draw	 * the linear parts of the outline (this often results in nothing	 * being displayed); just draw lines instead.	 */	if (arcPtr->width <= 2) {	    Tk_CanvasDrawableCoords(canvas, arcPtr->center1[0],		    arcPtr->center1[1], &x1, &y1);	    Tk_CanvasDrawableCoords(canvas, arcPtr->center2[0],		    arcPtr->center2[1], &x2, &y2);	    if (arcPtr->style == chordUid) {		XDrawLine(display, drawable, arcPtr->outlineGC,			x1, y1, x2, y2);	    } else if (arcPtr->style == pieSliceUid) {		short cx, cy;		Tk_CanvasDrawableCoords(canvas,			(arcPtr->bbox[0] + arcPtr->bbox[2])/2.0,			(arcPtr->bbox[1] + arcPtr->bbox[3])/2.0, &cx, &cy);		XDrawLine(display, drawable, arcPtr->outlineGC,			cx, cy, x1, y1);		XDrawLine(display, drawable, arcPtr->outlineGC,			cx, cy, x2, y2);	    }	} else {	    if (arcPtr->style == chordUid) {		TkFillPolygon(canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS,			display, drawable, arcPtr->outlineGC, None);	    } else if (arcPtr->style == pieSliceUid) {		TkFillPolygon(canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS,			display, drawable, arcPtr->outlineGC, None);		TkFillPolygon(canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,			PIE_OUTLINE2_PTS, display, drawable, arcPtr->outlineGC,			None);	    }	}	if (arcPtr->outlineStipple != None) {	    XSetTSOrigin(display, arcPtr->outlineGC, 0, 0);	}    }}/* *-------------------------------------------------------------- * * ArcToPoint -- * *	Computes the distance from a given point to a given *	arc, in canvas units. * * Results: *	The return value is 0 if the point whose x and y coordinates *	are coordPtr[0] and coordPtr[1] is inside the arc.  If the *	point isn't inside the arc then the return value is the *	distance from the point to the arc.  If itemPtr is filled, *	then anywhere in the interior is considered "inside"; if *	itemPtr isn't filled, then "inside" means only the area *	occupied by the outline. * * Side effects: *	None. * *-------------------------------------------------------------- */	/* ARGSUSED */static doubleArcToPoint(canvas, itemPtr, pointPtr)    Tk_Canvas canvas;		/* Canvas containing item. */    Tk_Item *itemPtr;		/* Item to check against point. */    double *pointPtr;		/* Pointer to x and y coordinates. */{    ArcItem *arcPtr = (ArcItem *) itemPtr;    double vertex[2], pointAngle, diff, dist, newDist;    double poly[8], polyDist, width, t1, t2;    int filled, angleInRange;    /*     * See if the point is within the angular range of the arc.     * Remember, X angles are backwards from the way we'd normally     * think of them.  Also, compensate for any eccentricity of     * the oval.     */    vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;    vertex[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;    t1 = (pointPtr[1] - vertex[1])/(arcPtr->bbox[3] - arcPtr->bbox[1]);    t2 = (pointPtr[0] - vertex[0])/(arcPtr->bbox[2] - arcPtr->bbox[0]);    if ((t1 == 0.0) && (t2 == 0.0)) {	pointAngle = 0;    } else {	pointAngle = -atan2(t1, t2)*180/PI;    }    diff = pointAngle - arcPtr->start;    diff -= ((int) (diff/360.0) * 360.0);    if (diff < 0) {	diff += 360.0;    }    angleInRange = (diff <= arcPtr->extent) ||	    ((arcPtr->extent < 0) && ((diff - 360.0) >= arcPtr->extent));    /*     * Now perform different tests depending on what kind of arc     * we're dealing with.     */    if (arcPtr->style == arcUid) {	if (angleInRange) {	    return TkOvalToPoint(arcPtr->bbox, (double) arcPtr->width,		    0, pointPtr);	}	dist = hypot(pointPtr[0] - arcPtr->center1[0],		pointPtr[1] - arcPtr->center1[1]);	newDist = hypot(pointPtr[0] - arcPtr->center2[0],		pointPtr[1] - arcPtr->center2[1]);	if (newDist < dist) {	    return newDist;	}	return dist;    }    if ((arcPtr->fillGC != None) || (arcPtr->outlineGC == None)) {	filled = 1;    } else {	filled = 0;    }    if (arcPtr->outlineGC == None) {	width = 0.0;    } else {	width = arcPtr->width;    }    if (arcPtr->style == pieSliceUid) {	if (width > 1.0) {	    dist = TkPolygonToPoint(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,		    pointPtr);	    newDist = TkPolygonToPoint(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,			PIE_OUTLINE2_PTS, pointPtr);	} else {	    dist = TkLineToPoint(vertex, arcPtr->center1, pointPtr);	    newDist = TkLineToPoint(vertex, arcPtr->center2, pointPtr);	}	if (newDist < dist) {	    dist = newDist;	}	if (angleInRange) {	    newDist = TkOvalToPoint(arcPtr->bbox, width, filled, pointPtr);	    if (newDist < dist) {		dist = newDist;	    }	}	return dist;    }    /*     * This is a chord-style arc.  We have to deal specially with the     * triangular piece that represents the difference between a     * chord-style arc and a pie-slice arc (for small angles this piece     * is excluded here where it would be included for pie slices;     * for large angles the piece is included here but would be     * excluded for pie slices).     */    if (width > 1.0) {	dist = TkPolygonToPoint(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,		    pointPtr);    } else {	dist = TkLineToPoint(arcPtr->center1, arcPtr->center2, pointPtr);    }    poly[0] = poly[6] = vertex[0];    poly[1] = poly[7] = vertex[1];    poly[2] = arcPtr->center1[0];    poly[3] = arcPtr->center1[1];    poly[4] = arcPtr->center2[0];    poly[5] = arcPtr->center2[1];    polyDist = TkPolygonToPoint(poly, 4, pointPtr);    if (angleInRange) {	if ((arcPtr->extent < -180.0) || (arcPtr->extent > 180.0)		|| (polyDist > 0.0)) {

⌨️ 快捷键说明

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