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

📄 miarc.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
     * so that it divides evenly into the total.     * I'm just using cdt 'cause I'm lazy.     */    cdt = parc->width;    if (parc->height > cdt)	cdt = parc->height;    cdt /= 2.0;    if(cdt <= 0)	return 0;    if (cdt < 1.0)	cdt = 1.0;    dt = miDasin ( 1.0 / cdt ); /* minimum step necessary */    count = et/dt;    count = abs(count) + 1;    dt = et/count;	    count++;    cdt = 2 * miDcos(dt);    if (!(poly = (SppPointPtr) xrealloc((pointer)*ppPts,					(cpt + count) * sizeof(SppPointRec))))	return(0);    *ppPts = poly;    xc = parc->width/2.0;		/* store half width and half height */    yc = parc->height/2.0;        x0 = xc * miDcos(st);    y0 = yc * miDsin(st);    x1 = xc * miDcos(st + dt);    y1 = yc * miDsin(st + dt);    xc += parc->x;		/* by adding initial point, these become */    yc += parc->y;		/* the center point */    poly[cpt].x = (xc + x0);    poly[cpt].y = (yc + y0);    last.x = ROUNDTOINT( poly[cpt + 1].x = (xc + x1) );    last.y = ROUNDTOINT( poly[cpt + 1].y = (yc + y1) );    for(i = 2; i < count; i++)    {	x2 = cdt * x1 - x0;	y2 = cdt * y1 - y0; 	poly[cpt + i].x = (xc + x2); 	poly[cpt + i].y = (yc + y2);	x0 = x1; y0 = y1;	x1 = x2; y1 = y2;    }    /* adjust the last point */    if (abs(parc->angle2) >= 360.0)	poly[cpt +i -1] = poly[0];    else {	poly[cpt +i -1].x = (miDcos(st + et) * parc->width/2.0 + xc);	poly[cpt +i -1].y = (miDsin(st + et) * parc->height/2.0 + yc);    }    return(count);}struct arcData {	double	x0, y0, x1, y1;	int	selfJoin;};# define ADD_REALLOC_STEP	20static voidaddCap (capsp, ncapsp, sizep, end, arcIndex)	miArcCapPtr	*capsp;	int		*ncapsp, *sizep;	int		end, arcIndex;{	int newsize;	miArcCapPtr	cap;	if (*ncapsp == *sizep)	{	    newsize = *sizep + ADD_REALLOC_STEP;	    cap = (miArcCapPtr) xrealloc (*capsp,					  newsize * sizeof (**capsp));	    if (!cap)		return;	    *sizep = newsize;	    *capsp = cap;	}	cap = &(*capsp)[*ncapsp];	cap->end = end;	cap->arcIndex = arcIndex;	++*ncapsp;}static voidaddJoin (joinsp, njoinsp, sizep, end0, index0, phase0, end1, index1, phase1)	miArcJoinPtr	*joinsp;	int		*njoinsp, *sizep;	int		end0, index0, phase0, end1, index1, phase1;{	int newsize;	miArcJoinPtr	join;	if (*njoinsp == *sizep)	{	    newsize = *sizep + ADD_REALLOC_STEP;	    join = (miArcJoinPtr) xrealloc (*joinsp,					    newsize * sizeof (**joinsp));	    if (!join)		return;	    *sizep = newsize;	    *joinsp = join;	}	join = &(*joinsp)[*njoinsp];	join->end0 = end0;	join->arcIndex0 = index0;	join->phase0 = phase0;	join->end1 = end1;	join->arcIndex1 = index1;	join->phase1 = phase1;	++*njoinsp;}static miArcDataPtraddArc (arcsp, narcsp, sizep, xarc)	miArcDataPtr	*arcsp;	int		*narcsp, *sizep;	xArc		*xarc;{	int newsize;	miArcDataPtr	arc;	if (*narcsp == *sizep)	{	    newsize = *sizep + ADD_REALLOC_STEP;	    arc = (miArcDataPtr) xrealloc (*arcsp,					   newsize * sizeof (**arcsp));	    if (!arc)		return (miArcDataPtr)NULL;	    *sizep = newsize;	    *arcsp = arc;	}	arc = &(*arcsp)[*narcsp];	arc->arc = *xarc;	++*narcsp;	return arc;}static voidmiFreeArcs(arcs, pGC)    miPolyArcPtr arcs;    GCPtr pGC;{	int iphase;	for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0); 	     iphase >= 0;	     iphase--)	{	    if (arcs[iphase].narcs > 0)		xfree(arcs[iphase].arcs);	    if (arcs[iphase].njoins > 0)		xfree(arcs[iphase].joins);	    if (arcs[iphase].ncaps > 0)		xfree(arcs[iphase].caps);	}	xfree(arcs);}/* * map angles to radial distance.  This only deals with the first quadrant *//* * a polygonal approximation to the arc for computing arc lengths */# define DASH_MAP_SIZE	91# define dashIndexToAngle(di)	((((double) (di)) * 90.0) / ((double) DASH_MAP_SIZE - 1))# define xAngleToDashIndex(xa)	((((long) (xa)) * (DASH_MAP_SIZE - 1)) / (90 * 64))# define dashIndexToXAngle(di)	((((long) (di)) * (90 * 64)) / (DASH_MAP_SIZE - 1))# define dashXAngleStep	(((double) (90 * 64)) / ((double) (DASH_MAP_SIZE - 1)))typedef struct {	double	map[DASH_MAP_SIZE];} dashMap;static voidcomputeDashMap (arcp, map)	xArc	*arcp;	dashMap	*map;{	int	di;	double	a, x, y, prevx, prevy, dist;	for (di = 0; di < DASH_MAP_SIZE; di++) {		a = dashIndexToAngle (di);		x = ((double) arcp->width / 2.0) * miDcos (a);		y = ((double) arcp->height / 2.0) * miDsin (a);		if (di == 0) {			map->map[di] = 0.0;		} else {			dist = hypot (x - prevx, y - prevy);			map->map[di] = map->map[di - 1] + dist;		}		prevx = x;		prevy = y;	}}typedef enum {HORIZONTAL, VERTICAL, OTHER} arcTypes;/* this routine is a bit gory */static miPolyArcPtrmiComputeArcs (parcs, narcs, pGC)	xArc	*parcs;	int	narcs;	GCPtr	pGC;{	int		isDashed, isDoubleDash;	int		dashOffset;	miPolyArcPtr	arcs;	int		start, i, j, k, nexti, nextk;	int		joinSize[2];	int		capSize[2];	int		arcSize[2];	int		angle2;	double		a0, a1;	struct arcData	*data;	miArcDataPtr	arc;	xArc		xarc;	int		iphase, prevphase, joinphase;	int		arcsJoin;	int		selfJoin;	int		iDash, dashRemaining;	int		iDashStart, dashRemainingStart, iphaseStart;	int		startAngle, spanAngle, endAngle, backwards;	int		prevDashAngle, dashAngle;	dashMap		map;	isDashed = !(pGC->lineStyle == LineSolid);	isDoubleDash = (pGC->lineStyle == LineDoubleDash);	dashOffset = pGC->dashOffset;	data = (struct arcData *) ALLOCATE_LOCAL (narcs * sizeof (struct arcData));	if (!data)	    return (miPolyArcPtr)NULL;	arcs = (miPolyArcPtr) xalloc (sizeof (*arcs) * (isDoubleDash ? 2 : 1));	if (!arcs)	{	    DEALLOCATE_LOCAL(data);	    return (miPolyArcPtr)NULL;	}	for (i = 0; i < narcs; i++) {		a0 = todeg (parcs[i].angle1);		angle2 = parcs[i].angle2;		if (angle2 > FULLCIRCLE)			angle2 = FULLCIRCLE;		else if (angle2 < -FULLCIRCLE)			angle2 = -FULLCIRCLE;		data[i].selfJoin = angle2 == FULLCIRCLE || angle2 == -FULLCIRCLE;		a1 = todeg (parcs[i].angle1 + angle2);		data[i].x0 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a0));		data[i].y0 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a0));		data[i].x1 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a1));		data[i].y1 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a1));	}	for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) {		arcs[iphase].njoins = 0;		arcs[iphase].joins = 0;		joinSize[iphase] = 0;				arcs[iphase].ncaps = 0;		arcs[iphase].caps = 0;		capSize[iphase] = 0;				arcs[iphase].narcs = 0;		arcs[iphase].arcs = 0;		arcSize[iphase] = 0;	}	iphase = 0;	if (isDashed) {		iDash = 0;		dashRemaining = pGC->dash[0];	 	while (dashOffset > 0) {			if (dashOffset >= dashRemaining) {				dashOffset -= dashRemaining;				iphase = iphase ? 0 : 1;				iDash++;				if (iDash == pGC->numInDashList)				    iDash = 0;				dashRemaining = pGC->dash[iDash];			} else {				dashRemaining -= dashOffset;				dashOffset = 0;			}		}		iDashStart = iDash;		dashRemainingStart = dashRemaining;	}	iphaseStart = iphase;	for (i = narcs - 1; i >= 0; i--) {		j = i + 1;		if (j == narcs)			j = 0;		if (data[i].selfJoin || i == j ||		     (UNEQUAL (data[i].x1, data[j].x0) ||		      UNEQUAL (data[i].y1, data[j].y0))) 		{			if (iphase == 0 || isDoubleDash)				addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,	 				&capSize[iphase], RIGHT_END, 0);			break;		}	}	start = i + 1;	if (start == narcs)		start = 0;	i = start;	for (;;) {		j = i + 1;		if (j == narcs)			j = 0;		nexti = i+1;		if (nexti == narcs)			nexti = 0;		if (isDashed) {			/*			** deal with dashed arcs.  Use special rules for certain 0 area arcs.			** Presumably, the other 0 area arcs still aren't done right.			*/			arcTypes	arcType = OTHER;			CARD16		thisLength;			if (parcs[i].height == 0			    && (parcs[i].angle1 % FULLCIRCLE) == 0x2d00			    && parcs[i].angle2 == 0x2d00) 				arcType = HORIZONTAL;			else if (parcs[i].width == 0			    && (parcs[i].angle1 % FULLCIRCLE) == 0x1680			    && parcs[i].angle2 == 0x2d00)				arcType = VERTICAL;			if (arcType == OTHER) {				/*				 * precompute an approximation map				 */				computeDashMap (&parcs[i], &map);				/*				 * compute each individual dash segment using the path				 * length function				 */				startAngle = parcs[i].angle1;				spanAngle = parcs[i].angle2;				if (spanAngle > FULLCIRCLE)					spanAngle = FULLCIRCLE;				else if (spanAngle < -FULLCIRCLE)					spanAngle = -FULLCIRCLE;				if (startAngle < 0)					startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;				if (startAngle >= FULLCIRCLE)					startAngle = startAngle % FULLCIRCLE;				endAngle = startAngle + spanAngle;				backwards = spanAngle < 0;			} else {				xarc = parcs[i];				if (arcType == VERTICAL) {					xarc.angle1 = 0x1680;					startAngle = parcs[i].y;					endAngle = startAngle + parcs[i].height;				} else {					xarc.angle1 = 0x2d00;					startAngle = parcs[i].x;					endAngle = startAngle + parcs[i].width;				}			}			dashAngle = startAngle;			selfJoin = data[i].selfJoin && 				    (iphase == 0 || isDoubleDash);			/*			 * add dashed arcs to each bucket			 */			arc = 0;			while (dashAngle != endAngle) {				prevDashAngle = dashAngle;				if (arcType == OTHER) {					dashAngle = computeAngleFromPath (prevDashAngle, endAngle,								&map, &dashRemaining, backwards);					/* avoid troubles with huge arcs and small dashes */					if (dashAngle == prevDashAngle) {						if (backwards)							dashAngle--;						else							dashAngle++;					}				} else {					thisLength = (dashAngle + dashRemaining <= endAngle) ? 					    dashRemaining : endAngle - dashAngle;					if (arcType == VERTICAL) {						xarc.y = dashAngle;						xarc.height = thisLength;					} else {						xarc.x = dashAngle;						xarc.width = thisLength;					}					dashAngle += thisLength;					dashRemaining -= thisLength;				}				if (iphase == 0 || isDoubleDash) {					if (arcType == OTHER) {						xarc = parcs[i];						spanAngle = prevDashAngle;						if (spanAngle < 0)						    spanAngle = FULLCIRCLE - (-spanAngle) % FULLCIRCLE;						if (spanAngle >= FULLCIRCLE)						    spanAngle = spanAngle % FULLCIRCLE;						xarc.angle1 = spanAngle;						spanAngle = dashAngle - prevDashAngle;						if (backwards) {							if (dashAngle > prevDashAngle)								spanAngle = - FULLCIRCLE + spanAngle;						} else {							if (dashAngle < prevDashAngle)								spanAngle = FULLCIRCLE + spanAngle;						}						if (spanAngle > FULLCIRCLE)						    spanAngle = FULLCIRCLE;						if (spanAngle < -FULLCIRCLE)						    spanAngle = -FULLCIRCLE;						xarc.angle2 = spanAngle;					}					arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs, 							&arcSize[iphase], &xarc);					if (!arc)					    goto arcfail;					/*					 * cap each end of an on/off dash					 */					if (!isDoubleDash) {						if (prevDashAngle != startAngle) {							addCap (&arcs[iphase].caps, 								&arcs[iphase].ncaps, 								&capSize[iphase], RIGHT_END, 								arc - arcs[iphase].arcs);													}						if (dashAngle != endAngle) {							addCap (&arcs[iphase].caps, 								&arcs[iphase].ncaps, 								&capSize[iphase], LEFT_END, 								arc - arcs[iphase].arcs);						}					}					arc->cap = arcs[iphase].ncaps;					arc->join = arcs[iphase].njoins;					arc->render = 0;					arc->selfJoin = 0;					if (dashAngle == endAngle)						arc->selfJoin = selfJoin;				}				prevphase = iphase;				if (dashRemaining <= 0) {					++iDash;					if (iDash == pGC->numInDashList)						iDash = 0;					iphase = iphase ? 0:1;					dashRemaining = pGC->dash[iDash];				}			}			/*			 * make sure a place exists for the position data when			 * drawing a zero-length arc			 */			if (startAngle == endAngle) {				prevphase = iphase;				if (!isDoubleDash && iphase == 1)					prevphase = 0;				arc = addArc (&arcs[prevphase].arcs, &arcs[prevphase].narcs,					      &arcSize[prevphase], &parcs[i]);				if (!arc)				    goto arcfail;				arc->join = arcs[prevphase].njoins;				arc->cap = arcs[prevphase].ncaps;				arc->selfJoin = data[i].selfJoin;			}		} else {			arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs, 				      &arcSize[iphase], &parcs[i]);			if (!arc)			    goto arcfail;			arc->join = arcs[iphase].njoins;			arc->cap = arcs[iphase].ncaps;			arc->selfJoin = data[i].selfJoin;			prevphase = iphase;		}		if (prevphase == 0 || isDoubleDash)			k = arcs[prevphase].narcs - 1;		if (iphase == 0 || isDoubleDash)			nextk = arcs[iphase].narcs;		if (nexti == start) {			nextk = 0;			if (isDashed) {				iDash = iDashStart;				iphase = iphaseStart;				dashRemaining = dashRemainingStart;			}		}		arcsJoin = narcs > 1 && i != j &&	 		    ISEQUAL (data[i].x1, data[j].x0) &&			    ISEQUAL (data[i].y1, data[j].y0) &&			    !data[i].selfJoin && !data[j].selfJoin;		if (arc)		{			if (arcsJoin)				arc->render = 0;			else				arc->render = 1;		}		if (arcsJoin &&		    (prevphase == 0 || isDoubleDash) &&		    (iphase == 0 || isDoubleDash)) 		{			joinphase = iphase;			if (isDoubleDash) {				if (nexti == start)					joinphase = iphaseStart;				/*				 * if the join is right at the dash,				 * draw the join in foreground				 * This is because the foreground				 * arcs are computed second, the results				 * of which are needed to draw the join				 */				if (joinphase != prevphase)					joinphase = 0;			}			if (joinphase == 0 || isDoubleDash) {				addJoin (&arcs[joinphase].joins, 					 &arcs[joinphase].njoins, 					 &joinSize[joinphase],	 				 LEFT_END, k, prevphase,	 				 RIGHT_END, nextk, iphase);				arc->join = arcs[prevphase].njoins;			}		} else {			/*			 * cap the left end of this arc			 * unless it joins itself			 */

⌨️ 快捷键说明

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