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

📄 miarc.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
	    fTricky = FALSE;	    pDrawTo = pDraw;	    pGCTo = pGC;	    break;	  default:	    fTricky = TRUE;	    /* find bounding box around arcs */	    xMin = yMin = MAXSHORT;	    xMax = yMax = MINSHORT;	    for(i = narcs, parc = parcs; --i >= 0; parc++)	    {		xMin = min (xMin, parc->x);		yMin = min (yMin, parc->y);		xMax = max (xMax, (parc->x + (int) parc->width));		yMax = max (yMax, (parc->y + (int) parc->height));	    }	    /* expand box to deal with line widths */	    halfWidth = (width + 1)/2;	    xMin -= halfWidth;	    yMin -= halfWidth;	    xMax += halfWidth;	    yMax += halfWidth;	    /* compute pixmap size; limit it to size of drawable */	    xOrg = max(xMin, 0);	    yOrg = max(yMin, 0);	    pixmapWidth = min(xMax, pDraw->width) - xOrg;	    pixmapHeight = min(yMax, pDraw->height) - yOrg;	    /* if nothing left, return */	    if ( (pixmapWidth <= 0) || (pixmapHeight <= 0) ) return;	    for(i = narcs, parc = parcs; --i >= 0; parc++)	    {		parc->x -= xOrg;		parc->y -= yOrg;	    }	    if (pGC->miTranslate)	    {		xOrg += pDraw->x;		yOrg += pDraw->y;	    }	    /* set up scratch GC */	    pGCTo = GetScratchGC(1, pDraw->pScreen);	    if (!pGCTo)		return;	    gcvals[GCValsFunction] = GXcopy;	    gcvals[GCValsForeground] = 1;	    gcvals[GCValsBackground] = 0;	    gcvals[GCValsLineWidth] = pGC->lineWidth;	    gcvals[GCValsCapStyle] = pGC->capStyle;	    gcvals[GCValsJoinStyle] = pGC->joinStyle;	    dixChangeGC(NullClient, pGCTo, GCValsMask, gcvals, NULL);    	    /* allocate a 1 bit deep pixmap of the appropriate size, and	     * validate it */	    pDrawTo = (DrawablePtr)(*pDraw->pScreen->CreatePixmap)				(pDraw->pScreen, pixmapWidth, pixmapHeight, 1);	    if (!pDrawTo)	    {		FreeScratchGC(pGCTo);		return;	    }	    ValidateGC(pDrawTo, pGCTo);	    miClearDrawable(pDrawTo, pGCTo);	}	fg = pGC->fgPixel;	bg = pGC->bgPixel;	if ((pGC->fillStyle == FillTiled) ||	    (pGC->fillStyle == FillOpaqueStippled))	    bg = fg; /* the protocol sez these don't cause color changes */	polyArcs = miComputeArcs (parcs, narcs, pGC);	if (!polyArcs)	{	    if (fTricky) {		(*pDraw->pScreen->DestroyPixmap) ((PixmapPtr)pDrawTo);		FreeScratchGC (pGCTo);	    }	    return;	}	cap[0] = cap[1] = 0;	join[0] = join[1] = 0;	for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0); 	     iphase >= 0;	     iphase--)	{	    if (iphase == 1) {		dixChangeGC (NullClient, pGC, GCForeground, &bg, NULL);		ValidateGC (pDraw, pGC);	    } else if (pGC->lineStyle == LineDoubleDash) {		dixChangeGC (NullClient, pGC, GCForeground, &fg, NULL);		ValidateGC (pDraw, pGC);	    }	    for (i = 0; i < polyArcs[iphase].narcs; i++) {		miArcDataPtr	arcData;		arcData = &polyArcs[iphase].arcs[i];		miArcSegment(pDrawTo, pGCTo, arcData->arc,			     &arcData->bounds[RIGHT_END],			     &arcData->bounds[LEFT_END]);		if (polyArcs[iphase].arcs[i].render) {		    fillSpans (pDrawTo, pGCTo);		    /*		     * don't cap self-joining arcs		     */		    if (polyArcs[iphase].arcs[i].selfJoin &&		        cap[iphase] < polyArcs[iphase].arcs[i].cap)		    	cap[iphase]++;		    while (cap[iphase] < polyArcs[iphase].arcs[i].cap) {			int	arcIndex, end;			miArcDataPtr	arcData0;			arcIndex = polyArcs[iphase].caps[cap[iphase]].arcIndex;			end = polyArcs[iphase].caps[cap[iphase]].end;			arcData0 = &polyArcs[iphase].arcs[arcIndex];			miArcCap (pDrawTo, pGCTo, 				  &arcData0->bounds[end], end,				  arcData0->arc.x, arcData0->arc.y,				  (double) arcData0->arc.width / 2.0, 				  (double) arcData0->arc.height / 2.0);			++cap[iphase];		    }		    while (join[iphase] < polyArcs[iphase].arcs[i].join) {			int	arcIndex0, arcIndex1, end0, end1;			int	phase0, phase1;			miArcDataPtr	arcData0, arcData1;			miArcJoinPtr	joinp;			joinp = &polyArcs[iphase].joins[join[iphase]];			arcIndex0 = joinp->arcIndex0;			end0 = joinp->end0;			arcIndex1 = joinp->arcIndex1;			end1 = joinp->end1;			phase0 = joinp->phase0;			phase1 = joinp->phase1;			arcData0 = &polyArcs[phase0].arcs[arcIndex0];			arcData1 = &polyArcs[phase1].arcs[arcIndex1];			miArcJoin (pDrawTo, pGCTo,				  &arcData0->bounds[end0], 				  &arcData1->bounds[end1],				  arcData0->arc.x, arcData0->arc.y,				  (double) arcData0->arc.width / 2.0, 				  (double) arcData0->arc.height / 2.0,				  arcData1->arc.x, arcData1->arc.y,				  (double) arcData1->arc.width / 2.0, 				  (double) arcData1->arc.height / 2.0);			++join[iphase];		    }		    if (fTricky) {			if (pGC->serialNumber != pDraw->serialNumber)			    ValidateGC (pDraw, pGC);		    	(*pGC->ops->PushPixels) (pGC, (PixmapPtr)pDrawTo,				 pDraw, pixmapWidth, pixmapHeight, xOrg, yOrg);			miClearDrawable ((DrawablePtr) pDrawTo, pGCTo);		    }		}	    }	}	miFreeArcs(polyArcs, pGC);	if(fTricky)	{	    (*pGCTo->pScreen->DestroyPixmap)((PixmapPtr)pDrawTo);	    FreeScratchGC(pGCTo);	}    }}static doubleangleBetween (center, point1, point2)	SppPointRec	center, point1, point2;{	double	a1, a2, a;		/*	 * reflect from X coordinates back to ellipse	 * coordinates -- y increasing upwards	 */	a1 = miDatan2 (- (point1.y - center.y), point1.x - center.x);	a2 = miDatan2 (- (point2.y - center.y), point2.x - center.x);	a = a2 - a1;	if (a <= -180.0)		a += 360.0;	else if (a > 180.0)		a -= 360.0;	return a;}static voidtranslateBounds (b, x, y, fx, fy)miArcFacePtr	b;int		x, y;double		fx, fy;{	fx += x;	fy += y;	b->clock.x -= fx;	b->clock.y -= fy;	b->center.x -= fx;	b->center.y -= fy;	b->counterClock.x -= fx;	b->counterClock.y -= fy;}static voidmiArcJoin (pDraw, pGC, pLeft, pRight,	   xOrgLeft, yOrgLeft, xFtransLeft, yFtransLeft,	   xOrgRight, yOrgRight, xFtransRight, yFtransRight)	DrawablePtr	pDraw;	GCPtr		pGC;	miArcFacePtr	pRight, pLeft;	int		xOrgRight, yOrgRight;	double		xFtransRight, yFtransRight;	int		xOrgLeft, yOrgLeft;	double		xFtransLeft, yFtransLeft;{	SppPointRec	center, corner, otherCorner;	SppPointRec	poly[5], e;	SppPointPtr	pArcPts;	int		cpt;	SppArcRec	arc;	miArcFaceRec	Right, Left;	int		polyLen;	int		xOrg, yOrg;	double		xFtrans, yFtrans;	double		a;	double		ae, ac2, ec2, bc2, de;	double		width;		xOrg = (xOrgRight + xOrgLeft) / 2;	yOrg = (yOrgRight + yOrgLeft) / 2;	xFtrans = (xFtransLeft + xFtransRight) / 2;	yFtrans = (yFtransLeft + yFtransRight) / 2;	Right = *pRight;	translateBounds (&Right, xOrg - xOrgRight, yOrg - yOrgRight,				 xFtrans - xFtransRight, yFtrans - yFtransRight);	Left = *pLeft;	translateBounds (&Left, xOrg - xOrgLeft, yOrg - yOrgLeft,				 xFtrans - xFtransLeft, yFtrans - yFtransLeft);	pRight = &Right;	pLeft = &Left;	if (pRight->clock.x == pLeft->counterClock.x &&	    pRight->clock.y == pLeft->counterClock.y)		return;	center = pRight->center;	if (0 <= (a = angleBetween (center, pRight->clock, pLeft->counterClock)) 	    && a <= 180.0) 	{		corner = pRight->clock;		otherCorner = pLeft->counterClock;	} else {		a = angleBetween (center, pLeft->clock, pRight->counterClock);		corner = pLeft->clock;		otherCorner = pRight->counterClock;	}	switch (pGC->joinStyle) {	case JoinRound:		width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1);		arc.x = center.x - width/2;		arc.y = center.y - width/2;		arc.width = width;		arc.height = width;		arc.angle1 = -miDatan2 (corner.y - center.y, corner.x - center.x);		arc.angle2 = a;		pArcPts = (SppPointPtr) xalloc (3 * sizeof (SppPointRec));		if (!pArcPts)		    return;		pArcPts[0].x = otherCorner.x;		pArcPts[0].y = otherCorner.y;		pArcPts[1].x = center.x;		pArcPts[1].y = center.y;		pArcPts[2].x = corner.x;		pArcPts[2].y = corner.y;		if( (cpt = miGetArcPts(&arc, 3, &pArcPts)) )		{			/* by drawing with miFillSppPoly and setting the endpoints of the arc			 * to be the corners, we assure that the cap will meet up with the			 * rest of the line */			miFillSppPoly(pDraw, pGC, cpt, pArcPts, xOrg, yOrg, xFtrans, yFtrans);		}		xfree(pArcPts);		return;	case JoinMiter:		/*		 * don't miter arcs with less than 11 degrees between them		 */		if (a < 169.0) {			poly[0] = corner;			poly[1] = center;			poly[2] = otherCorner;			bc2 = (corner.x - otherCorner.x) * (corner.x - otherCorner.x) +			      (corner.y - otherCorner.y) * (corner.y - otherCorner.y);			ec2 = bc2 / 4;			ac2 = (corner.x - center.x) * (corner.x - center.x) +			      (corner.y - center.y) * (corner.y - center.y);			ae = sqrt (ac2 - ec2);			de = ec2 / ae;			e.x = (corner.x + otherCorner.x) / 2;			e.y = (corner.y + otherCorner.y) / 2;			poly[3].x = e.x + de * (e.x - center.x) / ae;			poly[3].y = e.y + de * (e.y - center.y) / ae;			poly[4] = corner;			polyLen = 5;			break;		}	case JoinBevel:		poly[0] = corner;		poly[1] = center;		poly[2] = otherCorner;		poly[3] = corner;		polyLen = 4;		break;	}	miFillSppPoly (pDraw, pGC, polyLen, poly, xOrg, yOrg, xFtrans, yFtrans);}/*ARGSUSED*/static voidmiArcCap (pDraw, pGC, pFace, end, xOrg, yOrg, xFtrans, yFtrans)	DrawablePtr	pDraw;	GCPtr		pGC;	miArcFacePtr	pFace;	int		end;	int		xOrg, yOrg;	double		xFtrans, yFtrans;{	SppPointRec	corner, otherCorner, center, endPoint, poly[5];	corner = pFace->clock;	otherCorner = pFace->counterClock;	center = pFace->center;	switch (pGC->capStyle) {	case CapProjecting:		poly[0].x = otherCorner.x;		poly[0].y = otherCorner.y;		poly[1].x = corner.x;		poly[1].y = corner.y;		poly[2].x = corner.x - 				(center.y - corner.y);		poly[2].y = corner.y + 				(center.x - corner.x);		poly[3].x = otherCorner.x - 				(otherCorner.y - center.y);		poly[3].y = otherCorner.y + 				(otherCorner.x - center.x);		poly[4].x = otherCorner.x;		poly[4].y = otherCorner.y;		miFillSppPoly (pDraw, pGC, 5, poly, xOrg, yOrg, xFtrans, yFtrans);		break;	case CapRound:		/*		 * miRoundCap just needs these to be unequal.		 */		endPoint = center;		endPoint.x = endPoint.x + 100;		miRoundCap (pDraw, pGC, center, endPoint, corner, otherCorner, 0,			    -xOrg, -yOrg, xFtrans, yFtrans);		break;	}}/* MIROUNDCAP -- a private helper function * Put Rounded cap on end. pCenter is the center of this end of the line * pEnd is the center of the other end of the line. pCorner is one of the * two corners at this end of the line.   * NOTE:  pOtherCorner must be counter-clockwise from pCorner. *//*ARGSUSED*/static voidmiRoundCap(pDraw, pGC, pCenter, pEnd, pCorner, pOtherCorner, fLineEnd,     xOrg, yOrg, xFtrans, yFtrans)    DrawablePtr	pDraw;    GCPtr	pGC;    SppPointRec	pCenter, pEnd;    SppPointRec	pCorner, pOtherCorner;    int		fLineEnd, xOrg, yOrg;    double	xFtrans, yFtrans;{    int		cpt;    double	width;    double	miDatan2 ();    SppArcRec	arc;    SppPointPtr	pArcPts;    width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1);    arc.x = pCenter.x - width/2;    arc.y = pCenter.y - width/2;    arc.width = width;    arc.height = width;    arc.angle1 = -miDatan2 (pCorner.y - pCenter.y, pCorner.x - pCenter.x);    if(PTISEQUAL(pCenter, pEnd))	arc.angle2 = - 180.0;    else {	arc.angle2 = -miDatan2 (pOtherCorner.y - pCenter.y, pOtherCorner.x - pCenter.x) - arc.angle1;	if (arc.angle2 < 0)	    arc.angle2 += 360.0;    }    pArcPts = (SppPointPtr) NULL;    if( (cpt = miGetArcPts(&arc, 0, &pArcPts)) )    {	/* by drawing with miFillSppPoly and setting the endpoints of the arc	 * to be the corners, we assure that the cap will meet up with the	 * rest of the line */	miFillSppPoly(pDraw, pGC, cpt, pArcPts, -xOrg, -yOrg, xFtrans, yFtrans);    }    xfree(pArcPts);}/* * To avoid inaccuracy at the cardinal points, use trig functions * which are exact for those angles */#ifndef M_PI#define M_PI	3.14159265358979323846#endif#ifndef M_PI_2#define M_PI_2	1.57079632679489661923#endif# define Dsin(d)	((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))# define Dcos(d)	((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))# define mod(a,b)	((a) >= 0 ? (a) % (b) : (b) - (-a) % (b))static doublemiDcos (a)double	a;{	int	i;	if (floor (a/90) == a/90) {		i = (int) (a/90.0);		switch (mod (i, 4)) {		case 0: return 1;		case 1: return 0;		case 2: return -1;		case 3: return 0;		}	}	return cos (a * M_PI / 180.0);}static doublemiDsin (a)double	a;{	int	i;	if (floor (a/90) == a/90) {		i = (int) (a/90.0);		switch (mod (i, 4)) {		case 0: return 0;		case 1: return 1;		case 2: return 0;		case 3: return -1;		}	}	return sin (a * M_PI / 180.0);}static doublemiDasin (v)double	v;{    if (v == 0)	return 0.0;    if (v == 1.0)	return 90.0;    if (v == -1.0)	return -90.0;    return asin(v) * (180.0 / M_PI);}static doublemiDatan2 (dy, dx)double	dy, dx;{    if (dy == 0) {	if (dx >= 0)	    return 0.0;	return 180.0;    } else if (dx == 0) {	if (dy > 0)	    return 90.0;	return -90.0;    } else if (Fabs (dy) == Fabs (dx)) {	if (dy > 0) {	    if (dx > 0)		return 45.0;	    return 135.0;	} else {	    if (dx > 0)		return 315.0;	    return 225.0;	}    } else {	return atan2 (dy, dx) * (180.0 / M_PI);    }}/* MIGETARCPTS -- Converts an arc into a set of line segments -- a helper * routine for filled arc and line (round cap) code. * Returns the number of points in the arc.  Note that it takes a pointer * to a pointer to where it should put the points and an index (cpt). * This procedure allocates the space necessary to fit the arc points. * Sometimes it's convenient for those points to be at the end of an existing * array. (For example, if we want to leave a spare point to make sectors * instead of segments.)  So we pass in the xalloc()ed chunk that contains the * array and an index saying where we should start stashing the points. * If there isn't an array already, we just pass in a null pointer and  * count on xrealloc() to handle the null pointer correctly. */static intmiGetArcPts(parc, cpt, ppPts)    SppArcPtr	parc;	/* points to an arc */    int		cpt;	/* number of points already in arc list */    SppPointPtr	*ppPts; /* pointer to pointer to arc-list -- modified */{    double 	st,	/* Start Theta, start angle */                et,	/* End Theta, offset from start theta */		dt,	/* Delta Theta, angle to sweep ellipse */		cdt,	/* Cos Delta Theta, actually 2 cos(dt) */    		x0, y0,	/* the recurrence formula needs two points to start */		x1, y1,		x2, y2, /* this will be the new point generated */		xc, yc; /* the center point */    int		count, i;    SppPointPtr	poly;    DDXPointRec last;		/* last point on integer boundaries */    /* The spec says that positive angles indicate counterclockwise motion.     * Given our coordinate system (with 0,0 in the upper left corner),      * the screen appears flipped in Y.  The easiest fix is to negate the     * angles given */        st = - parc->angle1;    et = - parc->angle2;    /* Try to get a delta theta that is within 1/2 pixel.  Then adjust it

⌨️ 快捷键说明

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