Пример #1
0
int Set_PictureBox_InitImage(LCUI_Widget *widget, LCUI_Graph *pic)
/* 功能:设定正在加载另一图像时显示的图像 */
{
    LCUI_PictureBox *pic_box = (LCUI_PictureBox*)Get_Widget_PrivData(widget);

    if(Graph_Valid(pic)) {
        Graph_Copy(&pic_box->initial_image, pic);
        return 0;
    }
    return -1;
}
Пример #2
0
int Set_PictureBox_ErrorImage(LCUI_Widget *widget, LCUI_Graph *pic)
/* 功能:设定当加载图像失败时显示的图像 */
{
    LCUI_PictureBox *pic_box = (LCUI_PictureBox*)
                               Get_Widget_PrivData(widget);

    if(Graph_Valid(pic)) {
        Graph_Copy(&pic_box->error_image, pic);
        return 0;
    }
    return -1;
}
Пример #3
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;
}
Пример #4
0
/* 设定正在加载另一图像时显示的图像 */
LCUI_API int
PictureBox_SetInitImage( LCUI_Widget *widget, LCUI_Graph *pic )
{
	LCUI_PictureBox *pic_box;
	
	pic_box = Widget_GetPrivData(widget);
	
	if(Graph_IsValid(pic)) {
		Graph_Copy(&pic_box->initial_image, pic);
		return 0;
	}
	return -1;
}
Пример #5
0
/**
 * 渲染指定部件呈现的图形内容
 * @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 );
}
Пример #6
0
int GaussianSmooth( LCUI_Graph *src, LCUI_Graph *des, double sigma )
/* 对图像进行高斯模糊处理 */
{
	LCUI_Graph temp;
	
	int32_t kcenter, i;
	uint_t x, y, ksize;
	uint_t temp_pos, temp_start_pos;
	uint_t a_src_pos, b_src_pos, src_start_pos;
	double amul, bmul, gmul, rmul, *kvalue_ptr;
	double *kernel, scale, cons, sum = 0;
	const double PI = 3.141592653;
	
	sigma = sigma > 0 ? sigma : -sigma;
	//ksize为奇数 
	ksize = ceil(sigma * 3) * 2 + 1; 
	if(ksize == 1) {
		Graph_Copy( des, src );
		return 0;
	}

	//计算一维高斯核 
	scale = -0.5/(sigma*sigma);
	cons = 1/sqrt(-scale / PI); 
	kcenter = ksize/2; 
	kernel = (double*) malloc( ksize*sizeof(double) );
	for(i = 0; i < ksize; ++i) {
		int x = i - kcenter;
		*(kernel+i) = cons * exp(x * x * scale);//一维高斯函数
		sum += *(kernel+i);
	} 
	//归一化,确保高斯权值在[0,1]之间
	for(i = 0; i < ksize; i++) {
		*(kernel+i) /= sum;
	}
	
	des->have_alpha = src->have_alpha;
	if( Graph_Create( des, src->width, src->height ) != 0 ) {
		return -1;
	}
	
	Graph_Init( &temp );
	temp.have_alpha = src->have_alpha;
	if( Graph_Create( &temp, src->width, src->height ) != 0 ) {
		return -2;
	}
	
	Graph_Lock( src, RWLOCK_READ );
	Graph_Lock( &temp, RWLOCK_WRITE );
	
	//x方向一维高斯模糊
	temp_start_pos = 0;
	src_start_pos = 0 - kcenter;
	for(y = 0; y < src->height; y++) {
		temp_pos = temp_start_pos;
		b_src_pos = src_start_pos;
		for(x = 0; x < src->width; x++) { 
			sum = amul = bmul = gmul = rmul = 0;
			a_src_pos = b_src_pos;
			kvalue_ptr = kernel;
			for(i = -kcenter; i <= kcenter; i++) {
				if((x+i) >= 0 && (x+i) < src->width) {
					rmul += src->rgba[0][a_src_pos]*(*kvalue_ptr);
					gmul += src->rgba[1][a_src_pos]*(*kvalue_ptr);
					bmul += src->rgba[2][a_src_pos]*(*kvalue_ptr);
					if(src->have_alpha) {
						amul += src->rgba[3][a_src_pos]*(*kvalue_ptr);
					}
					sum += (*kvalue_ptr);
				}
				++a_src_pos;
				++kvalue_ptr;
			}
			temp.rgba[0][temp_pos] = rmul/sum;
			temp.rgba[1][temp_pos] = gmul/sum;
			temp.rgba[2][temp_pos] = bmul/sum;
			if(temp.have_alpha) {
				temp.rgba[3][temp_pos] = amul/sum;
			}
			++temp_pos;
			++b_src_pos;
		}
		temp_start_pos += temp.width;
		src_start_pos += src->width;
	}
	Graph_Unlock( &temp );
	
	Graph_Lock( des, RWLOCK_WRITE );
	Graph_Lock( &temp, RWLOCK_READ );
	//y方向一维高斯模糊
	src_start_pos = 0 - kcenter*temp.width;
	src_start_pos = 0 - kcenter*temp.width;
	for(x = 0; x < temp.width; x++) {
		temp_start_pos = x;
		b_src_pos = src_start_pos;
		for(y = 0; y < temp.height; y++) { 
			sum = amul = bmul = gmul = rmul = 0;
			a_src_pos = b_src_pos;
			kvalue_ptr = kernel;
			for(i = -kcenter; i <= kcenter; i++) {
				if((y+i) >= 0 && (y+i) < temp.height) { 
					rmul += temp.rgba[0][a_src_pos]*(*kvalue_ptr);
					gmul += temp.rgba[1][a_src_pos]*(*kvalue_ptr);
					bmul += temp.rgba[2][a_src_pos]*(*kvalue_ptr);
					if(temp.have_alpha) {
						amul += temp.rgba[3][a_src_pos]*(*kvalue_ptr);
					}
					sum += (*kvalue_ptr);
				}
				a_src_pos += temp.width;
				++kvalue_ptr;
			}
			des->rgba[0][temp_start_pos] = rmul/sum;
			des->rgba[1][temp_start_pos] = gmul/sum;
			des->rgba[2][temp_start_pos] = bmul/sum;
			if(des->have_alpha) {
				des->rgba[3][temp_start_pos] = amul/sum; 
			}
			temp_start_pos += des->width;
			b_src_pos += temp.width;
		}
		++src_start_pos;
	}
	
	Graph_Unlock( &temp );
	Graph_Unlock( des );
	Graph_Unlock( src );
	
	Graph_Free( &temp );
	free(kernel);
	return 0;
}
Пример #7
0
/** 对图像进行高斯模糊处理 */
LCUI_API int GaussianSmooth( LCUI_Graph *src, LCUI_Graph *des, double sigma )
{
	LCUI_Graph temp;
	int kcenter, i;
	int x, y, ksize;
	double *kernel, scale, cons, sum = 0;
	LCUI_ARGB *p_src_px, *p_des_px;
	
	sigma = sigma > 0 ? sigma : -sigma;
	// ksize为奇数 
	ksize = ceil(sigma * 3) * 2 + 1; 
	if(ksize == 1) {
		Graph_Copy( des, src );
		return 0;
	}

	// 计算一维高斯核 
	scale = -0.5/(sigma*sigma);
	cons = 1/sqrt(-scale / PI); 
	kcenter = ksize/2; 
	kernel = (double*)malloc( ksize*sizeof(double) );
	for(i = 0; i < ksize; ++i) {
		int x = i - kcenter;
		*(kernel+i) = cons * exp(x * x * scale); // 一维高斯函数
		sum += *(kernel+i);
	} 
	// 归一化,确保高斯权值在[0,1]之间
	for(i = 0; i < ksize; i++) {
		*(kernel+i) /= sum;
	}
	
	des->color_type = src->color_type;
	if( Graph_Create( des, src->w, src->h ) != 0 ) {
		return -1;
	}
	
	Graph_Init( &temp );
	temp.color_type = src->color_type;
	if( Graph_Create( &temp, src->w, src->h ) != 0 ) {
		return -2;
	}
	
	// x方向一维高斯模糊
	p_des_px = temp.argb;
	p_src_px = src->argb - kcenter;
	for( y=0; y<src->h; ++y ) {
		HorizSmoothARGB( p_src_px, p_des_px, src->w, kernel, kcenter );
		p_des_px += temp.w;
		p_src_px += src->w;
	}

	// y方向一维高斯模糊
	p_des_px = temp.argb;
	p_src_px = src->argb - kcenter*temp.w;
	for( x=0; x<temp.w; ++x ) {
		VertiSmoothARGB( p_src_px, p_des_px, src->h, src->w, kernel, kcenter );
		++p_des_px;
		++p_src_px;
	}
	
	Graph_Free( &temp );
	free(kernel);
	return 0;
}