Beispiel #1
0
static int 
__GraphLayer_GetLayers(
	LCUI_GraphLayer *root_glayer,
	LCUI_GraphLayer *glayer, 
	LCUI_Rect rect, LCUI_Queue *queue )
{
	int i, total;
	LCUI_Pos pos;
	LCUI_Rect tmp;
	LCUI_GraphLayer *child; 
	LCUI_Queue *child_list;

	if( !glayer ) {
		//_DEBUG_MSG("!glayer\n");
		return -1;
	}
	if( !glayer->visible ) {
		//_DEBUG_MSG("!glayer_visible\n");
		return 1;
	}
	child_list = &glayer->child;
	/* 从底到顶遍历子部件 */
	total = Queue_GetTotal( child_list );
	//_DEBUG_MSG( "root: %p, cur: %p, child total: %d\n",
	//		root_glayer, glayer, total );
	/* 从尾到首,从底到顶,遍历图层 */
	for( i=total-1; i>=0; --i ) {
		child = (LCUI_GraphLayer*)Queue_Get( child_list, i );
		/* 忽略无效或不可见的图层 */
		if( !child || !child->visible ) {
			continue;
		}
		/* 获取子图层的有效区域及全局坐标 */
		tmp = GraphLayer_GetValidRect( root_glayer, child );
		pos = GraphLayer_GetGlobalPos( root_glayer, child );
		//_DEBUG_MSG( "child: %p, pos: %d,%d, valid rect: %d,%d, %d, %d\n", 
		//	child, pos.x, pos.y, tmp.x, tmp.y, tmp.width, tmp.height);
		//Graph_PrintInfo( &child->graph );
		/* 有效区域加上子部件的全局坐标 */
		tmp.x += pos.x;
		tmp.y += pos.y;
		/* 判断区域是否有效 */
		if( !LCUIRect_IsValid(tmp) ) {
			continue;
		}
		/* 若该有效区域与目标区域重叠,则记录子部件,并进行递归 */
		if( LCUIRect_Overlay(tmp, rect) ) {
			Queue_AddPointer( queue, child );
			__GraphLayer_GetLayers(	root_glayer, 
						child, rect, queue );
		}
	}
	return 0;
}
Beispiel #2
0
LCUI_API LCUI_Pos
GraphLayer_GetGlobalPos(	LCUI_GraphLayer *root_glayer,
				LCUI_GraphLayer *glayer )
{
	LCUI_Pos pos;
	if( !glayer || !root_glayer || glayer == root_glayer ) {
		return Pos(0,0);
	}
	/* 递归获取父图层的全局坐标 */
	pos = GraphLayer_GetGlobalPos( root_glayer, glayer->parent );
	pos.x += glayer->pos.x;
	pos.y += glayer->pos.y;
	if( glayer->parent ) {
		/* 加上内边距 */
		pos.x += glayer->parent->padding.left;
		pos.y += glayer->parent->padding.top;
	}
	return pos;
}
Beispiel #3
0
LCUI_API int GraphLayer_GetGraph( LCUI_GraphLayer *ctnr, 
				LCUI_Graph *graph_buff, LCUI_Rect rect )
{
	int i, total; 
	uchar_t tmp_alpha, alpha;
	LCUI_Pos pos, glayer_pos;
	LCUI_GraphLayer *glayer;
	LCUI_Queue glayerQ;
	LCUI_Rect valid_area;
	LCUI_Graph tmp_graph;
	
	/* 检测这个区域是否有效 */
	if (rect.x < 0 || rect.y < 0) {
		return -1; 
	}
	if (rect.x + rect.width > ctnr->graph.w
	 || rect.y + rect.height > ctnr->graph.h ) {
		 return -1;
	}
	if (rect.width <= 0 || rect.height <= 0) {
		return -2;
	}
	if( !Graph_IsValid(graph_buff) ) {
	graph_buff->color_type = COLOR_TYPE_ARGB;
		Graph_Create( graph_buff, rect.width, rect.height );
	}

	Graph_Init( &tmp_graph );
	Queue_Init( &glayerQ, 0, NULL);
	Queue_UsingPointer( &glayerQ );
	
	/* 获取rect区域内的图层列表 */
	GraphLayer_GetLayers( ctnr, rect, &glayerQ ); 
	total = Queue_GetTotal( &glayerQ ); 
	DEBUG_MSG( "total: %d\n", total );
	/* 若记录数为零,则表明该区域没有图层 */
	if( total <= 0 ) {
		/* 若没有父图层,则填充白色 */
		if( ctnr == NULL ) {
			Graph_FillColor( graph_buff, RGB(255,255,255) );
		} else { /* 否则使用父图层的图形 */
			Graph_Cut( &ctnr->graph, rect, graph_buff );
		}
		/* 销毁记录 */
		Queue_Destroy( &glayerQ );
		return 0;
	}
	/* 从顶层到底层遍历图层,排除被其它图层完全遮挡或者自身完全透明的图层 */
	for(i=total-1; i>=0; --i) {
		glayer = (LCUI_GraphLayer*)Queue_Get( &glayerQ, i );
		valid_area = GraphLayer_GetValidRect( ctnr, glayer );
		glayer_pos = GraphLayer_GetGlobalPos( ctnr, glayer );
		valid_area.x += glayer_pos.x;
		valid_area.y += glayer_pos.y;
		alpha = GraphLayer_GetRealAlpha( glayer );
		/* 当前图层的透明度小于255的话,就跳过 */
		if( alpha < 255 ) {
			continue;
		}
		/* 跳过有alpha通道的图层 */
		if( glayer->graph.color_type == COLOR_TYPE_ARGB ) {
			continue;
		}
		/* 如果该图层的有效区域包含目标区域 */
		if( rect.x >= valid_area.x && rect.y >= valid_area.y
		 && rect.x + rect.w <= valid_area.x + valid_area.w
		 && rect.y + rect.h <= valid_area.y + valid_area.h ) {
			/* 移除底层的图层,因为已经被完全遮挡 */
			for(total=i-1;total>=0; --total) {
				Queue_DeletePointer( &glayerQ, 0 );
			}
			goto skip_loop;
		}
	}
skip_loop:
	total = Queue_GetTotal( &glayerQ );
	DEBUG_MSG( "total: %d\n", total );
	if(i <= 0 && ctnr ) {
			Graph_Cut( &ctnr->graph, rect, graph_buff );
	}
	/* 获取图层列表中的图层 */
	for(i=0; i<total; ++i) {
		glayer = (LCUI_GraphLayer*)Queue_Get( &glayerQ, i );
		//_DEBUG_MSG("%p = Queue_Get( %p, %d )\n", glayer, &glayerQ, i);
		if( !glayer ) {
			continue;
		}
		DEBUG_MSG("%d,%d,%d,%d\n", glayer->pos.x, glayer->pos.y, glayer->graph.w, glayer->graph.h);
		/* 获取该图层的有效区域及全局坐标 */
		pos = GraphLayer_GetGlobalPos( ctnr, glayer );
		valid_area = GraphLayer_GetValidRect( ctnr, glayer );
		/* 引用该图层的有效区域内的图像 */
		Graph_Quote( &tmp_graph, &glayer->graph, valid_area ); 
		//_DEBUG_MSG("valid area: %d,%d,%d,%d, pos: %d,%d, size: %d,%d\n", 
		//	valid_area.x, valid_area.y, valid_area.width, valid_area.height,
		//	pos.x, pos.y, glayer->graph.w, glayer->graph.h
		//	);
		/* 获取相对坐标 */
		pos.x = pos.x - rect.x + valid_area.x;
		pos.y = pos.y - rect.y + valid_area.y;
		//_DEBUG_MSG("mix pos: %d,%d\n", pos.x, pos.y);
		/* 如果该图层没有继承父图层的透明度 */
		if( !glayer->inherit_alpha ) {
			/* 直接叠加至graph_buff */
			Graph_Mix( graph_buff, &tmp_graph, pos );
		} else {
			/* 否则,计算该图层应有的透明度 */
			alpha = GraphLayer_GetRealAlpha( glayer );
			/* 备份该图层的全局透明度 */
			tmp_alpha = glayer->graph.alpha;
			/* 将实际透明度作为全局透明度,参与图像叠加 */
			glayer->graph.alpha = alpha;
			Graph_Mix( graph_buff, &tmp_graph, pos );
			/* 还原全局透明度 */
			glayer->graph.alpha = tmp_alpha;
		}
	}
	Queue_Destroy( &glayerQ );
	return 0;
}