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

📄 miarc.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 5 页
字号:
				dashRemaining = dashRemainingStart;			}			nextk = arcs[iphase].narcs;			if (nexti == start) {				nextk = 0;				iDash = iDashStart;				iphase = iphaseStart;				dashRemaining = dashRemainingStart;			}			/*			 * cap the right end of the next arc.  If the			 * next arc is actually the first arc, only			 * cap it if it joins with this arc.  This			 * case will occur when the final dash segment			 * of an on/off dash is off.  Of course, this			 * cap will be drawn at a strange time, but that			 * hardly matters...			 */			if ((iphase == 0 || isDoubleDash) &&			    (nexti != start || (arcsJoin && isDashed)))				addCap (&arcs[iphase].caps, &arcs[iphase].ncaps, 					&capSize[iphase], RIGHT_END, nextk);		}		i = nexti;		if (i == start)			break;	}	/*	 * make sure the last section is rendered	 */	for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++)		if (arcs[iphase].narcs > 0) {			arcs[iphase].arcs[arcs[iphase].narcs-1].render = 1;			arcs[iphase].arcs[arcs[iphase].narcs-1].join =			         arcs[iphase].njoins;			arcs[iphase].arcs[arcs[iphase].narcs-1].cap =			         arcs[iphase].ncaps;		}	DEALLOCATE_LOCAL(data);	return arcs;arcfail:	miFreeArcs(arcs, pGC);	DEALLOCATE_LOCAL(data);	return (miPolyArcPtr)NULL;}static doubleangleToLength (int angle, dashMap *map){	double	len, excesslen, sidelen = map->map[DASH_MAP_SIZE - 1], totallen;	int	di;	int	excess;	gboolean	oddSide = FALSE;	totallen = 0;	if (angle >= 0) {		while (angle >= 90 * 64) {			angle -= 90 * 64;			totallen += sidelen;			oddSide = !oddSide;		}	} else {		while (angle < 0) {			angle += 90 * 64;			totallen -= sidelen;			oddSide = !oddSide;		}	}	if (oddSide)		angle = 90 * 64 - angle;			di = xAngleToDashIndex (angle);	excess = angle - dashIndexToXAngle (di);	len = map->map[di];	/*	 * linearly interpolate between this point and the next	 */	if (excess > 0) {		excesslen = (map->map[di + 1] - map->map[di]) *				((double) excess) / dashXAngleStep;		len += excesslen;	}	if (oddSide)		totallen += (sidelen - len);	else		totallen += len;	return totallen;}/* * len is along the arc, but may be more than one rotation */static intlengthToAngle (double len, dashMap *map){	double	sidelen = map->map[DASH_MAP_SIZE - 1];	int	angle, angleexcess;	gboolean	oddSide = FALSE;	int	a0, a1, a;	angle = 0;	/*	 * step around the ellipse, subtracting sidelens and	 * adding 90 degrees.  oddSide will tell if the	 * map should be interpolated in reverse	 */	if (len >= 0) {		if (sidelen == 0)			return 2 * FULLCIRCLE;	/* infinity */		while (len >= sidelen) {			angle += 90 * 64;			len -= sidelen;			oddSide = !oddSide;		}	} else {		if (sidelen == 0)			return -2 * FULLCIRCLE;	/* infinity */		while (len < 0) {			angle -= 90 * 64;			len += sidelen;			oddSide = !oddSide;		}	}	if (oddSide)		len = sidelen - len;	a0 = 0;	a1 = DASH_MAP_SIZE - 1;	/*	 * binary search for the closest pre-computed length	 */	while (a1 - a0 > 1) {		a = (a0 + a1) / 2;		if (len > map->map[a])			a0 = a;		else			a1 = a;	}	angleexcess = dashIndexToXAngle (a0);	/*	 * linearly interpolate to the next point	 */	angleexcess += (len - map->map[a0]) /			(map->map[a0+1] - map->map[a0]) * dashXAngleStep;	if (oddSide)		angle += (90 * 64) - angleexcess;	else		angle += angleexcess;	return angle;}/* * compute the angle of an ellipse which cooresponds to * the given path length.  Note that the correct solution * to this problem is an eliptic integral, we'll punt and * approximate (it's only for dashes anyway).  This * approximation uses a polygon. * * The remaining portion of len is stored in *lenp - * this will be negative if the arc extends beyond * len and positive if len extends beyond the arc. */static int computeAngleFromPath(int startAngle, int endAngle, dashMap *map, int *lenp, int backwards)/*	int	startAngle, endAngle;	*//* normalized absolute angles in *64 degrees */{	int	a0, a1, a;	double	len0;	int	len;	a0 = startAngle;	a1 = endAngle;	len = *lenp;	if (backwards) {		/*		 * flip the problem around to always be		 * forwards		 */		a0 = FULLCIRCLE - a0;		a1 = FULLCIRCLE - a1;	}	if (a1 < a0)		a1 += FULLCIRCLE;	len0 = angleToLength (a0, map);	a = lengthToAngle (len0 + len, map);	if (a > a1) {		a = a1;		len -= angleToLength (a1, map) - len0;	} else		len = 0;	if (backwards)		a = FULLCIRCLE - a;	*lenp = len;	return a;}/* * scan convert wide arcs. *//* * draw zero width/height arcs */static voiddrawZeroArc (GdkDrawable *pDraw, GdkGC *pGC, miArc *tarc, int lw,             miArcFacePtr left, miArcFacePtr right){	double	x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0, w, h, x, y;	double	xmax, ymax, xmin, ymin;	int	a0, a1;	double	a, startAngle, endAngle;	double	l, lx, ly;	l = lw / 2.0;	a0 = tarc->angle1;	a1 = tarc->angle2;	if (a1 > FULLCIRCLE)		a1 = FULLCIRCLE;	else if (a1 < -FULLCIRCLE)		a1 = -FULLCIRCLE;	w = (double)tarc->width / 2.0;	h = (double)tarc->height / 2.0;	/*	 * play in X coordinates right away	 */	startAngle = - ((double) a0 / 64.0);	endAngle = - ((double) (a0 + a1) / 64.0);		xmax = -w;	xmin = w;	ymax = -h;	ymin = h;	a = startAngle;	for (;;)	{		x = w * miDcos(a);		y = h * miDsin(a);		if (a == startAngle)		{			x0 = x;			y0 = y;		}		if (a == endAngle)		{			x1 = x;			y1 = y;		}		if (x > xmax)			xmax = x;		if (x < xmin)			xmin = x;		if (y > ymax)			ymax = y;		if (y < ymin)			ymin = y;		if (a == endAngle)			break;		if (a1 < 0)	/* clockwise */		{			if (floor (a / 90.0) == floor (endAngle / 90.0))				a = endAngle;			else				a = 90 * (floor (a/90.0) + 1);		}		else		{			if (ceil (a / 90.0) == ceil (endAngle / 90.0))				a = endAngle;			else				a = 90 * (ceil (a/90.0) - 1);		}	}	lx = ly = l;	if ((x1 - x0) + (y1 - y0) < 0)	    lx = ly = -l;	if (h)	{	    ly = 0.0;	    lx = -lx;	}	else	    lx = 0.0;	if (right)	{	    right->center.x = x0;	    right->center.y = y0;	    right->clock.x = x0 - lx;	    right->clock.y = y0 - ly;	    right->counterClock.x = x0 + lx;	    right->counterClock.y = y0 + ly;	}	if (left) 	{	    left->center.x = x1;	    left->center.y = y1;	    left->clock.x = x1 + lx;	    left->clock.y = y1 + ly;	    left->counterClock.x = x1 - lx;	    left->counterClock.y = y1 - ly;	}		x0 = xmin;	x1 = xmax;	y0 = ymin;	y1 = ymax;	if (ymin != y1) {		xmin = -l;		xmax = l;	} else {		ymin = -l;		ymax = l;	}	if (xmax != xmin && ymax != ymin) {		int	minx, maxx, miny, maxy;		minx = ICEIL (xmin + w) + tarc->x;		maxx = ICEIL (xmax + w) + tarc->x;		miny = ICEIL (ymin + h) + tarc->y;		maxy = ICEIL (ymax + h) + tarc->y;		gdk_fb_draw_rectangle(pDraw, pGC, TRUE, minx, miny, maxx - minx, maxy - miny);	}}/* * this computes the ellipse y value associated with the * bottom of the tail. */static voidtailEllipseY (struct arc_def *def, struct accelerators *acc){	double		t;	acc->tail_y = 0.0;	if (def->w == def->h)	    return;	t = def->l * def->w;	if (def->w > def->h) {	    if (t < acc->h2)		return;	} else {	    if (t > acc->h2)		return;	}	t = 2.0 * def->h * t;	t = (CUBED_ROOT_4 * acc->h2 - cbrt(t * t)) / acc->h2mw2;	if (t > 0.0)	    acc->tail_y = def->h / CUBED_ROOT_2 * sqrt(t);}/* * inverse functions -- compute edge coordinates * from the ellipse */static doubleouterXfromXY (double x, double y,              struct arc_def *def, struct accelerators *acc){	return x + (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);}static doubleouterYfromXY (double x, double y,              struct arc_def *def, struct accelerators *acc){	return y + (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);}static doubleinnerXfromXY (double x, double y,              struct arc_def *def, struct accelerators *acc){	return x - (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);}static doubleinnerYfromXY (double x, double y,              struct arc_def *def, struct accelerators *acc){	return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);}static doubleinnerYfromY (double y, struct arc_def *def, struct accelerators *acc){	double	x;	x = (def->w / def->h) * sqrt (acc->h2 - y*y);	return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);}static voidcomputeLine (double x1, double y1, double x2, double y2, struct line *line){	if (y1 == y2)		line->valid = 0;	else {		line->m = (x1 - x2) / (y1 - y2);		line->b = x1  - y1 * line->m;		line->valid = 1;	}}/* * compute various accelerators for an ellipse.  These * are simply values that are used repeatedly in * the computations */static voidcomputeAcc (miArc *tarc, int lw, struct arc_def *def, struct accelerators *acc){	def->w = ((double) tarc->width) / 2.0;	def->h = ((double) tarc->height) / 2.0;	def->l = ((double) lw) / 2.0;	acc->h2 = def->h * def->h;	acc->w2 = def->w * def->w;	acc->h4 = acc->h2 * acc->h2;	acc->w4 = acc->w2 * acc->w2;	acc->h2l = acc->h2 * def->l;	acc->w2l = acc->w2 * def->l;	acc->h2mw2 = acc->h2 - acc->w2;	acc->fromIntX = (tarc->width & 1) ? 0.5 : 0.0;	acc->fromIntY = (tarc->height & 1) ? 0.5 : 0.0;	acc->xorg = tarc->x + (tarc->width >> 1);	acc->yorgu = tarc->y + (tarc->height >> 1);	acc->yorgl = acc->yorgu + (tarc->height & 1);	tailEllipseY (def, acc);}		/* * compute y value bounds of various portions of the arc, * the outer edge, the ellipse and the inner edge. */static voidcomputeBound (struct arc_def *def, struct arc_bound *bound,              struct accelerators *acc, miArcFacePtr right, miArcFacePtr left){	double		t;	double		innerTaily;	double		tail_y;	struct bound	innerx, outerx;	struct bound	ellipsex;	bound->ellipse.min = Dsin (def->a0) * def->h;	bound->ellipse.max = Dsin (def->a1) * def->h;	if (def->a0 == 45 && def->w == def->h)		ellipsex.min = bound->ellipse.min;	else		ellipsex.min = Dcos (def->a0) * def->w;	if (def->a1 == 45 && def->w == def->h)		ellipsex.max = bound->ellipse.max;	else		ellipsex.max = Dcos (def->a1) * def->w;	bound->outer.min = outerYfromXY (ellipsex.min, bound->ellipse.min, def, acc);	bound->outer.max = outerYfromXY (ellipsex.max, bound->ellipse.max, def, acc);	bound->inner.min = innerYfromXY (ellipsex.min, bound->ellipse.min, def, acc);	bound->inner.max = innerYfromXY (ellipsex.max, bound->ellipse.max, def, acc);	outerx.min = outerXfromXY (ellipsex.min, bound->ellipse.min, def, acc);	outerx.max = outerXfromXY (ellipsex.max, bound->ellipse.max, def, acc);	innerx.min = innerXfromXY (ellipsex.min, bound->ellipse.min, def, acc);	innerx.max = innerXfromXY (ellipsex.max, bound->ellipse.max, def, acc);		/*	 * save the line end points for the	 * cap code to use.  Careful here, these are	 * in cartesean coordinates (y increasing upwards)	 * while the cap code uses inverted coordinates	 * (y increasing downwards)	 */	if (right) {		right->counterClock.y = bound->outer.min;		right->counterClock.x = outerx.min;		right->center.y = bound->ellipse.min;		right->center.x = ellipsex.min;		right->clock.y = bound->inner.min;		right->clock.x = innerx.min;	}	if (left) {		left->clock.y = bound->outer.max;		left->clock.x = outerx.max;		left->center.y = bound->ellipse.max;		left->center.x = ellipsex.max;		left->counterClock.y = bound->inner.max;		left->counterClock.x = innerx.max;	}	bound->left.min = bound->inner.max;	bound->left.max = bound->outer.max;	bound->right.min = bound->inner.min;	bound->right.max = bound->outer.min;	computeLine (innerx.min, bound->inner.min, outerx.min, bound->outer.min,		      &acc->right);	computeLine (innerx.max, bound->inner.max, outerx.max, bound->outer.max,		     &acc->left);	if (bound->inner.min > bound->inner.max) {		t = bound->inner.min;		bound->inner.min = bound->inner.max;		bound->inner.max = t;	}	tail_y = acc->tail_y;	if (tail_y > bound->ellipse.max)		tail_y = bound->ellipse.max;	else if (tail_y < bound->ellipse.min)	        tail_y = bound->ellipse.min;	innerTaily = innerYfromY (tail_y, def, acc);	if (bound->inner.min > innerTaily)		bound->inner.min = innerTail

⌨️ 快捷键说明

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