예제 #1
0
파일: LCUI_Graph.c 프로젝트: fshunj/LCUI
LCUI_API int Graph_PutImage( LCUI_Graph *graph, LCUI_Graph *image, int flag )
{
	LCUI_Pos pos;
	
	if(!Graph_IsValid(graph) || ! Graph_IsValid(image)) {
		return -1; 
	}
	pos.x = pos.y = 0;
	if((flag & ALIGN_TOP_LEFT) == ALIGN_TOP_LEFT); /* 左上角对齐 */
	else if((flag & ALIGN_TOP_CENTER) == ALIGN_TOP_CENTER) {
		/* 向上中间对齐 */
		pos.x = (graph->w - image->w) / 2;  
	}/* 向右上角对齐 */
	else if((flag & ALIGN_TOP_RIGHT) == ALIGN_TOP_RIGHT) {
		pos.x = graph->w - image->w;
	}/* 向中央偏左对齐 */ 
	else if((flag & ALIGN_MIDDLE_LEFT) == ALIGN_MIDDLE_LEFT) {
		pos.y = (graph->h - image->h) / 2; 
	}/* 向正中央对齐 */
	else if((flag & ALIGN_MIDDLE_CENTER) == ALIGN_MIDDLE_CENTER) { 
		pos.x = (graph->w - image->w) / 2;
		pos.y = (graph->h - image->h) / 2;
	}/* 向中央偏右对齐 */
	else if((flag & ALIGN_MIDDLE_RIGHT) == ALIGN_MIDDLE_RIGHT) { 
		pos.x = graph->w - image->w;
		pos.y = (graph->h - image->h) / 2;
	}/* 向底部偏左对齐 */ 
	else if((flag & ALIGN_BOTTOM_LEFT) == ALIGN_BOTTOM_LEFT) {
		pos.y = graph->h - image->h; 
	}/* 向底部居中对齐 */
	else if((flag & ALIGN_BOTTOM_CENTER) == ALIGN_BOTTOM_CENTER) { 
		pos.x = (graph->w - image->w) / 2;
		pos.y = graph->h - image->h;
	}/* 向底部偏右对齐 */
	else if((flag & ALIGN_BOTTOM_RIGHT) == ALIGN_BOTTOM_RIGHT) { 
		pos.x = graph->w - image->w;
		pos.y = graph->h - image->h;
	}
	
	if( Check_Option(flag, GRAPH_MIX_FLAG_OVERLAY) ) {
	/* 如果包含GRAPH_MIX_FLAG_OVERLAY选项 */
		Graph_Mix(graph, image, pos); 
	}
	else if( Check_Option(flag, GRAPH_MIX_FLAG_REPLACE) ) {
	/* 如果包含GRAPH_MIX_FLAG_REPLACE选项 */
		Graph_Replace(graph, image, pos); 
	} else {
		Graph_Mix(graph, image, pos);
	}
	
	return 0;
}
예제 #2
0
static size_t WidgetRenderer_Render( LCUI_WidgetRenderer renderer )
{
	size_t count = 0;
	LCUI_PaintContextRec self_paint;
	LCUI_WidgetRenderer that = renderer;
	/* 如果部件有需要绘制的内容 */
	if( that->can_render_self ) {
		count += 1;
		self_paint = *that->paint;
		self_paint.canvas = that->self_graph;
		Widget_OnPaint( that->target, &self_paint );
		/* 若不需要缓存自身位图则直接绘制到画布上 */
		if( !that->has_self_graph ) {
			Graph_Mix( &that->paint->canvas, &that->self_graph,
				   0, 0, that->paint->with_alpha );
		}
	}
	if( that->can_render_centent ) {
		count += WidgetRenderer_RenderChildren( that );
	}
	/* 如果与圆角边框重叠,则裁剪掉边框外的内容 */
	if( that->is_cover_border ) {
		/* content_graph ... */
	}
	if( !that->has_layer_graph ) {
		if( that->has_content_graph ) {
			Graph_Mix( &that->paint->canvas, &that->content_graph,
				   that->content_paint_rect.x,
				   that->content_paint_rect.y, TRUE );
		}
		return count;
	}
	/* 若需要绘制的是当前部件图层,则先混合部件自身位图和内容位图,得出当
	 * 前部件的图层,然后将该图层混合到输出的位图中
	 */
	if( that->can_render_self ) {
		Graph_Copy( &that->layer_graph, &that->self_graph );
		Graph_Mix( &that->layer_graph, &that->content_graph,
			   that->content_paint_rect.x,
			   that->content_paint_rect.y, TRUE );
	} else {
		Graph_Create( &that->layer_graph, that->paint->rect.width,
			      that->paint->rect.height );
		Graph_Replace( &that->layer_graph, &that->content_graph,
			       that->content_paint_rect.x,
			       that->content_paint_rect.y );
	}
	that->layer_graph.opacity = that->target->computed_style.opacity;
	Graph_Mix( &that->paint->canvas, &that->layer_graph,
		   0, 0, that->paint->with_alpha );
	return count;
}
예제 #3
0
파일: LCUI_Graph.c 프로젝트: fshunj/LCUI
LCUI_API int Graph_FillImage(	LCUI_Graph *graph,
				LCUI_Graph *bg, 
				int mode,
				LCUI_RGB color )
{
	LCUI_Size size;
	LCUI_Pos pos;
	LCUI_Graph temp_bg;
	LCUI_BOOL replace_mix;
	
	if( Check_Option( mode, GRAPH_MIX_FLAG_REPLACE ) ) {
		/* 将alpha通道置为0 */
		Graph_FillAlpha( graph, 0 );
		replace_mix = TRUE;
	} else {
		/* 填充背景色,将alpha通道置为255 */
		Graph_FillColor( graph, color );
		Graph_FillAlpha( graph, 255 );
		replace_mix = FALSE;
	}
	if(!Graph_IsValid(bg) || !Graph_IsValid(graph)) {
		return -1; 
	}
	size.w = graph->w;
	size.h = graph->h;
	Graph_Init(&temp_bg);
	pos.x = pos.y = 0;
	/* 平铺 */
	if( Check_Option( mode, LAYOUT_TILE ) ) {
		return Graph_Tile( bg, graph, replace_mix );
	}
	/* 缩放 */
	if( Check_Option( mode, LAYOUT_ZOOM ) ) {
		Graph_Zoom( bg, &temp_bg, TRUE, size );
		pos.x = (size.w - temp_bg.w) / 2.0;
		pos.y = (size.h - temp_bg.h) / 2.0;
		bg = &temp_bg;
	}
	/* 拉伸 */
	else if( Check_Option( mode, LAYOUT_STRETCH ) ) {
		Graph_Zoom( bg, &temp_bg, FALSE, size );
		bg = &temp_bg;
	}
	/* 居中 */
	else if( Check_Option( mode, LAYOUT_CENTER ) ) {
		pos.x = (size.w - bg->w) / 2.0;
		pos.y = (size.h - bg->h) / 2.0;
	}
	if( replace_mix ) {
		Graph_Replace( graph, bg, pos );
	} else {
		Graph_Mix( graph, bg, pos );
	}
	Graph_Free( &temp_bg );
	return 0; 
}
예제 #4
0
파일: LCUI_Graph.c 프로젝트: fshunj/LCUI
LCUI_API int Graph_Tile( LCUI_Graph *src, LCUI_Graph *des, LCUI_BOOL replace )
{
	int ret = 0;
	LCUI_Pos pos;
	
	if(!Graph_IsValid(src) || !Graph_IsValid(des)) {
		return -1;
	}
	for(pos.y=0; pos.y<des->h; pos.y+=src->h) {
		for(pos.x=0; pos.x<des->w; pos.x+=src->w) {
			if( replace ) {
				ret += Graph_Replace( des, src, pos );
			} else {
				ret += Graph_Mix( des, src, pos );
			}
		}
	}
	return ret;
}
예제 #5
0
파일: graph.c 프로젝트: WhatDream/LCUI
int Graph_Tile( LCUI_Graph *buff,  const LCUI_Graph *graph,
		LCUI_BOOL replace )
{
	int ret = 0;
	LCUI_Pos pos;

	if(!Graph_IsValid(graph) || !Graph_IsValid(buff)) {
		return -1;
	}
	for(pos.y=0; pos.y<buff->h; pos.y+=graph->h) {
		for(pos.x=0; pos.x<buff->w; pos.x+=graph->w) {
			if( replace ) {
				ret += Graph_Replace( buff, graph, pos );
			} else {
				ret += Graph_Mix( buff, graph, pos );
			}
		}
	}
	return ret;
}
예제 #6
0
파일: widget_paint.c 프로젝트: hbao/LCUI
/**
 * 渲染指定部件呈现的图形内容
 * @param[in] w		部件
 * @param[in] paint 	进行绘制时所需的上下文
 */
void Widget_Render( LCUI_Widget w, LCUI_PaintContext paint )
{
	int i, content_left, content_top;
	LCUI_Rect content_rect;
	LCUI_Graph content_graph, self_graph, layer_graph;
	LCUI_BOOL has_overlay, has_content_graph = FALSE,
		  has_self_graph = FALSE,has_layer_graph = FALSE,
		  is_cover_border = FALSE;

	Graph_Init( &layer_graph );
	Graph_Init( &self_graph );
	Graph_Init( &content_graph );
	/* 若部件本身是透明的 */
	if( w->style.opacity < 1.0 ) {
		has_self_graph = TRUE;
		has_content_graph = TRUE;
		has_layer_graph = TRUE;
	} else {
		/* 若使用了圆角边框,则判断当前脏矩形区域是否在圆角边框内
		...
		if( ... ) {
			has_content_graph = TRUE;
			is_cover_border = TRUE;
		}
		*/
	}
	/* 如果需要缓存自身的位图 */
	if( has_self_graph ) {
		LCUI_PaintContextRec_ self_paint;
		/* 有位图缓存则直接截取出来,否则绘制一次 */
		if( Graph_IsValid(&w->graph) ) {
			Graph_Quote( &self_graph, &w->graph, &paint->rect );
		} else {
			Graph_Create(
				&self_graph,
				paint->rect.width, paint->rect.height
			);
		}
		self_paint.canvas = self_graph;
		self_paint.rect = paint->rect;
		Widget_OnPaint( w, &self_paint );
	} else {
		/* 直接将部件绘制到目标位图缓存中 */
		if( Graph_IsValid(&w->graph) ) {
			Graph_Quote( &self_graph, &w->graph, &paint->rect );
			Graph_Mix( &paint->canvas, &self_graph, Pos(0,0) );
			Graph_WritePNG( "1,paint_canvas.png", &paint->canvas );
			Graph_WritePNG( "2,self_graph.png", &self_graph );
		} else {
			Widget_OnPaint( w, paint );
		}
	}
	/* 计算内容框相对于图层的坐标 */
	content_left = w->base.box.content.x - w->base.box.graph.x;
	content_top = w->base.box.content.y - w->base.box.graph.y;
	/* 获取内容框 */
	content_rect.x = content_left;
	content_rect.y = content_top;
	content_rect.width = w->base.box.content.width;
	content_rect.height = w->base.box.content.height;
	/* 获取内容框与脏矩形重叠的区域 */
	has_overlay = LCUIRect_GetOverlayRect(
		&content_rect, &paint->rect, &content_rect
	);
	/* 如果没有与内容框重叠,则跳过内容绘制 */
	if( !has_overlay ) {
		goto content_paint_done;
	}
	/* 将换重叠区域的坐标转换为相对于脏矩形的坐标 */
	content_rect.x -= paint->rect.x;
	content_rect.y -= paint->rect.y;
	/* 若需要部件内容区的位图缓存 */
	if( has_content_graph ) {
		content_graph.color_type = COLOR_TYPE_ARGB;
		Graph_Create( &content_graph, content_rect.w, content_rect.h );
	} else {
		/* 引用该区域的位图,作为内容框的位图 */
		Graph_Quote( &content_graph, &paint->canvas, &content_rect );
	}
	i = LinkedList_GetTotal( &w->children_show );
	/* 按照显示顺序,从底到顶,递归遍历子级部件 */
	while( i-- ) {
		LCUI_Widget child;
		LCUI_Rect child_rect;
		LCUI_PaintContextRec_ child_paint;

		child = (LCUI_Widget)LinkedList_Get( &w->children_show );
		if( !child->style.visible ) {
			continue;
		}
		/* 将子部件的区域,由相对于内容框转换为相对于当前脏矩形 */
		child_rect = child->base.box.graph;
		child_rect.x += (content_left - paint->rect.x);
		child_rect.y += (content_top - paint->rect.y);
		/* 获取于内容框重叠的区域,作为子部件的绘制区域 */
		has_overlay = LCUIRect_GetOverlayRect(
			&content_rect, &child_rect, &child_paint.rect
		);
		/* 区域无效则不绘制 */
		if( !has_overlay ) {
			continue;
		}
		/* 将子部件绘制区域转换相对于当前部件内容框 */
		child_rect.x = child_paint.rect.x - content_rect.x;
		child_rect.y = child_paint.rect.y - content_rect.y;
		child_rect.width = child_paint.rect.width;
		child_rect.height = child_paint.rect.height;
		/* 在内容位图中引用所需的区域,作为子部件的画布 */
		Graph_Quote( &child_paint.canvas, &content_graph, &child_rect );
		Widget_Render( child, &child_paint );
	}
	/* 如果与圆角边框重叠,则裁剪掉边框外的内容 */
	if( is_cover_border ) {
		/* content_graph ... */
	}

content_paint_done:

	/* 若需要绘制的是当前部件图层,则先混合部件自身位图和内容位图,得出当
	 * 前部件的图层,然后将该图层混合到输出的位图中
	 */
	if( has_layer_graph ) {
		Graph_Init( &layer_graph );
		layer_graph.color_type = COLOR_TYPE_ARGB;
		Graph_Copy( &layer_graph, &self_graph );
		Graph_Mix(
			&layer_graph, &content_graph,
			Pos(content_rect.x, content_rect.y)
		);
		layer_graph.opacity = w->style.opacity;
		Graph_Mix( &paint->canvas, &layer_graph, Pos(0,0) );
	}
	else if( has_content_graph ) {
		Graph_Mix(
			&paint->canvas, &content_graph,
			Pos(content_rect.x, content_rect.y)
		);
	}
	Graph_WritePNG( "layer_graph.png", &layer_graph );
	Graph_WritePNG( "self_graph.png", &self_graph );
	Graph_WritePNG( "content_graph.png", &content_graph );
	Graph_Free( &layer_graph );
	Graph_Free( &self_graph );
	Graph_Free( &content_graph );
}
예제 #7
0
static void Exec_Update_PictureBox(LCUI_Widget *widget)
/* 功能:更新PictureBox部件 */
{
    LCUI_Pos pos;
    LCUI_PictureBox *pic_box;
    LCUI_Graph graph, *p;
    //printf("Exec_Update_PictureBox(): start\n");
    pos = Pos(0,0);
    Graph_Init(&graph);
    pic_box  = (LCUI_PictureBox*)Get_Widget_PrivData(widget);

    //print_widget_info(widget);
    //Print_Graph_Info(&widget->graph);
    //Print_Graph_Info(pic_box->image);
    //printf("Exec_Update_PictureBox(): 1\n");
    if(! Graph_Valid(pic_box->image)) return;

    //printf("Exec_Update_PictureBox(): widget size: w: %d, h: %d\n", widget->size.w, widget->size.h);
    //printf("Exec_Update_PictureBox(): read box: %d,%d,%d,%d\n",
    //pic_box->read_box.x, pic_box->read_box.y,
    //pic_box->read_box.width, pic_box->read_box.height);
    switch(pic_box->size_mode) {
    case SIZE_MODE_BLOCK_ZOOM:
    case SIZE_MODE_ZOOM:
        /* 裁剪图像 */
        if(pic_box->scale == 1.00) p = pic_box->image;
        else p = &pic_box->buff_graph;
        if(! Graph_Valid(p)) {
            //printf("! Graph_Valid(p)\n");
            return;
        }

        pos.x = (widget->size.w - pic_box->read_box.width)/2.0;
        pos.y = (widget->size.h - pic_box->read_box.height)/2.0;
        /* 引用图像中指定区域的图形 */
        Quote_Graph(&graph, p, pic_box->read_box);
        break;

    case SIZE_MODE_NORMAL:/* 正常模式 */
        Quote_Graph(&graph, pic_box->image, pic_box->read_box);
        break;

    case SIZE_MODE_STRETCH:/* 拉伸模式 */
        /* 开始缩放图片 */
        Graph_Zoom( pic_box->image, &graph, CUSTOM, widget->size );
        break;

    case SIZE_MODE_TILE:/* 平铺模式 */
        Graph_Tile( pic_box->image, &graph, widget->size.w, widget->size.h);
        break;

    case SIZE_MODE_CENTER:
        /* 判断图像的尺寸是否小于图片盒子的尺寸,并计算坐标位置 */
        if(pic_box->image->width < widget->size.w) {
            pic_box->read_box.x = 0;
            pic_box->read_box.width = pic_box->image->width;
            pos.x = (widget->size.w - pic_box->image->width)/2 + 0.5;
        }
        if(pic_box->image->height < widget->size.h) {
            pos.y = (widget->size.h - pic_box->image->height)/2 + 0.5;
            pic_box->read_box.y = 0;
            pic_box->read_box.height = pic_box->image->height;
        }
        if(pic_box->read_box.y + pic_box->read_box.height >= pic_box->image->height)
            /* 如果读取区域的尺寸大于图片尺寸 */
            pic_box->read_box.y = pic_box->image->height - pic_box->read_box.height;
        if(pic_box->read_box.x + pic_box->read_box.width >= pic_box->image->width)
            pic_box->read_box.x = pic_box->image->width - pic_box->read_box.width;

        Quote_Graph(&graph, pic_box->image, pic_box->read_box);
        break;
    default :
        break;
    }
    // 用于调试
    //printf("Exec_Update_PictureBox(): read box: %d,%d,%d,%d; %d/%d, %d/%d\n",
    //pic_box->read_box.x, pic_box->read_box.y,
    //pic_box->read_box.width, pic_box->read_box.height,
    //pic_box->read_box.x + pic_box->read_box.width, pic_box->buff_graph.width,
    //pic_box->read_box.y + pic_box->read_box.height, pic_box->buff_graph.height);
    if(!Graph_Valid(&widget->background_image)) {
        Graph_Replace(&widget->graph, &graph, pos);
    } else {
        Graph_Mix(&widget->graph, &graph, pos);
    }
    Graph_Free(&graph);
    //printf("scale: %.4f\n", pic_box->scale);
    //printf("Exec_Update_PictureBox(): end\n");
    Refresh_Widget(widget);
}
예제 #8
0
파일: picturebox.c 프로젝트: fshunj/LCUI
/* 在PictureBox部件更新时进行附加处理 */
static void 
PictureBox_ExecUpdate(LCUI_Widget *widget)
{
	LCUI_Pos pos;
	LCUI_PictureBox *pic_box;
	LCUI_Graph graph, *widget_graph, *p;
	
	pos = Pos(0,0);
	Graph_Init(&graph);
	pic_box  = (LCUI_PictureBox*)Widget_GetPrivData(widget);
	widget_graph = Widget_GetSelfGraph( widget );
	//print_widget_info(widget);
	//Graph_PrintInfo(widget_graph);
	//Graph_PrintInfo(pic_box->image);
	//printf("PictureBox_ExecUpdate(): 1\n");
	if(! Graph_IsValid(pic_box->image)) {
		return;
	}
	
	//printf("PictureBox_ExecUpdate(): widget size: w: %d, h: %d\n", widget->size.w, widget->size.h);
	//printf("PictureBox_ExecUpdate(): read box: %d,%d,%d,%d\n",
		//pic_box->read_box.x, pic_box->read_box.y, 
		//pic_box->read_box.width, pic_box->read_box.height);
	switch(pic_box->size_mode) {
	case SIZE_MODE_BLOCK_ZOOM:
	case SIZE_MODE_ZOOM:
	/* 裁剪图像 */ 
		if(pic_box->scale == 1.00) p = pic_box->image; 
		else p = &pic_box->buff_graph; 
		if(! Graph_IsValid(p)) {
			//printf("! Graph_IsValid(p)\n");
			return;
		}
		
		pos.x = (widget->size.w - pic_box->read_box.width)/2.0;
		pos.y = (widget->size.h - pic_box->read_box.height)/2.0;
		/* 引用图像中指定区域的图形 */
		Graph_Quote(&graph, p, pic_box->read_box);
		break;
		 
	case SIZE_MODE_NORMAL:/* 正常模式 */
		Graph_Quote(&graph, pic_box->image, pic_box->read_box); 
		break;
		
	case SIZE_MODE_STRETCH:/* 拉伸模式 */ 
		/* 开始缩放图片 */
		Graph_Zoom( pic_box->image, &graph, FALSE, widget->size ); 
		break;
		
	case SIZE_MODE_TILE:/* 平铺模式 */ 
		Graph_Tile( pic_box->image, &graph, TRUE );
		break;
		
	case SIZE_MODE_CENTER:
		/* 判断图像的尺寸是否小于图片盒子的尺寸,并计算坐标位置 */
		if(pic_box->image->w < widget->size.w) {
			pic_box->read_box.x = 0;
			pic_box->read_box.width = pic_box->image->w;
			pos.x = (widget->size.w - pic_box->image->w)/2 + 0.5;
		}
		if(pic_box->image->h < widget->size.h) {
			pos.y = (widget->size.h - pic_box->image->h)/2 + 0.5;
			pic_box->read_box.y = 0;
			pic_box->read_box.height = pic_box->image->h;
		}
		if(pic_box->read_box.y + pic_box->read_box.height >= pic_box->image->h) 
		/* 如果读取区域的尺寸大于图片尺寸 */
			pic_box->read_box.y = pic_box->image->h - pic_box->read_box.height;
		if(pic_box->read_box.x + pic_box->read_box.width >= pic_box->image->w) 
			pic_box->read_box.x = pic_box->image->w - pic_box->read_box.width;
			
		Graph_Quote(&graph, pic_box->image, pic_box->read_box); 
		break;
	default : break;
	}
	// 用于调试
	//printf("PictureBox_ExecUpdate(): read box: %d,%d,%d,%d; %d/%d, %d/%d\n", 
	//pic_box->read_box.x, pic_box->read_box.y, 
	//pic_box->read_box.width, pic_box->read_box.height, 
	//pic_box->read_box.x + pic_box->read_box.width, pic_box->buff_graph.w, 
	//pic_box->read_box.y + pic_box->read_box.height, pic_box->buff_graph.h);
	if(!Graph_IsValid(&widget->background.image)) {
		Graph_Replace( widget_graph, &graph, pos );
	} else {
		Graph_Mix( widget_graph, &graph, pos );
	}
	Graph_Free(&graph);
	//printf("scale: %.4f\n", pic_box->scale);
	//printf("PictureBox_ExecUpdate(): end\n");
	Widget_Refresh(widget); 
}
예제 #9
0
파일: graphlayer.c 프로젝트: aem3372/LCUI
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;
}
예제 #10
0
파일: background.c 프로젝트: bitbegin/LCUI
void Graph_DrawBackground( LCUI_PaintContext paint, const LCUI_Rect *box,
			   LCUI_Background *bg )
{
	float scale;
	LCUI_Graph graph;
	LCUI_BOOL with_alpha;
	LCUI_Rect read_rect, paint_rect;
	int image_x, image_y, image_w, image_h;

	/* 计算背景图应有的尺寸 */
	if( bg->size.using_value ) {
		switch( bg->size.value ) {
		case SV_CONTAIN:
			image_w = box->width;
			scale = 1.0 * bg->image.width / image_w;
			image_h = 1.0 * bg->image.height / scale;
			if( image_h > box->height ) {
				image_h = box->height;
				scale = 1.0 * bg->image.height / box->height;
				image_w = (int)(1.0 * bg->image.width / scale);
			}
			break;
		case SV_COVER:
			image_w = box->width;
			scale = 1.0 * bg->image.width / image_w;
			image_h = 1.0 * bg->image.height / scale;
			if( image_h < box->height ) {
				image_h = box->height;
				scale = 1.0 * bg->image.height / image_h;
				image_w = (int)(1.0 * bg->image.width / scale);
			}
			break;
		case SV_AUTO:
		default:
			image_w = bg->image.width;
			image_h = bg->image.height;
			break;
		}
	} else {
		switch( bg->size.w.type ) {
		case SVT_SCALE:
			image_w = box->w * bg->size.w.scale;
			break;
		case SVT_PX:
			image_w = bg->size.w.px;
			break;
		default:
			image_w = bg->image.width;
			break;
		}
		switch( bg->size.h.type ) {
		case SVT_SCALE:
			image_h = box->h * bg->size.h.scale;
			break;
		case SVT_PX:
			image_h = bg->size.h.px;
			break;
		default:
			image_h = bg->image.height;
			break;
		}
	}
	/* 计算背景图的像素坐标 */
	if( bg->position.using_value ) {
		switch( bg->position.value ) {
		case SV_TOP:
		case SV_TOP_CENTER:
			image_x = (box->w - image_w) / 2;
			image_y = 0;
			break;
		case SV_TOP_RIGHT:
			image_x = box->w - image_w;
			image_y = 0;
			break;
		case SV_CENTER_LEFT:
			image_x = 0;
			image_y = (box->h - image_h) / 2;
			break;
		case SV_CENTER:
		case SV_CENTER_CENTER:
			image_x = (box->w - image_w) / 2;
			image_y = (box->h - image_h) / 2;
			break;
		case SV_CENTER_RIGHT:
			image_x = box->w - image_w;
			image_y = (box->h - image_h) / 2;
			break;
		case SV_BOTTOM_LEFT:
			image_x = 0;
			image_y = box->h - image_h;
			break;
		case SV_BOTTOM_CENTER:
			image_x = (box->w - image_w) / 2;
			image_y = box->h - image_h;
			break;
		case SV_BOTTOM_RIGHT:
			image_x = box->w - image_w;
			image_y = box->h - image_h;
			break;
		case SV_TOP_LEFT:
		default:image_x = image_y = 0; break;
		}
	} else {
		switch( bg->position.x.type ) {
		case SVT_SCALE:
			image_x = box->w - image_w;
			image_x *= bg->position.x.scale;
			break;
		case SVT_PX:
			image_x = bg->position.x.px;
			break;
		default:image_x = 0; break;
		}
		switch( bg->position.y.type ) {
		case SVT_SCALE:
			image_y = box->h - image_h;
			image_y *= bg->position.y.scale;
			break;
		case SVT_PX:
			image_y = bg->position.y.px;
			break;
		default:image_y = 0; break;
		}
	}
	/* 获取当前绘制区域与背景内容框的重叠区域 */
	if( !LCUIRect_GetOverlayRect( box, &paint->rect, &paint_rect ) ) {
		return;
	}
	with_alpha = bg->color.alpha < 255;
	paint_rect.x -= paint->rect.x;
	paint_rect.y -= paint->rect.y;
	Graph_Quote( &graph, &paint->canvas, &paint_rect );
	Graph_FillRect( &graph, bg->color, NULL, TRUE );
	/* 将坐标转换为相对于背景内容框 */
	paint_rect.x += paint->rect.x - box->x;
	paint_rect.y += paint->rect.y - box->y;
	/* 保存背景图像区域 */
	read_rect.x = image_x;
	read_rect.y = image_y;
	read_rect.width = image_w;
	read_rect.height = image_h;
	/* 获取当前绘制区域与背景图像的重叠区域 */
	if( !LCUIRect_GetOverlayRect( &read_rect, &paint_rect, &read_rect ) ) {
		return;
	}
	/* 转换成相对于图像的坐标 */
	read_rect.x -= image_x;
	read_rect.y -= image_y;
	/* 如果尺寸没有变化则直接引用 */
	if( image_w == bg->image.w && image_h == bg->image.h ) {
		Graph_Quote( &graph, &bg->image, &read_rect );
		/* 转换成相对于当前绘制区域的坐标 */
		image_x = image_x + box->x - paint->rect.x;
		image_y = image_y + box->y - paint->rect.y;
		image_x += read_rect.x;
		image_y += read_rect.y;
		Graph_Mix( &paint->canvas, &graph, image_x,
			   image_y, with_alpha );
	} else {
		float scale;
		LCUI_Graph buffer;
		LCUI_Rect quote_rect;

		Graph_Init( &buffer );
		quote_rect = read_rect;
		/* 根据宽高的缩放比例,计算实际需要引用的区域 */
		if( image_w != bg->image.w ) {
			scale = 1.0 * bg->image.width / image_w;
			quote_rect.x *= scale;
			quote_rect.width *= scale;
		}
		if( image_h != bg->image.h ) {
			scale = 1.0 * bg->image.height / image_h;
			quote_rect.y *= scale;
			quote_rect.height *= scale;
		}
		/* 引用源背景图像的一块区域 */
		Graph_Quote( &graph, &bg->image, &quote_rect );
		image_w = read_rect.width;
		image_h = read_rect.height;
		/* 计算相对于绘制区域的坐标 */
		image_x = read_rect.x + image_x;
		image_x = image_x + box->x - paint->rect.x;
		image_y = read_rect.y + image_y;
		image_y = image_y + box->y - paint->rect.y;
		/* 按比例进行缩放 */
		Graph_Zoom( &graph, &buffer, FALSE, image_w, image_h );
		Graph_Mix( &paint->canvas, &buffer, image_x, 
			   image_y, with_alpha );
		Graph_Free( &buffer );
	}
}