Exemplo n.º 1
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.º 2
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.º 3
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.º 4
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.º 5
0
/** 将字体位图绘制到目标图像上 */
int FontBMP_Mix( LCUI_Graph *graph, LCUI_Pos pos, 
		 LCUI_FontBMP *bmp, LCUI_Color color )
{
	int val, x, y;
	LCUI_Graph *des;
	LCUI_Rect des_rect, cut;
	LCUI_ARGB *px_des, *px_row_des;
	uchar_t *bmp_src, *bmp_row_src, *byte_row_des, *byte_des;

	/* 数据有效性检测 */
	if( !FontBMP_IsValid( bmp ) || !Graph_IsValid( graph ) ) {
		return -1;
	}
	/* 获取背景图形的有效区域 */
	Graph_GetValidRect( graph, &des_rect );
	/* 获取背景图引用的源图形 */
	des = Graph_GetQuote( graph );
	/* 起点位置的有效性检测 */
	if(pos.x > des->w || pos.y > des->h) {
		return -2;
	}
	/* 获取需要裁剪的区域 */
	LCUIRect_GetCutArea( Size( des_rect.width, des_rect.height ),
			Rect( pos.x, pos.y, bmp->width, bmp->rows ), &cut );
	pos.x += cut.x;
	pos.y += cut.y;
	if( graph->color_type == COLOR_TYPE_ARGB ) {
		bmp_row_src = bmp->buffer + cut.y*bmp->width + cut.x;
		px_row_des = des->argb + (pos.y + des_rect.y) * des->w;
		px_row_des += pos.x + des_rect.x;
		for( y=0; y<cut.h; ++y ) {
			bmp_src = bmp_row_src;
			px_des = px_row_des;
			for( x=0; x<cut.w; ++x ) {
				ALPHA_BLEND( px_des->r, color.r, *bmp_src );
				ALPHA_BLEND( px_des->g, color.g, *bmp_src );
				ALPHA_BLEND( px_des->b, color.b, *bmp_src );
				if( px_des->alpha == 255 || *bmp_src == 255 ) {
					px_des->alpha = 255;
				} else {
					val = (255 - *bmp_src)*(255 - px_des->alpha);
					px_des->alpha = (uchar_t)(255 - val / 65025);
				}
				++bmp_src;
				++px_des;
			}
			px_row_des += des->w;
			bmp_row_src += bmp->width;
		}
		return 0;
	}
	
	bmp_row_src = bmp->buffer + cut.y*bmp->width + cut.x;
	byte_row_des = des->bytes + (pos.y + des_rect.y) * des->bytes_per_row;
	byte_row_des += (pos.x + des_rect.x)*des->bytes_per_pixel;
	for( y=0; y<cut.h; ++y ) { 
		bmp_src = bmp_row_src;
		byte_des = byte_row_des;
		for( x=0; x<cut.w; ++x ) {
			ALPHA_BLEND( *byte_des, color.b, *bmp_src );
			byte_des++;
			ALPHA_BLEND( *byte_des, color.g, *bmp_src );
			byte_des++;
			ALPHA_BLEND( *byte_des, color.r, *bmp_src );
			byte_des++;
			++bmp_src;
		}
		byte_row_des += des->w*3;
		bmp_row_src += bmp->width;
	}
	return 0;
}