/* 从当前占用的队列中取出一个矩形区域 */ LCUI_API LCUI_BOOL RectQueue_GetFromCurrent( LCUI_RectQueue *queue, LCUI_Rect *rect_buff ) { LCUI_Rect *rect_ptr; LCUI_Queue *q; if( queue->number == 0 ) { q = &queue->queue[0]; } else { q = &queue->queue[1]; } rect_ptr = (LCUI_Rect*)Queue_Get( q, 0 ); if( rect_ptr == NULL ) { Queue_Delete( q, 0 ); return FALSE; } *rect_buff = *rect_ptr; Queue_Delete( q, 0 ); return TRUE; }
/* 更新文本框的样式以及文本图层相关的数据 */ static void TextBox_ExecUpdate( LCUI_Widget *widget ) { LCUI_TextLayer *layer; LCUI_TextBlock *text_ptr; LCUI_TextBox *textbox; textbox = Widget_GetPrivData( widget ); /* 如果缓冲区内有文本块 */ if( Queue_GetTotal( &textbox->text_block_buff ) > 0 ) { /* 获取文本块 */ text_ptr = Queue_Get( &textbox->text_block_buff, 0 ); if( text_ptr ) { //_DEBUG_MSG("text block: %p, text: %p\n", // text_ptr, text_ptr->text); switch( text_ptr->pos_type ) { case AT_TEXT_LAST: /* 将此文本块追加至文本末尾 */ __TextBox_Text_AppendW( widget, text_ptr->text ); break; case AT_CURSOR_POS: /* 将此文本块插入至光标当前处 */ __TextBox_Text_Add( widget, text_ptr->text ); break; default: break; } } /* 删除该文本块 */ Queue_Delete( &textbox->text_block_buff, 0 ); /* 更新滚动条的位置 */ TextBox_ScrollBar_UpdatePos( widget ); /* 标记下次继续更新 */ __Widget_Update( widget ); } /* 如果文本框内没有文本,且还未显示占位符,则设置占位符并显示 */ if( TextBox_Text_GetTotalLength( widget ) == 0 && !textbox->show_placeholder ) { layer = TextBox_GetTextLayer(widget); /* 备份文本框内的文本样式以及屏蔽符 */ textbox->textstyle_bak = layer->default_data; textbox->password_char_bak = layer->password_char.char_code; /* 占位符不能被屏蔽,所以设置屏蔽符为0 */ TextLayer_Text_SetPasswordChar( layer, 0 ); /* 文本框内显示占位符 */ TextLayer_TextW( layer, textbox->placeholder.string ); /* 设置占位符的样式 */ TextLayer_Text_SetDefaultStyle( layer, textbox->placeholder_style ); textbox->show_placeholder = TRUE; } TextBox_ExecUpdateStyle( widget ); /* 更新文本框的样式 */ Widget_ExecUpdate( TextBox_GetLabel( widget ) ); /* 更新文本图层的内容 */ TextBox_ScrollBar_UpdateSize( widget ); /* 更新滚动条的长度 */ TextBox_Cursor_Update( widget ); /* 更新文本框内的光标 */ }
TextLayer_SetRowEnd( LCUI_TextLayer *layer, uint_t row, uint_t start_cols ) /* 为指定行设定结束点,结束点及后面的数据将被删除,但不记录残余文本位图区域 */ { uint_t total, i; Text_RowData *row_data; row_data = Queue_Get( &layer->rows_data, row ); total = Queue_GetTotal( &row_data->string ); /* 移除多余的数据 */ for(i=start_cols; i<total; ++i) { Queue_Delete( &row_data->string, start_cols ); } }
static void LCUI_DestroyAllApps(void) { LCUI_App *app; int i, total; Queue_Lock( &LCUI_Sys.app_list ); total = Queue_GetTotal(&LCUI_Sys.app_list); for (i = 0; i < total; ++i) { app = Queue_Get(&LCUI_Sys.app_list, 0); if(app == NULL) { continue; } Queue_Delete (&LCUI_Sys.app_list, 0); } Queue_Unlock( &LCUI_Sys.app_list ); Queue_Destroy( &LCUI_Sys.app_list ); }
/** 移除指定部件的记录,使之不再响应状态变化 */ LCUI_API void WidgetRecord_Delete( LCUI_Widget *widget ) { int n; WidgetRecordItem *item; Queue_Lock( &widget_proc_record ); n = Queue_GetTotal( &widget_proc_record ); for(; n>=0; --n) { item = (WidgetRecordItem*) Queue_Get( &widget_proc_record, n ); if( item && item->widget == widget ) { Queue_Delete( &widget_proc_record, n ); break; } } Queue_Unlock( &widget_proc_record ); }
static int TextLayer_Text_DeleteChar( LCUI_TextLayer *layer, LCUI_CharData *char_ptr, int left_or_right ) /* * 功能:将字符数据从源文本中移除 * 参数: * layer 操作对象 * char_ptr 指向所要删除的字符数据的指针 * left_or_right 指定在源文本中遍历的方向,值为0时是向左遍历,其它值则像右遍历 * */ { int n; n = TextLayer_GetCharPos( layer, char_ptr, left_or_right ); /* 将该字从源文本中移除 */ Queue_Delete( &layer->text_source_data, n ); return 0; }
/* 从消息队列中取出一个消息 */ int Game_GetMsg( GameMsg *msg_buff ) { GameMsg *p_msg; Game_RecvMsg(); while( Queue_GetTotal(&game_msg_queue)<=0 ) { LCUISleeper_StartSleep( &msg_sleeper, 1000 ); } Queue_Lock( &game_msg_queue ); p_msg = (GameMsg*)Queue_Get( &game_msg_queue, 0 ); if( p_msg == NULL ) { Queue_Unlock( &game_msg_queue ); return -1; } *msg_buff = *p_msg; Queue_Delete( &game_msg_queue, 0 ); Queue_Unlock( &game_msg_queue ); return 0; }
/** 将指定标签的样式数据从队列中删除,只删除队列尾部第一个匹配的标签 */ static void StyleTag_Delete( LCUI_Queue *tags, StyleTag_ID tag ) { int i, total; StyleTag_Data *p; total = Queue_GetTotal( tags ); DEBUG_MSG("delete start, total tag: %d\n", Queue_GetTotal( tags )); if(total <= 0) { return; } for(i=total-1; i>=0; --i) { p = Queue_Get( tags, i ); if( p->tag == tag ) { Queue_Delete( tags, i ); break; } } DEBUG_MSG("delete end, total tag: %d\n", Queue_GetTotal( tags )); }
int Run_Task( LCUI_App *app ) /* 功能:执行任务 */ { static LCUI_Task *task; task = (LCUI_Task*)Queue_Get( &app->task_queue, 0 ); //clock_t start = clock(); //printf("run task %p\n", task->func); /* 调用函数指针指向的函数,并传递参数 */ task->func( task->arg[0], task->arg[1] ); /* 若需要在调用回调函数后销毁参数 */ if( task->destroy_arg[0] ) { free( task->arg[0] ); } if( task->destroy_arg[1] ) { free( task->arg[1] ); } //printf("task %p use time: %ldus\n", task->func, clock()-start); return Queue_Delete(&app->task_queue, 0); }
/** 清理部件列表中需要移除的部件,并将部件状态设置为NORMAL */ static void WidgetRecord_Clear( void ) { int i, n; WidgetRecordItem *item; Queue_Lock( &widget_proc_record ); n = Queue_GetTotal( &widget_proc_record ); for(i=0; i<n; ++i) { item = (WidgetRecordItem*) Queue_Get( &widget_proc_record, i ); if( !item->need_delete ) { continue; } Widget_SetState( item->widget, WIDGET_STATE_NORMAL ); Queue_Delete( &widget_proc_record, i ); n = Queue_GetTotal( &widget_proc_record ); --i; } Queue_Unlock( &widget_proc_record ); }
static void Exec_TextBox_Update( LCUI_Widget *widget ) /* 更新文本框的文本图层 */ { LCUI_TextBlock *text_ptr; LCUI_TextBox *textbox; textbox = Get_Widget_PrivData( widget ); /* 如果缓冲区内有文本块 */ if( Queue_Get_Total( &textbox->text_block_buff ) > 0 ) { /* 获取文本块 */ text_ptr = Queue_Get( &textbox->text_block_buff, 0 ); if( text_ptr ) { //_DEBUG_MSG("text block: %p, text: %p\n", // text_ptr, text_ptr->text); switch( text_ptr->pos_type ) { case AT_TEXT_LAST: /* 将此文本块追加至文本末尾 */ __TextBox_Text_Append( widget, text_ptr->text ); break; case AT_CURSOR_POS: /* 将此文本块插入至光标当前处 */ __TextBox_Text_Add( widget, text_ptr->text ); break; default: break; } } /* 删除该文本块 */ Queue_Delete( &textbox->text_block_buff, 0 ); /* 更新滚动条的位置 */ TextBox_ScrollBar_Update_Pos( widget ); /* 标记下次继续更新 */ __Update_Widget( widget ); } /* 更新文本图层的内容 */ Exec_Update_Widget( TextBox_Get_Label( widget ) ); /* 更新滚动条的长度 */ TextBox_ScrollBar_Update_Size( widget ); /* 更新文本框内的光标 */ TextBox_Cursor_Update( widget ); }
static void TextLayer_TagStyle_Delete( LCUI_TextLayer *layer, enum_tag_id tag) /* 将指定标签的样式数据从队列中删除,只删除队列尾部第一个匹配的标签 */ { int i, total; tag_style_data *p; total = Queue_Get_Total( &layer->tag_buff ); DEBUG_MSG("delete start, total tag: %d\n", Queue_Get_Total( &layer->tag_buff )); if(total <= 0) { return; } for(i=total-1; i>=0; --i) { p = Queue_Get( &layer->tag_buff, i ); if( p->tag == tag ) { Queue_Delete( &layer->tag_buff, i ); break; } } DEBUG_MSG("delete end, total tag: %d\n", Queue_Get_Total( &layer->tag_buff )); }
LCUI_API void WidgetMsg_Proc( LCUI_Widget *widget ) { int i,n; WidgetMsgData *data_ptr; LCUI_Widget *child; LCUI_Queue *msg_buff, *child_list; if( widget == NULL ) { widget = RootWidget_GetSelf(); } msg_buff = Widget_GetMsgBuff( widget ); child_list = Widget_GetChildList( widget ); Queue_Lock( msg_buff ); n = Queue_GetTotal( msg_buff ); for(i=0; i<n; ++i) { DEBUG_MSG("[%d/%d]get msg\n", i, n); data_ptr = (WidgetMsgData*)Queue_Get( msg_buff, i ); DEBUG_MSG("[%d/%d]dispatch msg\n", i, n); if( WidgetMsg_Dispatch( widget, data_ptr ) ) { DEBUG_MSG("[%d/%d]delete msg\n", i, n); Queue_Delete( msg_buff, i ); n = Queue_GetTotal( msg_buff ); --i; } DEBUG_MSG("[%d/%d]skip msg\n", i, n); } Queue_Unlock( msg_buff ); n = Queue_GetTotal( child_list ); /* 从尾到首,递归处理子部件的更新 */ while(n--) { child = (LCUI_Widget*)Queue_Get( child_list, n ); if( child ) { DEBUG_MSG("proc child msg\n"); WidgetMsg_Proc( child ); } } }
void Set_PictureBox_Image_From_Graph(LCUI_Widget *widget, LCUI_Graph *image) /* 功能:添加一个图片数据至图片盒子 */ { int i; float scale_x,scale_y; LCUI_Graph *graph = image; LCUI_PictureBox *pic_box = (LCUI_PictureBox*) Get_Widget_PrivData(widget); for(i = 0; i < 2; ++i) { /* 如果image有效 */ if(Graph_Valid(graph)) { /* 图片更换了,就释放缓存图形 */ Graph_Free(&pic_box->buff_graph); pic_box->image = graph; /* 读取的范区域为整个图片区域 */ pic_box->read_box.x = 0; pic_box->read_box.y = 0; pic_box->read_box.width = graph->width; pic_box->read_box.height = graph->height; pic_box->read_box.center_x = 0.5; pic_box->read_box.center_y = 0.5; pic_box->scale = 1.0; //printf("Set_PictureBox_Image_From_Graph(): img, w: %d, h: %d\n", graph->width, graph->height); //printf("Set_PictureBox_Image_From_Graph(): pb: w: %d, h: %d\n", widget->size.w, widget->size.h); //printf("Set_PictureBox_Image_From_Graph(): size mode: %d\n", pic_box->size_mode); switch(pic_box->size_mode) { case SIZE_MODE_BLOCK_ZOOM: case SIZE_MODE_ZOOM: //printf("Set_PictureBox_Image_From_Graph(): widget: w: %d, h: %d\n", widget->size.w, widget->size.h); if(widget->size.w <= 0 || widget->size.h <= 0) { //printf("Set_PictureBox_Image_From_Graph(): break\n"); break; } scale_x = (float)widget->size.w / pic_box->image->width; scale_y = (float)widget->size.h / pic_box->image->height; if(scale_x < scale_y) pic_box->scale = scale_x; else pic_box->scale = scale_y; //printf("Set_PictureBox_Image_From_Graph(): scale: %.4f, x: %.4f, y: %.4f\n", //pic_box->scale, scale_x, scale_y); Zoom_PictureBox_View_Area(widget, pic_box->scale); //printf("Set_PictureBox_Image_From_Graph(): 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); break; /* 正常模式 */ case SIZE_MODE_NORMAL: break; /* 拉伸模式 */ case SIZE_MODE_STRETCH: break; /* 平铺模式 */ case SIZE_MODE_TILE: break; case SIZE_MODE_CENTER: /* 判断图像的尺寸是否超出图片盒子的尺寸 */ if(pic_box->image->width >= widget->size.w) { pic_box->read_box.x = (pic_box->image->width - widget->size.w)/2.0; pic_box->read_box.width = widget->size.w; } if(pic_box->image->height >= widget->size.h) { pic_box->read_box.y = (pic_box->image->height - widget->size.h)/2.0; pic_box->read_box.height = widget->size.h; } break; default : break; } break; } else if(pic_box->image_status == IMAGE_STATUS_LOADING) { /* 使用对应的图片 */ if(Graph_Valid(&pic_box->initial_image)) { graph = &pic_box->initial_image; } else { return; } } else { /* 使用对应的图片 */ if(Graph_Valid(&pic_box->error_image)) { graph = &pic_box->error_image; pic_box->image_status = IMAGE_STATUS_FAIL; } else { return; } } } /* 如果记录中有该部件,那判断该部件使用的图像是否为同一个,不一样就释放之前的 */ graph_data *data; i = find_widget_data(widget); if(i >= 0) { data = (graph_data*)Queue_Get(&picbox_graph_mem, i); if(data->image != image) { Queue_Delete(&picbox_graph_mem, i); } } Draw_Widget(widget); }
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; } }
/* 将矩形数据追加至队列 */ static int RectQueue_Add( LCUI_Queue* queue, LCUI_Rect rect ) { int i, flag = 0; LCUI_Rect *rect_ptr, *cur_rect_ptr; LCUI_Queue rect_buff; if( rect.width <= 0 || rect.height <= 0 ) { return -1; } DEBUG_MSG("add new rect: %d,%d,%d,%d, current total: %d\n", rect.x, rect.y, rect.width, rect.height, queue->total_num); Queue_Init( &rect_buff, sizeof(LCUI_Rect), NULL ); for (i=0; i<queue->total_num; ++i) { cur_rect_ptr = (LCUI_Rect*)Queue_Get( queue, i ); if( !cur_rect_ptr ) { break; } DEBUG_MSG("[%d] rect: %d,%d,%d,%d\n", i, cur_rect_ptr->x, cur_rect_ptr->y, cur_rect_ptr->width, cur_rect_ptr->height); /* 如果矩形无效,或者被新增的矩形区域包含,则删除 */ if ( cur_rect_ptr->width <= 0 || cur_rect_ptr->height <= 0 || LCUIRect_IncludeRect( rect, *cur_rect_ptr) ) { Queue_Delete ( queue, i ); continue; } /* 如果与现有的矩形相同,或被现有的矩形包含 */ if( LCUIRect_Equal( rect, *cur_rect_ptr) || LCUIRect_IncludeRect( *cur_rect_ptr, rect ) ) { flag = 1; break; } /* 如果新增的矩形与队列中的矩形不重叠 */ if( !LCUIRect_Overlay(rect, *cur_rect_ptr) ) { continue; } continue; // 暂时不对相交的矩形进行分割 DEBUG_MSG("[%d] rect overlay, start cut\n", i); /* 根据当前区域,分割新区域 */ LCUIRect_Cut( *cur_rect_ptr, rect, &rect_buff ); for( i=0; i<rect_buff.total_num; ++i ) { rect_ptr = (LCUI_Rect*)Queue_Get( &rect_buff, i ); if( !rect_ptr ) { break; } DEBUG_MSG("[%d] add child rect: %d,%d,%d,%d\n", i, rect_ptr->x, rect_ptr->y, rect_ptr->width, rect_ptr->height); RectQueue_Add( queue, *rect_ptr ); } flag = 1; break; } /* 销毁队列 */ Queue_Destroy( &rect_buff ); if ( flag == 0 ) { return Queue_Add( queue, &rect ); } return -1; }
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"); }
static int _TextLayer_Text_Delete ( LCUI_TextLayer *layer, LCUI_Pos start_pos, int len ) /* 以start_pos为起点,删除n个文字 */ { LCUI_BOOL refresh = TRUE; LCUI_CharData *char_ptr; LCUI_Pos tmp_pos, pixel_pos; int left_or_right, rows, cols; Text_RowData *row_ptr, *tmp_row; if( start_pos.x < 0 ) { len += start_pos.x; start_pos.x = 0; } if( start_pos.y < 0 ) { start_pos.y = 0; } if( len <= 0 ) { return -1; } /* 确定起点位置的XY轴坐标 */ pixel_pos = TextLayer_Char_GetPixelPos( layer, start_pos ); rows = Queue_GetTotal( &layer->rows_data ); row_ptr = Queue_Get( &layer->rows_data, start_pos.y ); if( !row_ptr ) { return -1; } cols = Queue_GetTotal( &row_ptr->string ); /* 根据光标所在位置,确定遍历方向 */ if( layer->current_des_pos.y > start_pos.y || (layer->current_des_pos.y == start_pos.y && layer->current_des_pos.x > start_pos.x)) { left_or_right = 0; } else { left_or_right = 1; } /* 如果需删除的字符只在当前行 */ if( start_pos.x + len <= cols ) { /* 标记后面的文字位图需要刷新 */ TextLayer_CharLater_Refresh( layer, start_pos ); } for( ; start_pos.x<=cols && len>0; --len ) { /* 如果到了行尾 */ if( start_pos.x == cols ) { /* 如果当前行是最后一行 */ if( start_pos.y >= rows-1 ) { break; } if( refresh ) { tmp_pos.x = 0; tmp_pos.y=start_pos.y+1; /* 刷新该行后面所有行的字符 */ for( ; tmp_pos.y<rows; ++tmp_pos.y ) { TextLayer_CharLater_Refresh( layer, tmp_pos ); } refresh = FALSE; } /* 将当前行行尾的换行符'\n'从源文本中移除 */ TextLayer_Text_DeleteChar( layer, row_ptr->last_char, left_or_right ); /* 获取指向下一行文本的指针 */ tmp_row = Queue_Get( &layer->rows_data, start_pos.y+1 ); /* 将下一行的文本拼接至当前行行尾 */ Queue_Cat( &row_ptr->string, &tmp_row->string ); /* 将下一行的行尾字符数据转移至当前行 */ row_ptr->last_char = tmp_row->last_char; /* 销毁下一行的文本 */ Queue_Destroy( &tmp_row->string ); Queue_Delete( &layer->rows_data, start_pos.y+1 ); /* 更新当前行的总字符数 */ cols = Queue_GetTotal( &row_ptr->string ); /* 更新总行数 */ rows = Queue_GetTotal( &layer->rows_data ); /* 更新当前行的尺寸 */ TextLayer_Update_RowSize( layer, start_pos.y ); continue; } char_ptr = Queue_Get( &row_ptr->string, start_pos.x ); if( !char_ptr ) { continue; } TextLayer_Clear( layer, pixel_pos, row_ptr->max_size.h, char_ptr ); pixel_pos.x += char_ptr->bitmap->advance.x; /* 将该字从源文本中移除 */ TextLayer_Text_DeleteChar( layer, char_ptr, left_or_right ); /* 该字在这行的字体位图也需要删除 */ cols = Queue_GetTotal( &row_ptr->string ); Queue_DeletePointer( &row_ptr->string, start_pos.x ); cols = Queue_GetTotal( &row_ptr->string ); char_ptr = Queue_Get( &row_ptr->string, start_pos.x ); cols = Queue_GetTotal( &row_ptr->string ); } /* 更新当前行的尺寸 */ TextLayer_Update_RowSize( layer, start_pos.y ); return 0; }
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"); }