/** * 将文本图层中的指定区域的内容绘制至目标图像中 * @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; }
TextLayer_Draw( LCUI_Widget *widget, LCUI_TextLayer *layer, int mode ) /* 将文本图层绘制到目标部件的图层上 */ { LCUI_Rect area; LCUI_Pos pos, mix_pos; LCUI_BOOL draw_all = FALSE, redraw_row; int i, j, n, rows, size; LCUI_RGB color; LCUI_Graph slot, *graph; LCUI_CharData *p_data; Text_RowData *p_row; //clock_t start; //start = clock(); //_DEBUG_MSG("enter\n"); graph = Widget_GetSelfGraph( widget ); /* 如果文本缓存区内有数据 */ if( layer->need_proc_buff ) { __TextLayer_Text( layer ); layer->need_proc_buff = FALSE; } /* 如果需要滚动图层 */ if( layer->need_scroll_layer ) { layer->need_scroll_layer = FALSE; //_DEBUG_MSG("layer->need_scroll_layer\n"); /* 根据之前记录的偏移坐标,刷新文本图层 */ __TextLayer_OldArea_Erase( layer, Widget_GetSelfGraph( widget ) ); draw_all = TRUE; } //_DEBUG_MSG("1, use time: %ld\n", clock() - start ); //start = clock(); Graph_Init( &slot ); /* 先处理需要清空的区域 */ n = Queue_GetTotal( &layer->clear_area ); for(i=0; i<n; ++i) { RectQueue_Get( &area, 0 , &layer->clear_area ); area.x += layer->offset_pos.x; area.y += layer->offset_pos.y; Queue_Delete( &layer->clear_area, 0 ); Graph_Quote( &slot, graph, area ); /* 将该区域的alpha通道填充为0 */ Graph_FillAlpha( &slot, 0 ); Widget_InvalidArea( widget, area ); //printf("refresh area: %d,%d,%d,%d\n", //area.x, area.y, area.width, area.height); } //_DEBUG_MSG("2, use time: %ld\n", clock() - start ); //start = clock(); /* 开始绘制文本位图至目标图层上 */ rows = Queue_GetTotal( &layer->rows_data ); for(pos.y=layer->offset_pos.y,i=0; i<rows; ++i) { redraw_row = FALSE; p_row = Queue_Get( &layer->rows_data, i ); if( !p_row ) { continue; } n = Queue_GetTotal( &p_row->string ); /* 如果当前字的位图的Y轴跨距不在有效绘制区域内 */ if( pos.y + p_row->max_size.h <= 0 ) { pos.y += p_row->max_size.h; continue; } for(pos.x=layer->offset_pos.x,j=0; j<n; ++j) { /* 如果设置了屏蔽符 */ p_data = Queue_Get( &p_row->string, j ); if( !p_data ) { continue; } if( layer->password_char.char_code > 0 ) { layer->password_char.need_update = p_data->need_update; p_data = &layer->password_char; } /* 如果当前字的位图的X轴跨距不在有效绘制区域内 */ if( pos.x + p_data->bitmap->advance.x <= 0) { pos.x += p_data->bitmap->advance.x; continue; } /* 获取该字体位图的大致尺寸 */ if( p_data->data ) { size = p_data->data->pixel_size; size += 2; color = p_data->data->fore_color; } else { size = layer->default_data.pixel_size + 2; color = layer->default_data.fore_color; } /* 如果字体位图已标记更新,则绘制它 */ if( p_data->need_update || draw_all ) { p_data->need_update = FALSE; if( !redraw_row ) { area.x = pos.x; area.height = p_row->max_size.h; redraw_row = TRUE; } mix_pos.x = pos.x + p_data->bitmap->left; mix_pos.y = pos.y + p_row->max_size.h-1; mix_pos.y -= p_data->bitmap->top; /* 贴上字体位图 */ FontBMP_Mix( graph, mix_pos, p_data->bitmap, color, mode ); } pos.x += p_data->bitmap->advance.x; if( pos.x > widget->size.w ) { break; } } if(redraw_row) { area.y = pos.y; area.width = pos.x - area.x; //_DEBUG_MSG("area:%d,%d,%d,%d\n", //area.x, area.y, area.width, area.height); Widget_InvalidArea( widget, area ); } pos.y += p_row->max_size.h; if( pos.y > widget->size.h ) { break; } } //_DEBUG_MSG("3, use time: %ld\n", clock() - start ); //_DEBUG_MSG("quit\n"); }
void TextLayer_Draw( LCUI_Widget *widget, LCUI_TextLayer *layer, int mode ) /* 绘制文本图层 */ { LCUI_Rect area; LCUI_Pos pos; int i, j, n, rows, size; LCUI_RGB color; LCUI_Graph slot; LCUI_CharData *p_data; Text_RowData *p_row; Graph_Init( &slot ); n = Queue_Get_Total( &layer->clear_area ); for(i=0; i<n; ++i) { RectQueue_Get( &area, 0 , &layer->clear_area ); Queue_Delete( &layer->clear_area, 0 ); Quote_Graph( &slot, &widget->graph, area ); /* 将该区域的alpha通道填充为0 */ Graph_Fill_Alpha( &slot, 0 ); Add_Widget_Refresh_Area( widget, area ); } /* 开始粘贴文本位图 */ rows = Queue_Get_Total( &layer->rows_data ); for(pos.y=0,i=0; i<rows; ++i) { p_row = Queue_Get( &layer->rows_data, i ); n = Queue_Get_Total( &p_row->string ); pos.x = 0; // //if( p_row->pos.y != pos.y ) { // RectQueue_Add( &layer->clear_area, Rect(pos.x, pos.y, // p_row->max_size.w, p_row->max_size.h) ); // p_row->pos.y = pos.y; //} for(j=0; j<n; ++j) { p_data = Queue_Get( &p_row->string, j ); if( p_data->data != NULL ) { //if( p_data->data->pixel_size > 0 ) { size = p_data->data->pixel_size; //} else { // size = layer->default_data.pixel_size; //} size += 2; //if( p_data->data->_fore_color ) { color = p_data->data->fore_color; //} else { // color = layer->default_data.fore_color; //} } else { size = layer->default_data.pixel_size + 2; color = layer->default_data.fore_color; } pos.x += p_data->bitmap.left; if( p_data->need_update ) { p_data->need_update = FALSE; area = Rect(pos.x, pos.y, size, size); /* 贴上字体位图 */ FontBMP_Mix( &widget->graph, Pos( pos.x, pos.y + p_row->max_size.h-1 - p_data->bitmap.top), &p_data->bitmap, color, mode ); Add_Widget_Refresh_Area( widget, area ); } pos.x += p_data->bitmap.width; } pos.y += p_row->max_size.h; } }
void TextLayer_Draw( LCUI_Widget *widget, LCUI_TextLayer *layer, int mode ) /* 将文本图层绘制到目标部件的图层上 */ { LCUI_Rect area; LCUI_Pos pos; BOOL draw_all = FALSE; int i, j, n, rows, size; LCUI_RGB color; LCUI_Graph slot; LCUI_CharData *p_data; Text_RowData *p_row; //clock_t start; //start = clock(); //printf("TextLayer_Draw(): enter\n"); /* 如果文本缓存区内有数据 */ if( layer->need_proc_buff ) { __TextLayer_Text( layer ); layer->need_proc_buff = FALSE; } /* 如果需要滚动图层 */ if( layer->need_scroll_layer ) { /* 根据之前记录的偏移坐标,刷新文本图层 */ __TextLayer_OldArea_Erase( widget, layer ); draw_all = TRUE; layer->need_scroll_layer = FALSE; } //nobuff_printf("1, use time: %ld\n", clock() - start ); //start = clock(); Graph_Init( &slot ); /* 先处理需要清空的区域 */ n = Queue_Get_Total( &layer->clear_area ); for(i=0; i<n; ++i) { RectQueue_Get( &area, 0 , &layer->clear_area ); area.x += layer->offset_pos.x; area.y += layer->offset_pos.y; Queue_Delete( &layer->clear_area, 0 ); Quote_Graph( &slot, &widget->graph, area ); /* 将该区域的alpha通道填充为0 */ Graph_Fill_Alpha( &slot, 0 ); Add_Widget_Refresh_Area( widget, area ); //printf("refresh area: %d,%d,%d,%d\n", //area.x, area.y, area.width, area.height); } //nobuff_printf("2, use time: %ld\n", clock() - start ); //start = clock(); /* 开始绘制文本位图至目标图层上 */ rows = Queue_Get_Total( &layer->rows_data ); for(pos.y=layer->offset_pos.y,i=0; i<rows; ++i) { p_row = Queue_Get( &layer->rows_data, i ); if( !p_row ) { continue; } n = Queue_Get_Total( &p_row->string ); /* 如果当前字的位图的Y轴跨距不在有效绘制区域内 */ if( pos.y + p_row->max_size.h <= 0 ) { pos.y += p_row->max_size.h; continue; } for(pos.x=layer->offset_pos.x,j=0; j<n; ++j) { /* 如果设置了屏蔽符 */ p_data = Queue_Get( &p_row->string, j ); if( !p_data ) { continue; } if( layer->password_char.char_code > 0 ) { layer->password_char.need_update = p_data->need_update; p_data = &layer->password_char; } /* 如果当前字的位图的X轴跨距不在有效绘制区域内 */ if( pos.x + p_data->bitmap.advance.x <= 0) { pos.x += p_data->bitmap.advance.x; continue; } /* 获取该字体位图的大致尺寸 */ if( p_data->data ) { size = p_data->data->pixel_size; size += 2; color = p_data->data->fore_color; } else { size = layer->default_data.pixel_size + 2; color = layer->default_data.fore_color; } /* 如果字体位图已标记更新,则绘制它 */ if( p_data->need_update || draw_all ) { //nobuff_printf("get, pos: %d, char_ptr: %p, char: %c, draw\n", // i, p_data, p_data->char_code ); p_data->need_update = FALSE; /* 计算区域范围 */ area.x = pos.x + p_data->bitmap.left; area.y = pos.y + p_row->max_size.h-1; area.y -= p_data->bitmap.top; area.height = p_data->bitmap.rows; area.width = p_data->bitmap.width; /* 贴上字体位图 */ FontBMP_Mix( &widget->graph, Pos(area.x, area.y), &p_data->bitmap, color, mode ); /* 记录该区域,以刷新显示到屏幕上 */ Add_Widget_Refresh_Area( widget, area ); } pos.x += p_data->bitmap.advance.x; if( pos.x > widget->size.w ) { break; } } pos.y += p_row->max_size.h; if( pos.y > widget->size.h ) { break; } } //nobuff_printf("3, use time: %ld\n", clock() - start ); //printf("TextLayer_Draw(): quit\n"); }