Exemplo n.º 1
0
Arquivo: graph.c Projeto: rokite/LCUI
int Graph_Replace( LCUI_Graph *back, const LCUI_Graph *fore, LCUI_Pos pos )
{
	LCUI_Graph write_slot;
	LCUI_Rect read_rect,write_rect;
	
	if( !Graph_IsValid(back) || !Graph_IsValid(fore) ) {
		return -1;
	}

	write_rect.x = pos.x;
	write_rect.y = pos.y;
	write_rect.width = fore->width;
	write_rect.height = fore->height;
	Graph_Quote( &write_slot, back, &write_rect );
	Graph_GetValidRect( &write_slot, &write_rect );
	Graph_GetValidRect( fore, &read_rect );
	if( write_rect.width <= 0 || write_rect.height <= 0
	 || read_rect.width <= 0 || read_rect.height <= 0 ) {
		return -2;
	}
	pos.x = read_rect.x;
	pos.y = read_rect.y;
	fore = Graph_GetQuote( fore );
	back = Graph_GetQuote( back );

	switch( fore->color_type ) {
	case COLOR_TYPE_RGB888:
		return Graph_RGBReplaceRGB( back, write_rect, fore, pos );
	case COLOR_TYPE_ARGB8888:
		return Graph_ARGBReplaceARGB( back, write_rect, fore, pos );
	default:break;
	}

	return -1;
}
Exemplo n.º 2
0
int Graph_Mix( LCUI_Graph *back, const LCUI_Graph *fore, LCUI_Pos pos )
{
	LCUI_Graph write_slot;
	LCUI_Rect read_rect, write_rect;
	void (*mixer)(LCUI_Graph*, LCUI_Rect, const LCUI_Graph *, LCUI_Pos) = NULL;

	/* 预先进行有效性判断 */
	if( !Graph_IsValid(back) || !Graph_IsValid(fore) ) {
		return -1;
	}

	write_rect.x = pos.x;
	write_rect.y = pos.y;
	write_rect.width = fore->width;
	write_rect.height = fore->height;
	LCUIRect_GetCutArea( Size( back->width, back->height ),
			     write_rect, &read_rect );
	write_rect.x += read_rect.x;
	write_rect.y += read_rect.y;
	write_rect.width = read_rect.width;
	write_rect.height = read_rect.height;
	Graph_Quote( &write_slot, back, &write_rect );
	/* 获取实际操作区域 */
	Graph_GetValidRect( &write_slot, &write_rect );
	Graph_GetValidRect( fore, &read_rect );
	/* 若读或写的区域无效 */
	if( write_rect.width <= 0 || write_rect.height <= 0
	 || read_rect.width <= 0 || read_rect.height <= 0 ) {
		return -2;
	}
	pos.x = read_rect.x;
	pos.y = read_rect.y;
	/* 获取引用的源图像 */
	fore = Graph_GetQuote( fore );
	back = Graph_GetQuote( back );

	switch( fore->color_type ) {
	case COLOR_TYPE_RGB888:
		if( back->color_type == COLOR_TYPE_RGB888 ) {
			mixer = Graph_RGBReplaceRGB;
		} else {
			mixer = Graph_ARGBReplaceRGB;
		}
		break;
	case COLOR_TYPE_ARGB8888:
		if( back->color_type == COLOR_TYPE_RGB888 ) {
			mixer = Graph_RGBMixARGB;
		} else {
			mixer = Graph_ARGBMixARGB;
		}
	default:break;
	}

	if( mixer ) {
		mixer( back, write_rect, fore, pos );
		return 0;
	}
	return -3;
}
Exemplo n.º 3
0
LCUI_API LCUI_BOOL Graph_GetPixel( LCUI_Graph *graph, LCUI_Pos pos, LCUI_RGBA *pixel )
{
	int i;
	LCUI_Rect rect;
	
	if( pos.x < 0 || pos.y < 0 ) {
		return FALSE;
	}
	rect = Graph_GetValidRect( graph );
	/* 若坐标超出范围 */
	if( pos.x >= rect.width || pos.y >= rect.height ) {
		return FALSE;
	}
	graph = Graph_GetQuote( graph );
	if( !Graph_IsValid(graph) ) {
		return FALSE;
	}
	i = graph->w*(pos.y+rect.y) + pos.x + rect.x;
	pixel->red = graph->rgba[0][i];
	pixel->green = graph->rgba[1][i];
	pixel->blue = graph->rgba[2][i];
	
	if(graph->color_type == COLOR_TYPE_RGBA) {
		pixel->alpha = graph->rgba[3][i];
	} else {
		pixel->alpha = 255;
	}
	return TRUE;
}
Exemplo n.º 4
0
static int Graph_VertiFlipARGB( const LCUI_Graph *graph, LCUI_Graph *buff )
{
	int y;
	LCUI_Rect rect;
	uchar_t *byte_src, *byte_des;

	if(!Graph_IsValid(graph)) {
		return -1;
	}
	Graph_GetValidRect( graph, &rect );
	graph = Graph_GetQuote( graph );
	buff->opacity = graph->opacity;
	buff->color_type = graph->color_type;
	if( 0 != Graph_Create( buff, rect.width, rect.height ) ) {
		return -2;
	}
	byte_src = graph->bytes + (rect.y + rect.h - 1)*graph->bytes_per_row;
	byte_src += rect.x * graph->bytes_per_pixel;
	byte_des = buff->bytes;
	for( y=0; y<rect.h; ++y ) {
		memcpy( byte_des, byte_src, buff->bytes_per_row );
		byte_src -= graph->bytes_per_row;
		byte_des += buff->bytes_per_row;
	}
	return 0;
}
Exemplo n.º 5
0
static int Graph_HorizFlipARGB( const LCUI_Graph *graph, LCUI_Graph *buff )
{
	int x, y;
	LCUI_Rect rect;
	LCUI_ARGB *pixel_src, *pixel_des;

	if(!Graph_IsValid(graph)) {
		return -1;
	}
	Graph_GetValidRect( graph, &rect );
	graph = Graph_GetQuote( graph );
	buff->opacity = graph->opacity;
	buff->color_type = graph->color_type;
	if( 0 != Graph_Create( buff, rect.width, rect.height ) ) {
		return -2;
	}

	for( y=0; y<rect.h; ++y ) {
		pixel_des = buff->argb + y*buff->w;
		pixel_src = graph->argb + (rect.y+y)*graph->w;
		pixel_src += rect.x + rect.w - 1;
		for( x=0; x<rect.w; ++x ) {
			*pixel_des++ = *pixel_src--;
		}
	}
	return 0;
}
Exemplo n.º 6
0
int Graph_FillRectRGB( LCUI_Graph *graph, LCUI_Color color, LCUI_Rect rect )
{
	int x, y;
	LCUI_Graph canvas;
	uchar_t *rowbytep, *bytep;

	if(!Graph_IsValid(graph)) {
		return -1;
	}
	Graph_Quote( &canvas, graph, &rect );
	Graph_GetValidRect( &canvas, &rect );
	graph = Graph_GetQuote( &canvas );
	rowbytep = graph->bytes + rect.y*graph->bytes_per_row;
	rowbytep += rect.x*graph->bytes_per_pixel;
	for( y=0; y<rect.h; ++y ) {
		bytep = rowbytep;
		for( x=0; x<rect.w; ++x ) {
			*bytep++ = color.blue;
			*bytep++ = color.green;
			*bytep++ = color.red;
		}
		rowbytep += graph->bytes_per_row;
	}
	return 0;
}
Exemplo n.º 7
0
static int Graph_HorizFlipRGB( const LCUI_Graph *graph, LCUI_Graph *buff )
{
	int x, y, n;
	LCUI_Rect rect;
	uchar_t *byte_src, *byte_des;

	if(!Graph_IsValid(graph)) {
		return -1;
	}
	Graph_GetValidRect( graph, &rect );
	graph = Graph_GetQuote( graph );
	buff->color_type = graph->color_type;
	if( 0 != Graph_Create( buff, rect.width, rect.height ) ) {
		return -2;
	}

	for( y=0; y<rect.h; ++y ) {
		byte_des = buff->bytes + y*buff->w*3;
		n = ((rect.y+y)*graph->w + rect.x + rect.w - 1)*3;
		byte_src = buff->bytes + n;
		for( x=0; x<rect.w; ++x ) {
			*byte_des++ = *byte_src--;
			*byte_des++ = *byte_src--;
			*byte_des++ = *byte_src--;
		}
	}
	return 0;
}
Exemplo n.º 8
0
int Graph_FillAlpha( LCUI_Graph *graph, uchar_t alpha )
{
	int x, y;
	LCUI_Rect rect;
	LCUI_ARGB *pixel, *pixel_row;

	Graph_GetValidRect( graph, &rect );
	graph = Graph_GetQuote( graph );
	if( !Graph_IsValid(graph) ) {
		return -1;
	}
	if( !Graph_HasAlpha(graph) ) {
		return -2;
	}

	pixel_row = graph->argb + rect.y*graph->w + rect.x;
	for(y=0; y<rect.h; ++y) {
		pixel = pixel_row;
		for( x=0; x<rect.w; ++x ) {
			pixel->alpha = alpha;
			++pixel;
		}
		pixel_row += graph->w;
	}
	return 0;
}
Exemplo n.º 9
0
LCUI_API int Graph_FillAlpha( LCUI_Graph *src, uchar_t alpha )
{
	int y, row_start;
	LCUI_Rect src_rect;
	
	/* 获取引用的区域在源图形中的有效区域 */
	src_rect = Graph_GetValidRect( src );
	/* 获取引用的源图指针 */
	src = Graph_GetQuote( src );
	
	if(! Graph_IsValid(src) ) {
		return -1;
	}
	if( !Graph_HaveAlpha(src) ) {
		return -2;
	}
	
	row_start = src_rect.x + src_rect.y * src->w;
	for(y=0; y<src_rect.height; ++y) {
		memset( &src->rgba[3][row_start], 
			alpha, src_rect.width*sizeof(uchar_t) );
		row_start += src->w;
	}
	return 0; 
}
Exemplo n.º 10
0
LCUI_API int Graph_VertiFlip( LCUI_Graph *src_graph, LCUI_Graph *out_graph )
{
	uchar_t buff;
	LCUI_Rect rect;
	int x, y, center; 
	int src_top_pos, src_bottom_pos;
	int des_top_pos, des_bottom_pos;
	int src_start_top_pos, src_start_bottom_pos;
	int des_start_top_pos, des_start_bottom_pos;

	if(!Graph_IsValid(src_graph)) {
		return -1;
	}
	src_graph = Graph_GetQuote(src_graph );
	rect = Graph_GetValidRect( src_graph );
	out_graph->color_type = src_graph->color_type;
	if( 0 != Graph_Create(out_graph, rect.width, rect.height ) ) {
		return -2;
	}

	center = (int)(rect.height / 2.0);
	/* 记录基坐标 */
	des_start_top_pos = 0;
	des_start_bottom_pos = (rect.height-1)*rect.width;
	src_start_top_pos = rect.y * src_graph->w + rect.x;
	src_start_bottom_pos = (rect.y + rect.height-1)*src_graph->w + rect.x;

	for (x=0; x < rect.width; ++x) {
		/* 当前坐标=基坐标+x */
		des_top_pos = des_start_top_pos + x;
		des_bottom_pos = des_start_bottom_pos + x;
		src_top_pos = src_start_top_pos + x;
		src_bottom_pos = src_start_bottom_pos + x;
		for (y = 0; y <= center; ++y) {
			buff = src_graph->rgba[0][src_top_pos]; 
			out_graph->rgba[0][des_top_pos] = src_graph->rgba[0][src_bottom_pos];  
			out_graph->rgba[0][des_bottom_pos] = buff;

			buff = src_graph->rgba[1][src_top_pos]; 
			out_graph->rgba[1][des_top_pos] = src_graph->rgba[1][src_bottom_pos];  
			out_graph->rgba[1][des_bottom_pos] = buff;

			buff = src_graph->rgba[2][src_top_pos]; 
			out_graph->rgba[2][des_top_pos] = src_graph->rgba[2][src_bottom_pos];  
			out_graph->rgba[2][des_bottom_pos] = buff;

			if(src_graph->color_type == COLOR_TYPE_RGBA) {
				buff = src_graph->rgba[3][src_top_pos]; 
				out_graph->rgba[3][des_top_pos] = src_graph->rgba[3][src_bottom_pos];  
				out_graph->rgba[3][des_bottom_pos] = buff;
			}
			src_top_pos += src_graph->w;
			des_top_pos += rect.width;
			src_bottom_pos -= src_graph->w;
			des_bottom_pos -= rect.width;
		}
	}
	return 0;
}
Exemplo n.º 11
0
static void Graph_DrawLeftShadow( LCUI_PaintContext paint, LCUI_Rect *box,
				  LCUI_BoxShadow *shadow )
{
	float v, a;
	LCUI_Color color;
	LCUI_Graph *graph;
	int s, t, x, y, bound_x, bound_y;
	LCUI_Rect shadow_area, box_area, paint_area, area;

	s = 255;
	t = BLUR_WIDTH(shadow);
	v = 512.0/t;
	a = 2*(v*t-s)/(t*t);
	color = shadow->color;
	box_area.x = BoxShadow_GetBoxX( shadow );
	box_area.y = BoxShadow_GetBoxY( shadow );
	box_area.w = BoxShadow_GetBoxWidth( shadow, box->w );
	box_area.h = BoxShadow_GetBoxHeight( shadow, box->h );
	shadow_area.x = BoxShadow_GetX( shadow );
	shadow_area.y = BoxShadow_GetY( shadow ) + BLUR_WIDTH(shadow);
	shadow_area.w = BLUR_WIDTH(shadow);
	shadow_area.h = box_area.h + INNER_SHADOW_WIDTH(shadow)*2;
	box_area.x += box->x;
	box_area.y += box->y;
	shadow_area.x += box->x;
	shadow_area.y += box->y;
	if( !LCUIRect_GetOverlayRect( &shadow_area, &paint->rect, &area ) ) {
		return;
	}
	Graph_GetValidRect( &paint->canvas, &paint_area );
	graph = Graph_GetQuote( &paint->canvas );
	shadow_area.x -= paint->rect.x;
	shadow_area.y -= paint->rect.y;
	box_area.x -= paint->rect.x;
	box_area.y -= paint->rect.y;
	area.x -= paint->rect.x;
	area.y -= paint->rect.y;
	bound_x = area.x + area.width;
	bound_y = area.y + area.height;
	if( bound_x > paint_area.x + paint_area.width ) {
		bound_x = paint_area.x + paint_area.width;
	}
	if( bound_y > paint_area.y + paint_area.height ) {
		bound_y = paint_area.y + paint_area.height;
	}
	t -= area.x - shadow_area.x;
	for( x = area.x; x < bound_x; ++x, --t ) {
		color.alpha = (uchar_t)(s - (v*t - (a*t*t) / 2));
		color.alpha *= shadow->color.a / 255.0;
		for( y = area.y; y < bound_y; ++y ) {
			if( y >= box_area.y && y < box_area.y + box_area.h &&
			    x >= box_area.x && x < box_area.x + box_area.w ) {
				continue;
			}
			Graph_SetPixel( graph, x, y, color );
		}
	}
}
Exemplo n.º 12
0
static void Graph_DrawTopShadow( LCUI_PaintContext paint, LCUI_Rect *box,
				 LCUI_BoxShadow *shadow )
{
	float v, a;
	int s, t, x, y, bound_x, bound_y;
	LCUI_Color color;
	LCUI_Graph *graph;
	LCUI_Rect shadow_area, box_area, area;

	box_area.x = BoxShadow_GetBoxX( shadow );
	box_area.y = BoxShadow_GetBoxY( shadow );
	box_area.w = BoxShadow_GetBoxWidth( shadow, box->w );
	box_area.h = BoxShadow_GetBoxHeight( shadow, box->h );
	/* 计算需要绘制上边阴影的区域 */
	shadow_area.x = BoxShadow_GetX( shadow ) + BLUR_WIDTH(shadow);
	shadow_area.y = BoxShadow_GetY( shadow );
	shadow_area.w = box_area.w + INNER_SHADOW_WIDTH(shadow)*2;
	shadow_area.h = BLUR_WIDTH(shadow);
	color = shadow->color;
	bound_x = shadow_area.x + shadow_area.w;
	bound_y = shadow_area.y + shadow_area.h;
	graph = Graph_GetQuote( &paint->canvas );
	Graph_GetValidRect( &paint->canvas, &area );
	if( !LCUIRect_GetOverlayRect( &area, &paint->rect, &area ) ) {
		return;
	}
	/**
	* 这里采用匀减速直线运动的公式: s = vt - at²/2
	* 加速度 a 的求值公式为:a = 2x(vt - s)/t²
	*/
	s = 255;
	t = BLUR_WIDTH(shadow);
	v = 512.0/t;
	a = 2*(v*t-s)/(t*t);

	for( y=shadow_area.y; y<bound_y; ++y,--t ) {
		/* 忽略不在有效区域内的像素 */
		if( y < area.y || y >= area.y + area.h ) {
			continue;
		}
		/* 计算当前行阴影的透明度 */
		color.alpha = (uchar_t)(s-(v*t-(a*t*t)/2));
		color.alpha *= shadow->color.a/255.0;
		for( x=shadow_area.x; x<bound_x; ++x ) {
			if( x < area.x || x >= area.x + area.w ) {
				continue;
			}
			if( y >= box_area.y && y < box_area.y + box_area.h
			 && x >= box_area.x && x < box_area.x + box_area.w ) {
				 continue;
			}
			Graph_SetPixel( graph, x, y, color );
		}
	}
}
Exemplo n.º 13
0
LCUI_API int Graph_Zoom(	LCUI_Graph *in_graph,
				LCUI_Graph *out_graph, 
				LCUI_BOOL keep_scale,
				LCUI_Size size )
{
	LCUI_Graph *src;
	LCUI_Rect rect;
	LCUI_Pos pos; 
	int des_n, src_n, x, y, k, m;
	double scale_x,scale_y;

	if(!Graph_IsValid(in_graph)) {
		return -1;
	}
	if(size.w <=0 || size.h <= 0) { 
		Graph_Free(out_graph);
		return -1;
	}
	/* 获取引用的有效区域,以及指向引用的对象的指针 */
	rect = Graph_GetValidRect(in_graph);
	src = Graph_GetQuote(in_graph);

	scale_x = (double)rect.width / size.w;
	scale_y = (double)rect.height / size.h;
	/* 如果缩放方式为缺省,图像的宽和高的缩放比例将会一样 */
	if( keep_scale ) {
		if (scale_x<scale_y) {
			scale_y = scale_x; 
		} else {
			scale_x = scale_y;
		}
	}
	out_graph->color_type = in_graph->color_type;
	if( Graph_Create(out_graph, size.w, size.h) < 0) {
		return -2;
	}
	for (y=0; y < size.h; ++y)  {
		pos.y = y*scale_y;
		k = y*size.w;
		m = (pos.y+rect.y)*src->w + rect.x;
		for (x = 0; x < size.w; ++x) {
			pos.x = x*scale_x; 
			src_n  = k + x;
			des_n = m + pos.x;
			out_graph->rgba[0][src_n] = src->rgba[0][des_n];
			out_graph->rgba[1][src_n] = src->rgba[1][des_n];
			out_graph->rgba[2][src_n] = src->rgba[2][des_n];
			if( in_graph->color_type == COLOR_TYPE_RGBA) {
				out_graph->rgba[3][src_n] = src->rgba[3][des_n];
			}
		}
	} 
	return 0;
}
Exemplo n.º 14
0
LCUI_API int Graph_HorizFlip( LCUI_Graph *src_graph, LCUI_Graph *out_graph )
{
	int x, y, center;
	int src_left_pos, src_right_pos;
	int des_left_pos, des_right_pos;
	uchar_t buff;
	LCUI_Graph *src;
	LCUI_Rect rect;

	if(!Graph_IsValid(src_graph)) {
		return -1;
	}
	rect = Graph_GetValidRect( src_graph );
	src = Graph_GetQuote( src_graph );
	out_graph->color_type = src->color_type;
	if( 0 != Graph_Create( out_graph, rect.width, rect.height ) ) {
		return -2;	
	}
	/* 水平翻转其实也就是交换两边的数据 */  
	center = (int)(rect.width / 2.0);
	for (y = 0; y < rect.height; ++y) {
		des_left_pos = y * rect.width;
		des_right_pos = des_left_pos + rect.width -1;
		src_left_pos = (y + rect.y) * src->w + rect.x;
		src_right_pos = src_left_pos + rect.width -1;
		for (x = 0; x <= center; ++x)  {
			buff = src->rgba[0][src_left_pos]; 
			out_graph->rgba[0][des_left_pos] = src->rgba[0][src_right_pos];  
			out_graph->rgba[0][des_right_pos] = buff;

			buff = src->rgba[1][src_left_pos]; 
			out_graph->rgba[1][des_left_pos] = src->rgba[1][src_right_pos];  
			out_graph->rgba[1][des_right_pos] = buff;

			buff = src->rgba[2][src_left_pos]; 
			out_graph->rgba[2][des_left_pos] = src->rgba[2][src_right_pos];  
			out_graph->rgba[2][des_right_pos] = buff;

			if(src->color_type == COLOR_TYPE_RGBA) {
				buff = src->rgba[3][src_left_pos]; 
				out_graph->rgba[3][des_left_pos] = src->rgba[3][src_right_pos];  
				out_graph->rgba[3][des_right_pos] = buff;
			}
			++src_left_pos;
			++des_left_pos;
			--src_right_pos;
			--des_right_pos;
		}
	} 
	return 0;
}
Exemplo n.º 15
0
Arquivo: win32.c Projeto: yydaor/LCUI
LCUI_API int
LCUIScreen_PutGraph (LCUI_Graph *graph, LCUI_Pos des_pos )
{
	int total, y, n, des_row_x, src_row_x, des_x, src_x;
	LCUI_Graph *src;
	LCUI_Rect cut, src_rect;
	LCUI_Size screen_size;
	uchar_t *des_ptr;
	
	src = Graph_GetQuote( graph );
	src_rect = Graph_GetValidRect( graph );
	screen_size = LCUIScreen_GetSize();
	
	if(!Graph_IsValid(src)) {
		return -1;
	}
	if(des_pos.x >= screen_size.w || des_pos.y >= screen_size.h) {
		return -1;
	}
	des_ptr = pixel_mem;
	Graph_Lock( src );
	/* 获取图像的截取区域 */ 
	if( LCUIRect_GetCutArea( screen_size,
		Rect( des_pos.x, des_pos.y, src_rect.width, src_rect.height ),
		&cut
	)) {
		des_pos.x += cut.x;
		des_pos.y += cut.y;
	}
	/* 根据二维坐标和图像尺寸,计算源图像的起始读取点的一维坐标 */
	src_row_x = (cut.y + src_rect.y) * src->width + cut.x + src_rect.x;
	/* 根据二维坐标和屏幕尺寸,计算帧缓冲的起始写入点的一维坐标 */
	des_row_x = des_pos.y * screen_size.w + des_pos.x;

	for(y=0; y<cut.height; ++y) {
		src_x = src_row_x;
		des_x = des_row_x;
		total = src_x + cut.width;
		for (; src_x < total; ++des_x,++src_x) {
			n = des_x << 2;
			des_ptr[n++] = src->rgba[2][src_x];
			des_ptr[n++] = src->rgba[1][src_x];
			des_ptr[n++] = src->rgba[0][src_x];
		}
		src_row_x += src->width;
		/* DIB扫描行是上下颠倒的,因此是从行尾到行首递减 */
		des_row_x += screen_size.w;
	}
	Graph_Unlock( src );
	return 0;
}
Exemplo n.º 16
0
static void Graph_DrawRightShadow( LCUI_PaintContext paint, LCUI_Rect *box,
				   LCUI_BoxShadow *shadow )
{
	float v, a;
	int s, t, x, y, bound_x, bound_y;
	LCUI_Color color;
	LCUI_Graph *graph;
	LCUI_Rect shadow_area, box_area, area;

	box_area.x = BoxShadow_GetBoxX( shadow );
	box_area.y = BoxShadow_GetBoxY( shadow );
	box_area.w = BoxShadow_GetBoxWidth( shadow, box->w );
	box_area.h = BoxShadow_GetBoxHeight( shadow, box->h );
	shadow_area.x = BoxShadow_GetX( shadow ) + SHADOW_WIDTH(shadow);
	shadow_area.x += box_area.w + INNER_SHADOW_WIDTH(shadow);
	shadow_area.y = BoxShadow_GetY( shadow ) + BLUR_WIDTH(shadow);
	shadow_area.w = BLUR_WIDTH(shadow);
	shadow_area.h = box_area.h + INNER_SHADOW_WIDTH(shadow)*2;
	color = shadow->color;
	bound_x = shadow_area.x + shadow_area.w;
	bound_y = shadow_area.y + shadow_area.h;
	graph = Graph_GetQuote( &paint->canvas );
	Graph_GetValidRect( &paint->canvas, &area );
	if( !LCUIRect_GetOverlayRect( &area, &paint->rect, &area ) ) {
		return;
	}
	s = 255;
	t = BLUR_WIDTH(shadow);
	v = 512.0/t;
	a = 2*(v*t-s)/(t*t);

	for( t=0,x=shadow_area.x; x<bound_x; ++x,++t ) {
		if( x < area.x || x >= area.x + area.w ) {
			continue;
		}
		color.alpha = (uchar_t)(s-(v*t-(a*t*t)/2));
		color.alpha *= shadow->color.a/255.0;
		for( y=shadow_area.y; y<bound_y; ++y ) {
			if( y < area.y || y >= area.y + area.h ) {
				continue;
			}
			if( y >= box_area.y && y < box_area.y + box_area.h
			 && x >= box_area.x && x < box_area.x + box_area.w ) {
				 continue;
			}
			Graph_SetPixel( graph, x, y, color );
		}
	}
}
Exemplo n.º 17
0
Arquivo: graph.c Projeto: rokite/LCUI
static int Graph_ZoomRGB( const LCUI_Graph *graph,
			  LCUI_Graph *buff,
			  LCUI_BOOL keep_scale,
			  LCUI_Size size )
{
	LCUI_Rect rect;
	int x, y, src_x, src_y, tmp;
	double scale_x, scale_y;
	uchar_t *byte_src, *byte_des;

	if( !Graph_IsValid(graph) ) {
		return -1;
	}
	if( size.w <= 0 || size.h <= 0 ) {
		Graph_Free( buff );
		return -1;
	}
	/* 获取引用的有效区域,以及指向引用的对象的指针 */
	Graph_GetValidRect( graph, &rect );
	graph = Graph_GetQuote( graph );
	scale_x = (double)rect.width / size.w;
	scale_y = (double)rect.height / size.h;
	/* 如果保持宽高比 */
	if( keep_scale ) {
		if (scale_x<scale_y) {
			scale_y = scale_x;
		} else {
			scale_x = scale_y;
		}
	}
	buff->color_type = graph->color_type;
	if( Graph_Create(buff, size.w, size.h) < 0) {
		return -2;
	}

	for( y=0; y < size.h; ++y )  {
		src_y = y * scale_y;
		tmp = ((src_y + rect.y) * graph->w + rect.x) * 3;
		byte_des = buff->bytes + y * size.w * 3;
		for( x=0; x < size.w; ++x ) {
			src_x = x * scale_x * 3;
			byte_src = graph->bytes + tmp + src_x;
			*byte_des++ = *byte_src++;
			*byte_des++ = *byte_src++;
			*byte_des++ = *byte_src++;
		}
	}
	return 0;
}
Exemplo n.º 18
0
LCUI_API int Graph_FillRect( LCUI_Graph *graph, LCUI_RGB color, LCUI_Rect rect )
{
	size_t size;
	int pos, y;
	LCUI_Rect src_rect;
	uchar_t *r_ptr, *g_ptr, *b_ptr;
	
	src_rect = Graph_GetValidRect( graph ); 
	graph = Graph_GetQuote( graph );
	
	if(! Graph_IsValid(graph) ) {
		return -1;
	}
	rect.x = rect.x + src_rect.x;
	rect.y = rect.y + src_rect.y;
	/* 计算出该填充区域实际的有效区域范围 */
	if( rect.x < src_rect.x ) {
		rect.width -= (src_rect.x-rect.x);
		rect.x = src_rect.x;
	}
	if( rect.x + rect.width > src_rect.x + src_rect.width ) {
		rect.width = src_rect.x + src_rect.width - rect.x;
	}
	
	if( rect.y < src_rect.y ) {
		rect.height -= (src_rect.y-rect.y);
		rect.y = src_rect.y;
	}
	if( rect.y + rect.height > src_rect.x + src_rect.height ) {
		rect.height = src_rect.y + src_rect.height - rect.y;
	}
	size = sizeof(uchar_t) * rect.width;
	pos = rect.x + rect.y * graph->w;
	r_ptr = graph->rgba[0] + pos;
	g_ptr = graph->rgba[1] + pos;
	b_ptr = graph->rgba[2] + pos;
	for(y=0; y<rect.height; ++y) {
		memset( r_ptr, color.red, size );
		memset( g_ptr, color.green, size );
		memset( b_ptr, color.blue, size );
		r_ptr += graph->w;
		g_ptr += graph->w;
		b_ptr += graph->w;
	}
	return 0; 
}
Exemplo n.º 19
0
static int Graph_FillRectARGB( LCUI_Graph *graph, LCUI_Color color,
			       LCUI_Rect rect )
{
	int x, y;
	LCUI_Rect rect_src;
	LCUI_ARGB *px_p, *px_row_p;

	if(!Graph_IsValid(graph)) {
		return -1;
	}
	Graph_GetValidRect( graph, &rect_src );
	graph = Graph_GetQuote( graph );
	px_row_p = graph->argb + (rect_src.y+rect.y)*graph->w;
	px_row_p += rect.x + rect_src.x;
	for( y=0; y<rect.h; ++y ) {
		px_p = px_row_p;
		for( x=0; x<rect.w; ++x ) {
			*px_p++ = color;
		}
		px_row_p += graph->w;
	}
	return 0;
}
Exemplo n.º 20
0
LCUI_API int Graph_Mix(	LCUI_Graph *back_graph, 
			LCUI_Graph *fore_graph,
			LCUI_Pos des_pos )
{
	LCUI_Graph *src, *des;
	LCUI_Rect cut, src_rect, area, des_rect;
	LCUI_Size box_size;
	LCUI_Pos src_pos;
	
	/* 预先进行有效性判断 */
	if( !Graph_IsValid(back_graph)
	 || !Graph_IsValid(fore_graph) ) {
		return -1;
	}
	/* 获取引用的源图像的最终区域 */
	src_rect = Graph_GetValidRect(fore_graph);
	des_rect = Graph_GetValidRect(back_graph);
	/* 获取引用的源图像 */
	src = Graph_GetQuote(fore_graph);
	des = Graph_GetQuote(back_graph);  
	/* 判断引用的源图像的有效性 */
	if(!Graph_IsValid(des) || !Graph_IsValid(src)) {
		return -1;
	} 
	/* 判断坐标是否在背景图的范围内 */
	if(des_pos.x > des->w || des_pos.y > des->h) {
		return -1;
	}
	/* 记录容器尺寸 */
	box_size.w = des_rect.width;
	box_size.h = des_rect.height;
	/* 记录前景图像在容器中的区域 */
	area.x = des_pos.x;
	area.y = des_pos.y;
	area.width = src_rect.width;
	area.height = src_rect.height;
	/* 获取前景图像区域中的需要裁减的区域 */ 
	LCUIRect_GetCutArea( box_size, area, &cut );
	/* 移动前景图像区域的坐标 */
	des_pos.x += cut.x;
	des_pos.y += cut.y;
	/* 得出源图像的读取区域的坐标 */
	src_pos.x = cut.x + src_rect.x;
	src_pos.y = cut.y + src_rect.y;
	/* 得出目标图像的写入区域 */
	des_rect.x = des_pos.x + des_rect.x;
	des_rect.y = des_pos.y + des_rect.y;
	des_rect.width = cut.width;
	des_rect.height = cut.height;
	
	/* 如果前景图像有alpha通道 */
	if( src->color_type == COLOR_TYPE_RGBA ) {
		/* 如果全局透明度为255,则说明混合时不需要考虑全局透明度 */
		if( src->alpha == 255 ) {
			Graph_RGBAMix( des, des_rect, src, src_pos );
			return 0;
		}
		Graph_RGBAMixWithGlobalAlpha( des, des_rect, src, src_pos );
		return 0;
	}
	/* 否则,前景图像没有Alpha通道 */

	/* 如果全局透明度为255,说明前景图形没有透明效果 */
	if( src->alpha == 255 ) { 
		Graph_RGBMix( des, des_rect, src, src_pos );
		return 0;
	}
	/* 否则,将全局透明度计算在内,进行alpha混合 */
	Graph_RGBMixWithGlobalAlpha( des, des_rect, des, src_pos );
	return 0;
}
Exemplo n.º 21
0
Arquivo: border.c Projeto: yydaor/LCUI
static int
Graph_Draw_RoundBorder_RightTop( 
	LCUI_Graph *des,	LCUI_Pos center,
	int radius,		int line_width,
	LCUI_RGB line_color,	LCUI_BOOL hide_outarea )
/* 绘制右上角的圆角,从右边框的上端到上边框的右端绘制一条圆角线 */
{
	LCUI_Rect real_rect;
	int pos, center_pos, y, x, i, n;
	int max_x, max_y, min_x, min_y;
	
	if( line_width <= 0 && !hide_outarea ) {
		return 1;
	}
	
	real_rect = Graph_GetValidRect( des );
	des = Graph_GetQuote( des );
	if( !Graph_IsValid( des ) ) {
		return -1;
	}
	
	max_x = radius*2;
	if( center.x+radius > real_rect.x + real_rect.width ) {
		max_x -= (center.x+radius-real_rect.x-real_rect.width);
	}
	if( max_x < 0 ) {
		max_x = 0;
	}
	min_x = center.x>radius? 0:radius-center.x;
	if( min_x < 0 ) {
		min_x = 0;
	}
	max_y = radius*2;
	if( center.y+radius > real_rect.y + real_rect.height ) {
		max_y -= (center.y+radius-real_rect.y-real_rect.height);
	}
	min_y = center.y>radius? 0:radius-center.y;
	if( min_y < 0 ) {
		min_y = 0;
	}
	
	center_pos = (real_rect.y + center.y) * des->width;
	center_pos = center_pos + center.x + real_rect.x;
	
	for( y=0; y<=radius; ++y, center_pos -= des->width ) {
		if( radius-y >= max_y || radius-y < min_y ) {
			continue;
		}
		x = (int)sqrt( pow(radius, 2) - y*y );
		
		if( line_width > 0 && radius+x >= min_x 
		 && radius+x <= max_x ) {
			pos = center_pos + x;
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
		
		if( hide_outarea && des->have_alpha ) {
			n = center_pos + max_x - radius;
			if( radius+x < min_x ) {
				pos = center_pos + min_x - radius;
			} else {
				pos = center_pos + x;
			}
			for( ++pos; pos<=n; ++pos ) {
				des->rgba[3][pos] = 0;
			}
		}
		
		/* 计算需要向左填充的像素点的个数n */
		n = radius+x-line_width;
		n = n<min_x ? x+radius-min_x:line_width;
		
		if( radius+x > max_x ) {
			pos = center_pos - radius+max_x-1;
			n -= (radius+x-max_x);
		} else {
			pos = center_pos + x;
		}
		for(i=0; i<n; ++i,--pos) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
	}
	return 0;
}
Exemplo n.º 22
0
/**
 * 绘制上边阴影
 * @param[in] paint 绘制上下文
 * @param[in] box 可供绘制阴影的区域范围
 * @param[in] shadow 阴影参数
 */
static void Graph_DrawTopShadow( LCUI_PaintContext paint, LCUI_Rect *box,
				 LCUI_BoxShadow *shadow )
{
	float v, a;
	LCUI_Color color;
	LCUI_Graph *graph;
	int s, t, x, y, bound_x, bound_y;
	LCUI_Rect shadow_area, box_area, paint_area, area;

	/**
	* 这里采用匀减速直线运动的公式: s = vt - at²/2
	* 加速度 a 的求值公式为:a = 2x(vt - s)/t²
	*/
	s = 255;
	t = BLUR_WIDTH( shadow );
	v = 512.0 / t;
	a = 2 * (v*t - s) / (t*t);
	color = shadow->color;
	/* 计算阴影内框区域 */
	box_area.x = BoxShadow_GetBoxX( shadow );
	box_area.y = BoxShadow_GetBoxY( shadow );
	box_area.w = BoxShadow_GetBoxWidth( shadow, box->w );
	box_area.h = BoxShadow_GetBoxHeight( shadow, box->h );
	/* 计算需要绘制的阴影区域 */
	shadow_area.x = BoxShadow_GetX( shadow ) + BLUR_WIDTH(shadow);
	shadow_area.y = BoxShadow_GetY( shadow );
	shadow_area.w = box_area.w + INNER_SHADOW_WIDTH(shadow)*2;
	shadow_area.h = BLUR_WIDTH(shadow);
	/* 调整坐标 */
	box_area.x += box->x;
	box_area.y += box->y;
	shadow_area.x += box->x;
	shadow_area.y += box->y;
	/* 如果阴影区域不在绘制范围内 */
	if( !LCUIRect_GetOverlayRect( &shadow_area, &paint->rect, &area ) ) {
		return;
	}
	/* 获取有效的绘制范围 */
	Graph_GetValidRect( &paint->canvas, &paint_area );
	graph = Graph_GetQuote( &paint->canvas );
	/* 将坐标转换成相对于绘制区域 */
	shadow_area.x -= paint->rect.x;
	shadow_area.y -= paint->rect.y;
	box_area.x -= paint->rect.x;
	box_area.y -= paint->rect.y;
	area.x -= paint->rect.x;
	area.y -= paint->rect.y;
	bound_x = area.x + area.width;
	bound_y = area.y + area.height;
	/* 避免超出绘制范围 */
	if( bound_x > paint_area.x + paint_area.width ) {
		bound_x = paint_area.x + paint_area.width;
	}
	if( bound_y > paint_area.y + paint_area.height ) {
		bound_y = paint_area.y + paint_area.height;
	}
	t -= area.x - shadow_area.x;
	for( y = area.y; y < bound_y; ++y, --t ) {
		/* 计算当前行像素点的透明度 */
		color.alpha = (uchar_t)(s - (v*t - (a*t*t) / 2));
		color.alpha *= shadow->color.a / 255.0;
		for( x = area.x; x < bound_x; ++x ) {
			if( y >= box_area.y && y < box_area.y + box_area.h
			    && x >= box_area.x && x < box_area.x + box_area.w ) {
				continue;
			}
			Graph_SetPixel( graph, x, y, color );
		}
	}
}
Exemplo n.º 23
0
LCUI_API int Graph_Replace(	LCUI_Graph *back_graph,
				LCUI_Graph *fore_graph,
				LCUI_Pos des_pos )
{
	LCUI_Graph *src, *des;
	LCUI_Rect cut, src_rect, area, des_rect;
	LCUI_Size box_size;
	LCUI_Pos src_pos;
	
	/* 预先进行有效性判断 */
	if( !Graph_IsValid(back_graph)
	 || !Graph_IsValid(fore_graph) ) {
		return -1;
	}
	/* 获取引用的源图像的最终区域 */
	src_rect = Graph_GetValidRect(fore_graph);
	des_rect = Graph_GetValidRect(back_graph);
	/* 获取引用的源图像 */
	src = Graph_GetQuote(fore_graph);
	des = Graph_GetQuote(back_graph);  
	/* 判断引用的源图像的有效性 */
	if(!Graph_IsValid(des) || !Graph_IsValid(src)) {
		return -1;
	} 
	/* 判断坐标是否在背景图的范围内 */
	if(des_pos.x > des->w || des_pos.y > des->h) {
		return -1;
	}
	/* 记录容器尺寸 */
	box_size.w = des_rect.width;
	box_size.h = des_rect.height;
	/* 记录前景图像在容器中的区域 */
	area.x = des_pos.x;
	area.y = des_pos.y;
	area.width = src_rect.width;
	area.height = src_rect.height;
	/* 获取前景图像区域中的需要裁减的区域 */ 
	LCUIRect_GetCutArea( box_size, area, &cut );
	/* 移动前景图像区域的坐标 */
	des_pos.x += cut.x;
	des_pos.y += cut.y;
	/* 得出源图像的读取区域的坐标 */
	src_pos.x = cut.x + src_rect.x;
	src_pos.y = cut.y + src_rect.y;
	/* 得出目标图像的写入区域 */
	des_rect.x = des_pos.x + des_rect.x;
	des_rect.y = des_pos.y + des_rect.y;
	des_rect.width = cut.width;
	des_rect.height = cut.height;
	/* 如果前景图像有透明度 */
	if( src->color_type == COLOR_TYPE_RGBA ) {
		 /* 若背景图有透明度 */
		if( des->color_type == COLOR_TYPE_RGBA ) {
			return Graph_DirectReplace( des, des_rect, src, src_pos );
		}
		if( src->alpha == 255 ) {
			return Graph_RGBAReplaceRGB( des, des_rect, src, src_pos );
		}
		return Graph_RGBAReplaceRGBWithGlobalAlpha( des, des_rect, src, src_pos );
	}
	if( des->color_type == COLOR_TYPE_RGBA ) {
		return Graph_RGBReplaceRGBA( des, des_rect, src, src_pos );
	}
	return Graph_DirectReplace( des, des_rect, src, src_pos );
}
Exemplo n.º 24
0
Arquivo: border.c Projeto: yydaor/LCUI
static int
Graph_Draw_RoundBorder_LeftTop( 
	LCUI_Graph *des,	LCUI_Pos center,
	int radius,		int line_width,
	LCUI_RGB line_color,	LCUI_BOOL hide_outarea )
/* 绘制左上角的圆角,从左边框的上端到上边框的左端绘制一条圆角线 */
{
	LCUI_Rect real_rect;
	int pos, center_pos, y, x, i, n;
	int max_x, max_y, min_x, min_y;
	
	if( line_width <= 0 && !hide_outarea ) {
		return 1;
	}
	
	real_rect = Graph_GetValidRect( des );
	des = Graph_GetQuote( des );
	if( !Graph_IsValid( des ) ) {
		return -1;
	}
	/* 预先计算xy轴坐标的有效范围 */
	max_x = radius*2;
	if( center.x+radius > real_rect.x + real_rect.width ) {
		max_x -= (center.x+radius-real_rect.x-real_rect.width);
	}
	if( max_x < 0 ) {
		max_x = 0;
	}
	min_x = center.x>radius? 0:radius-center.x;
	if( min_x < 0 ) {
		min_x = 0;
	}
	max_y = radius*2;
	if( center.y+radius > real_rect.y + real_rect.height ) {
		max_y -= (center.y+radius-real_rect.y-real_rect.height);
	}
	min_y = center.y>radius? 0:radius-center.y;
	if( min_y < 0 ) {
		min_y = 0;
	}
	
	/* 预先计算圆心的线性坐标 */
	center_pos = (real_rect.y + center.y) * des->width;
	center_pos = center_pos + center.x + real_rect.x;

	/* 根据y轴计算各点的x轴坐标并填充点 */
	for( y=0; y<=radius; ++y, center_pos -= des->width ) {
		if( radius-y >= max_y || radius-y < min_y ) {
			continue;
		}
		/* 计算出x轴整数坐标 */
		x = (int)sqrt( pow(radius, 2) - y*y );
		
		if( line_width > 0 && radius-x >= min_x 
		 && radius-x <= max_x ) {
			pos = center_pos - x;
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
		
		if( hide_outarea && des->have_alpha ) {
			/* 计算起点坐标 */
			pos = center_pos - center.x;
			if( radius-x > max_x ) {
				n = max_x - min_x;
			} else {
				n = radius-x-min_x;
			}
			/* 加上圆与背景图的左边距 */
			n += (center.x-radius);
			for(i=0; i<n; ++i) {
				des->rgba[3][pos++]=0;
			}
		}
		/* 计算需要向右填充的像素点的个数n */
		n = radius-x+line_width;
		n = n>radius ? x:line_width;
		/* 如果该点x轴坐标小于最小x轴坐标 */
		if( radius-x < min_x ) {
			/* 重新确定起点坐标pos和填充的像素点的个数n */
			pos = center_pos - radius+min_x-1;
			n -= (min_x-radius+x);
		} else {
			pos = center_pos - x;
		}
		/* 从下一个像素点开始 */
		++pos;
		/* 如果填充的像素点超出了最大x轴范围 */
		if( radius-x + n > max_x ) {
			/* 重新确定需要填充的像素点的个数n */
			n = max_x - radius + x;
		}
		/* 开始填充当前点右边的n-1个像素点 */
		for(i=0; i<n-1; ++i,++pos) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
	}
	return 0;
}
Exemplo n.º 25
0
Arquivo: border.c Projeto: yydaor/LCUI
static int
Graph_Draw_RoundBorder_BottomLeft(
	LCUI_Graph *des,	LCUI_Pos center,
	int radius,		int line_width,
	LCUI_RGB line_color,	LCUI_BOOL hide_outarea )
/* 绘制左下角的圆角,从下边框的左端到左边框的下端绘制一条圆角线 */
{
	LCUI_Rect real_rect;
	int tmp_pos, pos, center_pos, y, x, i, n;
	int max_x, max_y, min_x, min_y;
	
	if( line_width <= 0 && !hide_outarea ) {
		return 1;
	}
	
	real_rect = Graph_GetValidRect( des );
	des = Graph_GetQuote( des );
	if( !Graph_IsValid( des ) ) {
		return -1;
	}
	
	max_x = radius*2;
	if( center.x+radius > real_rect.x + real_rect.width ) {
		max_x -= (center.x+radius-real_rect.x-real_rect.width);
	}
	if( max_x < 0 ) {
		max_x = 0;
	}
	min_x = center.x>radius? 0:radius-center.x;
	if( min_x < 0 ) {
		min_x = 0;
	}
	max_y = radius*2;
	if( center.y+radius > real_rect.y + real_rect.height ) {
		max_y -= (center.y+radius-real_rect.y-real_rect.height);
	}
	min_y = center.y>radius? 0:radius-center.y;
	if( min_y < 0 ) {
		min_y = 0;
	}
	
	center_pos = (real_rect.y + center.y) * des->width;
	center_pos = center_pos + center.x + real_rect.x;

	for( x=0; x<=radius; ++x ) {
		if( radius-x >= max_x || radius-x < min_x ) {
			continue;
		}
		
		y = (int)sqrt( pow(radius, 2) - x*x );
		
		if( radius+y > max_y ) {
			pos = center_pos;
			pos += (max_y-radius)*des->width;
		} else {
			pos = center_pos + y * des->width - x;
		}
		
		if( line_width > 0 && radius+y >= min_y 
		 && radius+y <= max_y ) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
		
		if( hide_outarea && des->have_alpha ) {
			tmp_pos = pos;
			if( radius+y < min_y ) {
				n = max_y - min_y;
			} else {
				n = max_y-radius-y;
			}
			/* 加上圆与背景图的下边距 */
			n += (real_rect.height-center.y-radius);
			tmp_pos+=des->width;
			for(i=0; i<n; ++i,tmp_pos+=des->width) {
				des->rgba[3][tmp_pos]=0;
			}
		}
		/* 计算需要向上填充的像素点的个数n */
		n = radius+y-line_width;
		/* 判断是否超过圆的x轴对称线 */
		n = n<radius ? y:line_width;
		if( radius+y > max_y ) {
			n -= (radius+y-max_y);
		}
		/* 从上一行像素点开始 */
		pos -= des->width;
		if( radius+y - n < min_y ) {
			n = min_y - radius - y;
		}
		/* 开始填充当前点下边的n-1个像素点 */
		for(i=0; i<n-1; ++i,pos-=des->width) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
	}
	return 0;
}
Exemplo n.º 26
0
Arquivo: border.c Projeto: yydaor/LCUI
static int
Graph_Draw_RoundBorder_LeftBottom(
	LCUI_Graph *des,	LCUI_Pos center,
	int radius,		int line_width,
	LCUI_RGB line_color,	LCUI_BOOL hide_outarea )
/* 绘制左下角的圆角,从左边框的下端到下边框的左端绘制一条圆角线 */
{
	LCUI_Rect real_rect;
	int pos, center_pos, y, x, i, n;
	int max_x, max_y, min_x, min_y;
	
	if( line_width <= 0 && !hide_outarea ) {
		return 1;
	}
	
	real_rect = Graph_GetValidRect( des );
	des = Graph_GetQuote( des );
	if( !Graph_IsValid( des ) ) {
		return -1;
	}
	
	max_x = radius*2;
	if( center.x+radius > real_rect.x + real_rect.width ) {
		max_x -= (center.x+radius-real_rect.x-real_rect.width);
	}
	if( max_x < 0 ) {
		max_x = 0;
	}
	min_x = center.x>radius? 0:radius-center.x;
	if( min_x < 0 ) {
		min_x = 0;
	}
	max_y = radius*2;
	if( center.y+radius > real_rect.y + real_rect.height ) {
		max_y -= (center.y+radius-real_rect.y-real_rect.height);
	}
	min_y = center.y>radius? 0:radius-center.y;
	if( min_y < 0 ) {
		min_y = 0;
	}
	
	center_pos = (real_rect.y + center.y) * des->width;
	center_pos = center_pos + center.x + real_rect.x;

	if( hide_outarea && des->have_alpha ) {
		
	}
	for( y=0; y<=radius; ++y, center_pos += des->width ) {
		if( radius+y >= max_y || radius+y < min_y ) {
			continue;
		}
		x = (int)sqrt( pow(radius, 2) - y*y );
		
		if( line_width > 0 && radius-x >= min_x 
		 && radius-x <= max_x ) {
			pos = center_pos - x;
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
		if( hide_outarea && des->have_alpha ) {
			pos = center_pos - center.x;
			if( radius-x > max_x ) {
				n = max_x - min_x;
			} else {
				n = radius-x-min_x;
			}
			n += (center.x-radius);
			for(i=0; i<n; ++i) {
				des->rgba[3][pos++]=0;
			}
		}
		n = radius-x+line_width;
		n = n>radius ? x:line_width;
		if( radius-x < min_x ) {
			pos = center_pos - radius+min_x-1;
			n -= (min_x-radius+x);
		} else {
			pos = center_pos - x;
		}
		++pos;
		if( radius-x + n > max_x ) {
			n = max_x - radius + x;
		}
		for(i=0; i<n-1; ++i,++pos) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
	}
	return 0;
}
Exemplo n.º 27
0
static void DrawCircle( LCUI_Graph *graph, LCUI_Pos center,
			int r, LCUI_ARGB color )
{
	int x, y;
	int t = r;
	int s = 255;
	float v = 512.0/t;
	float a = 2*(v*t-s)/(t*t);
	LCUI_Rect area, box_rect;
	LCUI_Graph *src, box_graph;
	LCUI_ARGB tmp_px, *px;
	uchar_t *px_row_bytes;
	LCUI_Rect2 circle;

	tmp_px = color;
	Graph_GetValidRect( graph, &area );
	src = Graph_GetQuote( graph );
	center.x += area.x;
	center.y += area.y;
	circle.r = center.x + r;
	circle.l = center.x - r;
	circle.b = center.y + r;
	circle.t = center.y - r;
	/* 先填充 圆外切矩形 外的矩形区域 */
	box_rect.x = area.x;
	box_rect.y = area.y;
	box_rect.w = area.w;
	box_rect.h = circle.t - area.y;
	Graph_Quote( &box_graph, src, &box_rect );
	Graph_FillAlpha( &box_graph, 0 );
	box_rect.y = circle.t;
	box_rect.w = circle.l - area.x;
	box_rect.h = area.y + area.h - circle.t;
	Graph_Quote( &box_graph, src, &box_rect );
	Graph_FillAlpha( &box_graph, 0 );
	/* 调整圆的区域 */
	if( circle.l < area.x ) {
		circle.l = area.x;
	}
	if( circle.t < area.y ) {
		circle.t = area.y;
	}
	if( circle.r > area.x + area.w ) {
		circle.r = area.x + area.w;
	}
	if( circle.b > area.y + area.h ) {
		circle.b = area.y + area.h;
	}
	if( src->color_type != COLOR_TYPE_ARGB ) {
		return;
	}
	px_row_bytes = src->bytes + circle.top*src->bytes_per_row;
	px_row_bytes += circle.left * src->bytes_per_pixel;
	/* 遍历区域内每个像素点,根据点到圆心的距离,计算其alpha透明度 */
	for( y=circle.top; y<circle.bottom; ++y ) {
		px = (LCUI_ARGB*)px_row_bytes;
		for( x=circle.left; x<circle.right; ++x ) {
			t = (y-center.y)*(y-center.y);
			t += (x-center.x)*(x-center.x);
			t = (int)((double)sqrt(1.0*t)+0.5);
			if( t <= r ) {
				tmp_px.a = (uchar_t)(s-(v*t-(a*t*t)/2));
				tmp_px.a *= color.a/255.0;
			} else {
				tmp_px.alpha = 0;
			}
			*px++ = tmp_px;
		}
		px_row_bytes += src->bytes_per_row;
	}
}
Exemplo n.º 28
0
LCUI_API LCUI_Rect Graph_GetValidRect( LCUI_Graph *graph )
{
	int x, y, w, h, temp; 
	LCUI_Rect rect, cut_rect;
	
	x = cut_rect.x = graph->x;
	y = cut_rect.y = graph->y;
	cut_rect.width = graph->w;
	cut_rect.height = graph->h;
	
	if( !graph->quote ) {
		return cut_rect; 
	} else {
		w = graph->src->w;
		h = graph->src->h;
	} 
	/* 获取需裁剪的区域 */
	if(x < 0) {
		cut_rect.width += x;
		cut_rect.x = 0 - x; 
	}
	if(x + graph->w > w) {
		cut_rect.width -= (x +  graph->w - w); 
	}
	
	if(y < 0) {
		cut_rect.height += y;
		cut_rect.y = 0 - y; 
	}
	if(y + graph->h > h) {
		cut_rect.height -= (y +  graph->h - h); 
	}
	
	/* 获取引用的图像的有效显示范围 */
	rect = Graph_GetValidRect(graph->src);
	/* 如果引用的图像需要裁剪,那么,该图像根据情况,也需要进行裁剪 */
	if(rect.x > 0) { 
		temp = x + cut_rect.x;
		if(temp < rect.x) { 
			temp = rect.x - x; 
			cut_rect.width -= (temp - cut_rect.x); 
			cut_rect.x = temp; 
		}
	}
	if(rect.y > 0) {
		temp = y + cut_rect.y;
		if(y < rect.y) {
			temp = rect.y - y;
			cut_rect.height -= (temp - cut_rect.y);
			cut_rect.y = temp;
		}
	}
	if(rect.width < w) { 
		temp = x + cut_rect.x + cut_rect.width;
		if(temp > rect.x + rect.width) {
			cut_rect.width -= (temp-(rect.x+rect.width));
		}
	}
	if(rect.height < h) {
		temp = y + cut_rect.y+cut_rect.height;
		if(temp > rect.y+rect.height) {
			cut_rect.height -= (temp-(rect.y+rect.height));
		}
	} 
	
	return cut_rect;
}
Exemplo n.º 29
0
Arquivo: border.c Projeto: yydaor/LCUI
static int
Graph_Draw_RoundBorder_BottomRight(
	LCUI_Graph *des,	LCUI_Pos center,
	int radius,		int line_width,
	LCUI_RGB line_color,	LCUI_BOOL hide_outarea )
/* 绘制右下角的圆角,从下边框的右端到右边框的下端绘制一条圆角线 */
{
	LCUI_Rect real_rect;
	int pos, center_pos, y, x, i, n;
	int max_x, max_y, min_x, min_y;
	
	if( line_width <= 0 && !hide_outarea ) {
		return 1;
	}
	
	real_rect = Graph_GetValidRect( des );
	des = Graph_GetQuote( des );
	if( !Graph_IsValid( des ) ) {
		return -1;
	}
	
	max_x = radius*2;
	if( center.x+radius > real_rect.x + real_rect.width ) {
		max_x -= (center.x+radius-real_rect.x-real_rect.width);
	}
	if( max_x < 0 ) {
		max_x = 0;
	}
	min_x = center.x>radius? 0:radius-center.x;
	if( min_x < 0 ) {
		min_x = 0;
	}
	max_y = radius*2;
	if( center.y+radius > real_rect.y + real_rect.height ) {
		max_y -= (center.y+radius-real_rect.y-real_rect.height);
	}
	min_y = center.y>radius? 0:radius-center.y;
	if( min_y < 0 ) {
		min_y = 0;
	}
	
	center_pos = (real_rect.y + center.y) * des->width;
	center_pos = center_pos + center.x + real_rect.x;

	for( x=0; x<=radius; ++x ) {
		if( radius+x >= max_x || radius+x < min_x ) {
			continue;
		}
		
		y = (int)sqrt( pow(radius, 2) - x*x );
		
		if( line_width > 0 && radius+y >= min_y 
		 && radius+y < max_y ) {
			pos = center_pos + y * des->width + x;
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
		if( hide_outarea && des->have_alpha ) {
			if( radius+y > max_y ) {
				pos = center_pos;
				pos += (max_y-radius)*des->width;
			} else {
				pos = center_pos + y * des->width + x;
			}
			if( radius+y < min_y ) {
				n = max_y - min_y;
			} else {
				n = max_y-radius-y;
			}
			n += (real_rect.height-center.y-radius);
			pos+=des->width;
			for(i=0; i<n; ++i,pos+=des->width) {
				des->rgba[3][pos]=0;
			}
		}
		
		n = radius+y-line_width;
		n = n<radius ? y:line_width;
		if( radius+y > max_y ) {
			pos = center_pos + (max_y-radius)*des->width;
			n -= (radius+y-max_y);
		} else {
			pos = center_pos + y * des->width + x;
		}
		if( radius+y - n < min_y ) {
			n = min_y - radius - y;
		}
		pos -= des->width;
		for(i=0; i<n-1; ++i,pos-=des->width) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
	}
	return 0;
}
Exemplo n.º 30
0
Arquivo: border.c Projeto: yydaor/LCUI
static int
Graph_Draw_RoundBorder_TopLeft( 
	LCUI_Graph *des,	LCUI_Pos center,
	int radius,		int line_width,
	LCUI_RGB line_color,	LCUI_BOOL hide_outarea )
/* 绘制左上角的圆角,从上边框的左端到左边框的上端绘制一条圆角线 */
{
	LCUI_Rect real_rect;
	int pos, center_pos, y, x, i, n;
	int max_x, max_y, min_x, min_y;
	double tmp_pos;
	uchar_t alpha[2];
	
	if( line_width <= 0 && !hide_outarea ) {
		return 1;
	}
	
	real_rect = Graph_GetValidRect( des );
	des = Graph_GetQuote( des );
	if( !Graph_IsValid( des ) ) {
		return -1;
	}
	/* 预先计算xy轴坐标的有效范围 */
	max_x = radius*2;
	if( center.x+radius > real_rect.x + real_rect.width ) {
		max_x -= (center.x+radius-real_rect.x-real_rect.width);
	}
	if( max_x < 0 ) {
		max_x = 0;
	}
	min_x = center.x>radius? 0:radius-center.x;
	if( min_x < 0 ) {
		min_x = 0;
	}
	max_y = radius*2;
	if( center.y+radius > real_rect.y + real_rect.height ) {
		max_y -= (center.y+radius-real_rect.y-real_rect.height);
	}
	min_y = center.y>radius? 0:radius-center.y;
	if( min_y < 0 ) {
		min_y = 0;
	}
	
	center_pos = (real_rect.y + center.y) * des->width;
	center_pos = center_pos + center.x + real_rect.x;

	for( x=0; x<=radius; ++x ) {
		if( radius-x >= max_x || radius-x < min_x ) {
			continue;
		}
		tmp_pos = sqrt( pow(radius, 2) - x*x );
		y = (int)tmp_pos;
		alpha[1] =(uchar_t)( 255/(tmp_pos - y));
		alpha[0] = 255-alpha[1];
		
		if( line_width > 0 && radius-y >= min_y 
		 && radius-y <= max_y ) {
			pos = center_pos - y * des->width - x;
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}

		if( hide_outarea && des->have_alpha ) {
			/* 计算起点坐标 */
			if( radius-y < min_y ) {
				pos = center_pos;
				pos -= ((radius+min_y-1)*des->width);
			} else {
				pos = center_pos - y * des->width - x;
			}
			if( radius-y > max_y ) {
				n = max_y - min_y;
			} else {
				n = radius-y-min_y;
			}
			/* 加上圆与背景图的上边距 */
			n += (center.y-radius);
			pos-=des->width;
			for(i=0; i<n; ++i,pos-=des->width) {
				des->rgba[3][pos]=0;
			}
		}
		
		/* 计算需要向下填充的像素点的个数n */
		n = radius-y+line_width;
		n = n>radius ? y:line_width;
		if( radius-y < min_y ) {
			/* 重新确定起点坐标pos和填充的像素点的个数n */
			pos = center_pos - (radius+min_y-1)*des->width;
			n -= (min_y-radius+y);
		} else {
			pos = center_pos - y * des->width - x;
		}
		/* 从下一行像素点开始 */
		pos += des->width;
		/* 如果填充的像素点超出了最大y轴范围 */
		if( radius-y + n > max_y ) {
			/* 重新确定需要填充的像素点的个数n */
			n = max_y - radius + y;
		}
		/* 开始填充当前点下边的n-2个像素点 */
		for(i=0; i<n-1; ++i,pos+=des->width) {
			fill_pixel( des->rgba, pos, line_color );
			if( des->have_alpha ) {
				des->rgba[3][pos] = 255;
			}
		}
	}
	return 0;
}