/** * 为图像创建一个引用 * @param self 用于存放图像引用的缓存区 * @param source 引用的源图像 * ¶m rect 引用的区域,若为NULL,则引用整个图像 */ int Graph_Quote( LCUI_Graph *self, LCUI_Graph *source, const LCUI_Rect *rect ) { LCUI_Size box_size; LCUI_Rect quote_rect; if( rect == NULL ) { quote_rect.x = 0; quote_rect.y = 0; quote_rect.width = source->width; quote_rect.height = source->height; } else { quote_rect = *rect; } box_size.w = source->width; box_size.h = source->height; LCUIRect_ValidateArea( "e_rect, box_size ); /* 如果引用源本身已经引用了另一个源 */ if( source->quote.is_valid ) { quote_rect.x += source->quote.left; quote_rect.y += source->quote.top; source = source->quote.source; } if( quote_rect.w <= 0 || quote_rect.h <= 0 ) { self->width = 0; self->height = 0; self->opacity = 1.0; self->quote.left = 0; self->quote.top = 0; self->bytes = NULL; self->quote.source = NULL; self->quote.is_valid = FALSE; return -2; } self->width = quote_rect.width; self->height = quote_rect.height; self->opacity = 1.0; self->bytes = NULL; self->mem_size = 0; self->color_type = source->color_type; self->bytes_per_pixel = source->bytes_per_pixel; self->bytes_per_row = source->bytes_per_row; self->quote.is_valid = TRUE; self->quote.source = source; self->quote.left = quote_rect.x; self->quote.top = quote_rect.y; return 0; }
int Graph_Cut( const LCUI_Graph *graph, LCUI_Rect rect, LCUI_Graph *buff ) { if( !Graph_IsValid( graph ) ) { return -2; } LCUIRect_ValidateArea( &rect, Size(graph->w, graph->h) ); if( rect.width <= 0 || rect.height <= 0) { return -3; } switch( graph->color_type ) { case COLOR_TYPE_ARGB8888: return Graph_CutARGB( graph, rect, buff ); case COLOR_TYPE_RGB888: return Graph_CutRGB( graph, rect, buff ); default:break; } return -4; }
/** * 根据所处框区域,调整矩形 * @param[in] w 目标部件 * @param[in,out] r 矩形区域 * @param[in] box_type 区域相对于何种框进行定位 */ static void Widget_AdjustArea( LCUI_Widget w, LCUI_Rect *in_rect, LCUI_Rect *out_rect, int box_type ) { LCUI_Rect *box; switch( box_type ) { case BORDER_BOX: box = &w->base.box.border; break; case GRAPH_BOX: box = &w->base.box.graph; break; case CONTENT_BOX: default: box = &w->base.box.content; break; } /* 如果为NULL,则视为使用整个部件区域 */ if( !in_rect ) { out_rect->x = out_rect->y = 0; out_rect->w = box->w; out_rect->h = box->h; } else { *out_rect = *in_rect; } LCUIRect_ValidateArea( out_rect, Size(box->w, box->h) ); /* 将坐标转换成相对于图像呈现区的坐标 */ out_rect->x += (box->x - w->base.box.graph.x); out_rect->y += (box->y - w->base.box.graph.y); }
/** * 将文本图层中的指定区域的内容绘制至目标图像中 * @param layer 要使用的文本图层 * @param area 文本图层中需要绘制的区域 * @param layer_pos 文本图层在目标图像中的位置 * @param need_replace 绘制时是否需要覆盖像素 * @param graph 目标图像 */ int TextLayer_DrawToGraph( LCUI_TextLayer *layer, LCUI_Rect area, LCUI_Pos layer_pos, LCUI_Graph *graph ) { int x, y, row, col; LCUI_Pos char_pos; TextRowData *p_row; TextCharData *p_char; LCUI_Size box_size; box_size.w = layer->max_width; box_size.h = layer->max_height; /* 调整区域范围,使之有效 */ LCUIRect_ValidateArea( &area, box_size ); /* 加上Y轴坐标偏移量 */ y = layer->offset_y; /* 先确定从哪一行开始绘制 */ for( row=0; row<layer->row_list.rows; ++row ) { p_row = TextRowList_GetRow( &layer->row_list, row ); y += p_row->top_spacing; y += p_row->max_height; if( y > area.y ) { y -= p_row->top_spacing; y -= p_row->max_height; break; } y += p_row->bottom_spacing; } /* 如果没有可绘制的文本行 */ if( row >= layer->row_list.rows ) { return -1; } for( ; row < layer->row_list.rows; ++row ) { p_row = TextRowList_GetRow( &layer->row_list, row ); /* 根据对齐方式,计算该行的位置 */ switch( layer->text_align ) { case TEXT_ALIGN_CENTER: x = (layer->max_width - p_row->max_width)/2; break; case TEXT_ALIGN_RIGHT: x = layer->max_width - p_row->max_width; break; case TEXT_ALIGN_LEFT: default: x = 0; break; } y += p_row->top_spacing; x += layer_pos.x; x += layer->offset_x; /* 确定从哪个文字开始绘制 */ for( col=0; col<p_row->string_len; ++col ) { p_char = p_row->string[col]; /* 忽略无字体位图的文字 */ if( !p_char->bitmap ) { continue; } x += p_char->bitmap->advance.x; if( x > area.x ) { x -= p_char->bitmap->advance.x; break; } } /* 若一整行的文本都不在可绘制区域内 */ if( col >= p_row->string_len ) { y += p_row->max_height; y += p_row->bottom_spacing; continue; } /* 遍历该行的文字 */ for( ; col<p_row->string_len; ++col ) { p_char = p_row->string[col]; if( !p_char->bitmap ) { continue; } /* 计算字体位图的绘制坐标 */ char_pos.x = x + p_char->bitmap->left; char_pos.y = y + p_row->max_height*4/5; char_pos.y -= p_char->bitmap->top; x += p_char->bitmap->advance.x; /* 判断文字使用的前景颜色,再进行绘制 */ if( p_char->style && p_char->style->_fore_color ) { FontBMP_Mix( graph, char_pos, p_char->bitmap, p_char->style->fore_color ); } else { FontBMP_Mix( graph, char_pos, p_char->bitmap, layer->text_style.fore_color ); } /* 如果超过绘制区域则不继续绘制该行文本 */ if( x > area.x + area.width ) { break; } } y += p_row->max_height; y += p_row->bottom_spacing; /* 超出绘制区域范围就不绘制了 */ if( y > area.y + area.height ) { break; } } return 0; }
int TextLayer_DrawToGraph( LCUI_TextLayer layer, LCUI_Rect area, LCUI_Pos layer_pos, LCUI_Graph *graph ) { TextRow txtrow; TextChar txtchar; LCUI_Pos char_pos; int x, y, row, col, width, height; y = layer->offset_y; if( layer->fixed_width > 0 ) { width = layer->fixed_width; } else { width = layer->width; } if( layer->fixed_width > 0 ) { height = layer->fixed_width; } else { height = TextLayer_GetHeight( layer ); } LCUIRect_ValidateArea( &area, width, height ); for( row = 0; row < layer->rowlist.length; ++row ) { txtrow = TextLayer_GetRow( layer, row ); y += txtrow->height; if( y > area.y ) { y -= txtrow->height; break; } } /* 如果没有可绘制的文本行 */ if( row >= layer->rowlist.length ) { return -1; } for( ; row < layer->rowlist.length; ++row ) { txtrow = TextLayer_GetRow( layer, row ); x = TextLayer_GetRowStartX( layer, txtrow ); x += layer->offset_x; /* 确定从哪个文字开始绘制 */ for( col = 0; col < txtrow->length; ++col ) { txtchar = txtrow->string[col]; /* 忽略无字体位图的文字 */ if( !txtchar->bitmap ) { continue; } x += txtchar->bitmap->advance.x; if( x > area.x ) { x -= txtchar->bitmap->advance.x; break; } } /* 若一整行的文本都不在可绘制区域内 */ if( col >= txtrow->length ) { y += txtrow->height; continue; } /* 遍历该行的文字 */ for( ; col < txtrow->length; ++col ) { txtchar = txtrow->string[col]; if( !txtchar->bitmap ) { continue; } /* 计算字体位图的绘制坐标 */ char_pos.x = layer_pos.x + x; char_pos.y = layer_pos.y + y; char_pos.x += txtchar->bitmap->left; char_pos.y += txtrow->text_height * 4 / 5; char_pos.y += (txtrow->height - txtrow->text_height) / 2; char_pos.y -= txtchar->bitmap->top; x += txtchar->bitmap->advance.x; /* 判断文字使用的前景颜色,再进行绘制 */ if( txtchar->style && txtchar->style->has_fore_color ) { FontBitmap_Mix( graph, char_pos, txtchar->bitmap, txtchar->style->fore_color ); } else { FontBitmap_Mix( graph, char_pos, txtchar->bitmap, layer->text_style.fore_color ); } /* 如果超过绘制区域则不继续绘制该行文本 */ if( x > area.x + area.width ) { break; } } y += txtrow->height; /* 超出绘制区域范围就不绘制了 */ if( y > area.y + area.height ) { break; } } return 0; }