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; }
LCUI_API void Graph_Copy( LCUI_Graph *des, LCUI_Graph *src ) { if( !des || !Graph_IsValid(src) ) { return; } des->color_type = src->color_type; /* 创建合适尺寸的Graph */ Graph_Create( des, src->w, src->h ); Graph_Replace( des, src, Pos(0,0) ); des->alpha = src->alpha; }
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; }
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; }
void Graph_Copy( LCUI_Graph *des, const LCUI_Graph *src ) { const LCUI_Graph *graph; if( !des || !Graph_IsValid(src) ) { return; } graph = Graph_GetQuote( src ); des->color_type = graph->color_type; /* 创建合适尺寸的Graph */ Graph_Create( des, src->w, src->h ); Graph_Replace( des, src, Pos(0,0) ); des->opacity = src->opacity; }
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; }
/* 将动画当前帧的图像写入至槽中 */ static int Frames_UpdateGraphSlot( LCUI_Frames *frames, int num ) { LCUI_Pos pos; LCUI_Frame *frame; frame = Queue_Get( &frames->pic, num ); if( !frame ) { return -1; } if(!Graph_IsValid(&frames->slot)){ return -2; } Graph_FillAlpha(&frames->slot, 0); if(0 < Queue_GetTotal(&frames->pic)) { pos = Frames_GetFrameMixPos(frames, frame); Graph_Replace(&frames->slot, frame->pic, pos); } return 0; }
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; }
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); }
/* 在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); }