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

📄 ftgrays.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
			raster->cover += delta;			ey1       += incr;			gray_set_cell( raster, ex, ey1 );		}		delta      = (int)( fy2 - ONE_PIXEL + first );		raster->area  += (TArea)two_fx * delta;		raster->cover += delta;		goto End;	}	/* ok, we have to render several scanlines */	p     = ( ONE_PIXEL - fy1 ) * dx;	first = ONE_PIXEL;	incr  = 1;	if ( dy < 0 ) {		p     = fy1 * dx;		first = 0;		incr  = -1;		dy    = -dy;	}	delta = (int)( p / dy );	mod   = (int)( p % dy );	if ( mod < 0 ) {		delta--;		mod += (TCoord)dy;	}	x = raster->x + delta;	gray_render_scanline( raster, ey1, raster->x, fy1, x, (TCoord)first );	ey1 += incr;	gray_set_cell( raster, TRUNC( x ), ey1 );	if ( ey1 != ey2 ) {		p     = ONE_PIXEL * dx;		lift  = (int)( p / dy );		rem   = (int)( p % dy );		if ( rem < 0 ) {			lift--;			rem += (int)dy;		}		mod -= (int)dy;		while ( ey1 != ey2 ) {			delta = lift;			mod  += rem;			if ( mod >= 0 )	{				mod -= (int)dy;				delta++;			}			x2 = x + delta;			gray_render_scanline( raster, ey1, x, (TCoord)( ONE_PIXEL - first ), x2, (TCoord)first );			x = x2;			ey1 += incr;			gray_set_cell( raster, TRUNC( x ), ey1 );		}	}	gray_render_scanline( raster, ey1, x, (TCoord)( ONE_PIXEL - first ), to_x, fy2 );End:	raster->x       = to_x;	raster->y       = to_y;	raster->last_ey = SUBPIXELS( ey2 );} static int EVG_Outline_Decompose(EVG_Outline *outline, TRaster *user){	EVG_Vector   v_last;	EVG_Vector   v_start;	EVG_Vector*  point;	EVG_Vector*  limit;	char*       tags;	int   n;         /* index of contour in outline     */	int   first;     /* index of first point in contour */	char  tag;       /* current point's state           */#ifdef INLINE_POINT_CONVERSION	TPos _x, _y;#endif	first = 0;	for ( n = 0; n < outline->n_contours; n++ ) {		int  last;  /* index of last point in contour */		last  = outline->contours[n];		limit = outline->points + last;				v_start = outline->points[first];		v_last  = outline->points[last];		point = outline->points + first;		tags  = (char*) outline->tags  + first;		tag   = tags[0];		gray_move_to(&v_start, user);		while ( point < limit ) {			point++;			tags++;#ifdef INLINE_POINT_CONVERSION			evg_translate_point(user->mx, point, &_x, &_y);			gray_render_line(user, _x, _y, 1);#else			gray_render_line(user, UPSCALE(point->x), UPSCALE( point->y), 1);#endif		}#ifdef INLINE_POINT_CONVERSION		evg_translate_point(user->mx, &v_start, &_x, &_y);		gray_render_line(user, _x, _y, 0);#else		/* close the contour with a line segment */		gray_render_line(user, UPSCALE(v_start.x), UPSCALE( v_start.y), 0);#endif		first = last + 1;	}	return 0;}#define SWAP_CELLS( a, b, temp )  {              \                                    temp = *(a); \                                    *(a) = *(b); \                                    *(b) = temp; \                                  }  /* This is a non-recursive quicksort that directly process our cells     */  /* array.  It should be faster than calling the stdlib qsort(), and we   */  /* can even tailor our insertion threshold...                            */#define QSORT_THRESHOLD  9  /* below this size, a sub-array will be sorted */                            /* through a normal insertion sort             */static void gray_quick_sort( AACell *cells, int    count ) {	AACell *stack[80];  /* should be enough ;-) */	AACell **top;        /* top of stack */	AACell *base, *limit;	AACell temp;	limit = cells + count;	base  = cells;	top   = stack;	for (;;) {		int    len = (int)( limit - base );		AACell *i, *j, *pivot;		if ( len > QSORT_THRESHOLD ) {			/* we use base + len/2 as the pivot */			pivot = base + len / 2;			SWAP_CELLS( base, pivot, temp );			i = base + 1;			j = limit - 1;			/* now ensure that *i <= *base <= *j */			if(j->x < i->x)				SWAP_CELLS( i, j, temp );			if(base->x < i->x)				SWAP_CELLS( base, i, temp );			if(j->x < base->x)				SWAP_CELLS( base, j, temp );			for (;;) {				int x = base->x;				do i++; while( i->x < x );				do j--; while( x < j->x );				if ( i > j )					break;				SWAP_CELLS( i, j, temp );			}			SWAP_CELLS( base, j, temp );			/* now, push the largest sub-array */			if ( j - base > limit - i ) {				top[0] = base;				top[1] = j;				base   = i;			} else {				top[0] = i;				top[1] = limit;				limit  = j;			}			top += 2;		} else {			/* the sub-array is small, perform insertion sort */			j = base;			i = j + 1;			for ( ; i < limit; j = i, i++ ) {				for ( ; j[1].x < j->x; j-- ) {					SWAP_CELLS( j + 1, j, temp );					if ( j == base ) 						break;				}			}			if ( top > stack ) {				top  -= 2;				base  = top[0];				limit = top[1];			} else				break;		}	}}static void gray_hline( TRaster *raster, TCoord  x, TCoord  y, TPos    area, int     acount, Bool zero_non_zero_rule){	EVG_Span*   span;	int        count;	int        coverage;	x += (TCoord)raster->min_ex;	if (x>=raster->max_ex) return;	y += (TCoord)raster->min_ey;	/* compute the coverage line's coverage, depending on the    */	/* outline fill rule                                         */	/*                                                           */	/* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */	/*                                                           */	coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );									/* use range 0..256 */	if ( coverage < 0 )	coverage = -coverage;	if (zero_non_zero_rule) {		/* normal non-zero winding rule */		if ( coverage >= 256 )			coverage = 255;	} else {		coverage &= 511;		if ( coverage > 256 )			coverage = 512 - coverage;		else if ( coverage == 256 )			coverage = 255;	}	if ( coverage ) {		/* see if we can add this span to the current list */		count = raster->num_gray_spans;		span  = raster->gray_spans + count - 1;		if ( count > 0                          &&			(int)span->x + span->len == (int)x &&			span->coverage == coverage )		{			span->len = (unsigned short)( span->len + acount );			return;		}		if (count >= FT_MAX_GRAY_SPANS ) {			raster->render_span(y, count, raster->gray_spans, raster->render_span_data );			raster->num_gray_spans = 0;			count = 0;			span  = raster->gray_spans;		} else			span++;		/* add a gray span to the current list */		span->x        = (short)x;		span->len      = (unsigned short)acount;		span->coverage = (unsigned char)coverage;		raster->num_gray_spans++;	}}static void gray_sweep_line( TRaster *raster, AAScanline *sl, int y, Bool zero_non_zero_rule){	TCoord  x, cover;	TArea   area;	AACell *start, *cur;	cur = sl->cells;	cover = 0;	raster->num_gray_spans = 0;	while (sl->num) {		start  = cur;		x      = start->x;		area   = start->area;		cover += start->cover;		/* accumulate all start cells */		while(--sl->num) {			++cur ;			if (cur->x != start->x )				break;			area  += cur->area;			cover += cur->cover;		}				/* if the start cell has a non-null area, we must draw an */		/* individual gray pixel there                            */		if ( area && x >= 0 ) {			gray_hline( raster, x, y, cover * ( ONE_PIXEL * 2 ) - area, 1, zero_non_zero_rule);			x++;		}		if ( x < 0 ) x = 0;		/* draw a gray span between the start cell and the current one */		if ( cur->x > x )			gray_hline( raster, x, y, cover * ( ONE_PIXEL * 2 ), cur->x - x, zero_non_zero_rule);	}	raster->render_span(y + raster->min_ey, raster->num_gray_spans, raster->gray_spans, raster->render_span_data );}int evg_raster_render(EVG_Raster raster, EVG_Raster_Params*  params){	Bool zero_non_zero_rule;	int i, size_y;	EVG_Outline*  outline = (EVG_Outline*)params->source;	/* return immediately if the outline is empty */	if ( outline->n_points == 0 || outline->n_contours <= 0 ) return 0;	raster->render_span  = (EVG_Raster_Span_Func) params->gray_spans;	raster->render_span_data = params->user;	/* Set up state in the raster object */	raster->min_ex = params->clip_xMin;	raster->min_ey = params->clip_yMin;	raster->max_ex = params->clip_xMax;	raster->max_ey = params->clip_yMax;#ifdef INLINE_POINT_CONVERSION	raster->mx = params->mx;#endif	size_y = raster->max_ey - raster->min_ey;    if (raster->max_lines < size_y) {		raster->scanlines = (AAScanline*)realloc(raster->scanlines, sizeof(AAScanline)*size_y);		memset(&raster->scanlines[raster->max_lines], 0, sizeof(AAScanline)*(size_y-raster->max_lines) );		raster->max_lines = size_y;	}		raster->ex = raster->max_ex+1;	raster->ey = raster->max_ey+1;	raster->cover = 0;	raster->area = 0;	EVG_Outline_Decompose(outline, raster);    gray_record_cell( raster );		/*store odd/even rule*/	zero_non_zero_rule = (outline->flags & GF_PATH_FILL_ZERO_NONZERO) ? 1 : 0;	/* sort each scanline and render it*/	for (i=0; i<size_y; i++) {		AAScanline *sl = &raster->scanlines[i];		if (sl->num) {			if (sl->num>1) gray_quick_sort(sl->cells, sl->num);			gray_sweep_line(raster, sl, i, zero_non_zero_rule);			sl->num = 0;		}	}	return 0;}EVG_Raster evg_raster_new(){	TRaster *raster;	GF_SAFEALLOC(raster , TRaster);	return raster;}void evg_raster_del(EVG_Raster raster){	int i;	for (i=0; i<raster->max_lines; i++) {		free(raster->scanlines[i].cells);	}	free(raster->scanlines);    free(raster);}/* END */

⌨️ 快捷键说明

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