void TextLayer_Init( LCUI_TextLayer *layer ) { layer->max_width = 0; layer->max_height = 0; layer->offset_x = 0; layer->offset_y = 0; layer->new_offset_x = 0; layer->new_offset_y = 0; layer->insert_x = 0; layer->insert_y = 0; layer->is_mulitiline_mode = FALSE; layer->is_autowrap_mode = FALSE; layer->is_using_style_tags = FALSE; layer->is_using_buffer = TRUE; layer->text_align = TEXT_ALIGN_LEFT; layer->row_list.max_rows = 0; layer->row_list.rows = 0; layer->row_list.rowdata = NULL; TextStyle_Init( &layer->text_style ); TaskData_Init( &layer->task ); DirtyRectList_Init( &layer->dirty_rect ); Graph_Init( &layer->graph ); TextRowList_InsertNewRow( &layer->row_list, 0 ); layer->graph.color_type = COLOR_TYPE_ARGB; }
/*************************** 基本的处理 *********************************/ void TextLayer_Init( LCUI_TextLayer *layer ) /* 初始化文本图层相关数据 */ { layer->using_code_mode = IS_FALSE; layer->using_style_tags = IS_FALSE; layer->enable_word_wrap = IS_FALSE; layer->enable_multiline = IS_FALSE; layer->have_select = IS_FALSE; layer->start = 0; layer->end = 0; Queue_Init( &layer->color_keyword, sizeof(Special_KeyWord), Destroy_Special_KeyWord ); /* 队列中使用链表储存这些数据 */ Queue_Init( &layer->text_source_data, sizeof(LCUI_CharData), Destroy_CharData ); Queue_Set_DataMode( &layer->text_source_data, QUEUE_DATA_MODE_LINKED_LIST ); Queue_Init( &layer->rows_data, sizeof(Text_RowData), Destroy_Text_RowData ); Queue_Init( &layer->tag_buff, sizeof(tag_style_data), destroy_tag_style_data ); Queue_Init( &layer->style_data, sizeof(LCUI_TextStyle), NULL ); RectQueue_Init( &layer->clear_area ); layer->default_data.pixel_size = 12; layer->current_src_pos = 0; layer->current_des_pos = Pos(0,0); layer->max_text_len = 5000; TextStyle_Init ( &layer->default_data ); //TextLayer_Text_Add_NewRow ( layer );/* 添加新行 */ }
/** 获取当前的样式数据 */ LCUI_API LCUI_TextStyle* StyleTag_GetCurrentStyle( LCUI_Queue *tags ) { PX_PT_t pxpt; StyleTag_Data *tag_data; LCUI_TextStyle *style_data; int i, total, equal = 0, flags[MAX_TAG_NUM]; style_data = malloc (sizeof(LCUI_TextStyle)); TextStyle_Init( style_data ); memset( flags, 0, sizeof(flags) ); total = Queue_GetTotal( tags ); if(total <= 0) { free( style_data ); return NULL; } /* 从样式数据队列中获取字体样式数据 */ for(equal=0,i=total-1; i>=0; --i) { tag_data = Queue_Get( tags, i ); DEBUG_MSG("tag id: %d\n", tag_data->tag); switch( tag_data->tag ) { case TAG_ID_COLOR: if( flags[0] != 0 ) { break; } style_data->_fore_color = TRUE; style_data->fore_color = *((LCUI_RGB*)tag_data->style); DEBUG_MSG("color: %d,%d,%d\n", data->fore_color.red, data->fore_color.green, data->fore_color.blue); flags[0] = 1; ++equal; break; case TAG_ID_SIZE: if( flags[1] != 0 ) { break; } pxpt = *((PX_PT_t*)tag_data->style); style_data->_pixel_size = TRUE; style_data->pixel_size = pxpt.px; flags[1] = 1; ++equal; break; default: break; } if(equal == MAX_TAG_NUM) { break; } } if( equal == 0 ) { free( style_data ); return NULL; } return style_data; }
static LCUI_TextStyle * TextLayer_Get_Current_TextStyle ( LCUI_TextLayer *layer ) /* 获取当前的字体样式数据 */ { int i, total, equal = 0,flags[MAX_TAG_NUM]; LCUI_TextStyle *data; tag_style_data *p; data = (LCUI_TextStyle*) malloc (sizeof(LCUI_TextStyle)); TextStyle_Init( data ); memset( flags, 0, sizeof(flags) ); total = Queue_Get_Total( &layer->tag_buff ); if(total <= 0) { free( data ); return NULL; } /* 从样式数据队列中获取字体样式数据 */ for(equal=0,i=total-1; i>=0; --i) { p = Queue_Get( &layer->tag_buff, i ); DEBUG_MSG("tag id: %d\n", p->tag); switch( p->tag ) { case TAG_ID_COLOR: if( flags[0] == 0 ) { data->_fore_color = TRUE; data->fore_color = *((LCUI_RGB*)p->style); DEBUG_MSG("color: %d,%d,%d\n", data->fore_color.red, data->fore_color.green, data->fore_color.blue); flags[0] = 1; ++equal; } break; case TAG_ID_SIZE: if( flags[1] == 0 ) { PX_PT_t pxpt; pxpt = *((PX_PT_t*)p->style); data->_pixel_size = TRUE; data->pixel_size = pxpt.px; flags[1] = 1; ++equal; } break; default: break; } if(equal == MAX_TAG_NUM) { break; } } if( equal == 0 ) { free( data ); return NULL; } return data; }
/** 获取当前的文本样式 */ LCUI_TextStyle* StyleTagStack_GetTextStyle( LCUI_StyleTagStack *tags ) { LCUI_StyleTagData *tag_data; LCUI_TextStyle *style_data; int i, total, equal = 0, flags[MAX_TAG_NUM]; style_data = (LCUI_TextStyle*)malloc( sizeof(LCUI_TextStyle) ); TextStyle_Init( style_data ); memset( flags, 0, sizeof(flags) ); total = LinkedList_GetTotal( tags ); if(total <= 0) { free( style_data ); return NULL; } /* 根据已经记录的各种样式,生成当前应有的文本样式 */ for(equal=0,i=total-1; i>=0; --i) { LinkedList_Goto( tags, i ); tag_data = (LCUI_StyleTagData*)LinkedList_Get( tags ); DEBUG_MSG("tag id: %d\n", tag_data->tag_id); switch( tag_data->tag_id ) { case TAG_ID_COLOR: if( flags[0] != 0 ) { break; } style_data->_fore_color = TRUE; style_data->fore_color = tag_data->style.color; DEBUG_MSG("color: %d,%d,%d\n", data->fore_color.red, data->fore_color.green, data->fore_color.blue); flags[0] = 1; ++equal; break; case TAG_ID_SIZE: if( flags[1] != 0 ) { break; } style_data->_pixel_size = TRUE; style_data->pixel_size = tag_data->style.size.px; flags[1] = 1; ++equal; break; default: break; } if(equal == MAX_TAG_NUM) { break; } } if( equal == 0 ) { free( style_data ); return NULL; } return style_data; }
void TextLayer_Init( LCUI_TextLayer *layer ) /* 初始化文本图层相关数据 */ { layer->read_only = FALSE; layer->using_code_mode = FALSE; layer->using_style_tags = FALSE; layer->enable_word_wrap = FALSE; layer->enable_multiline = FALSE; layer->need_proc_buff = FALSE; layer->need_scroll_layer = FALSE; layer->have_select = FALSE; layer->start = 0; layer->end = 0; layer->offset_pos = Pos(0,0); layer->old_offset_pos = Pos(0,0); Queue_Init( &layer->color_keyword, sizeof(Special_KeyWord), Destroy_Special_KeyWord ); /* 队列中使用链表储存这些数据 */ Queue_Init( &layer->text_source_data, sizeof(LCUI_CharData), Destroy_CharData ); Queue_Set_DataMode( &layer->text_source_data, QUEUE_DATA_MODE_LINKED_LIST ); Queue_Init( &layer->rows_data, sizeof(Text_RowData), Destroy_Text_RowData ); Queue_Init( &layer->tag_buff, sizeof(tag_style_data), destroy_tag_style_data ); Queue_Init( &layer->style_data, sizeof(LCUI_TextStyle), NULL ); RectQueue_Init( &layer->clear_area ); /* 初始化屏蔽符的数据 */ layer->password_char.display = TRUE; layer->password_char.need_update = FALSE; layer->password_char.data = NULL; layer->password_char.char_code = 0; FontBMP_Init( &layer->password_char.bitmap ); layer->default_data.pixel_size = 12; layer->current_src_pos = 0; layer->current_des_pos = Pos(0,0); layer->max_text_len = 5000; TextStyle_Init ( &layer->default_data ); String_Init( &layer->text_buff ); //TextLayer_Text_Add_NewRow ( layer );/* 添加新行 */ }
int test_string_render( void ) { int ret; LCUI_Graph img; LCUI_Pos pos = {0, 80}; LCUI_Rect area = {0, 0, 320, 240}; LCUI_TextLayer txt = TextLayer_New(); LCUI_TextStyleRec txtstyle; /* 初始化字体处理功能 */ LCUI_InitFontLibrary(); /* 创建一个图像,并使用灰色填充 */ Graph_Init( &img ); Graph_Create( &img, 320, 240 ); Graph_FillRect( &img, RGB( 240, 240, 240 ), NULL, FALSE ); /* 设置文本的字体大小 */ TextStyle_Init( &txtstyle ); txtstyle.pixel_size = 24; txtstyle.has_pixel_size = TRUE; /* 设置文本图层的固定尺寸、文本样式、文本内容、对齐方式 */ TextLayer_SetFixedSize( txt, 320, 240 ); TextLayer_SetTextStyle( txt, &txtstyle ); TextLayer_SetTextAlign( txt, SV_CENTER ); TextLayer_SetTextW( txt, L"这是一段测试文本\nHello, World!", NULL ); TextLayer_Update( txt, NULL ); /* 将文本图层绘制到图像中,然后将图像写入至 png 文件中 */ TextLayer_DrawToGraph( txt, area, pos, &img ); ret = LCUI_WritePNGFile( "test_string_render.png", &img ); Graph_Free( &img ); /* 释放字体处理功能相关资源 */ LCUI_FreeFontLibrary(); return ret; }
/** 新建文本图层 */ LCUI_TextLayer TextLayer_New(void) { LCUI_TextLayer layer; layer = malloc( sizeof( LCUI_TextLayerRec ) ); layer->width = 0; layer->length = 0; layer->offset_x = 0; layer->offset_y = 0; layer->insert_x = 0; layer->insert_y = 0; layer->max_width = 0; layer->max_height = 0; layer->fixed_width = 0; layer->fixed_height = 0; layer->new_offset_x = 0; layer->new_offset_y = 0; layer->rowlist.length = 0; layer->rowlist.rows = NULL; layer->text_align = SV_LEFT; layer->is_using_buffer = FALSE; layer->is_autowrap_mode = FALSE; layer->is_mulitiline_mode = FALSE; layer->is_using_style_tags = FALSE; layer->line_height.scale = 1.428f; layer->line_height.type = SVT_SCALE; TextStyle_Init( &layer->text_style ); LinkedList_Init( &layer->style_cache ); layer->task.typeset_start_row = 0; layer->task.update_typeset = 0; layer->task.update_bitmap = 0; layer->task.redraw_all = 0; Graph_Init( &layer->graph ); LinkedList_Init( &layer->dirty_rect ); layer->graph.color_type = COLOR_TYPE_ARGB; TextRowList_InsertNewRow( &layer->rowlist, 0 ); return layer; }
static void TextBox_Init( LCUI_Widget *widget ) /* 初始化文本框相关数据 */ { LCUI_TextBox *textbox; widget->valid_state = WIDGET_STATE_ACTIVE | WIDGET_STATE_OVERLAY; widget->valid_state |= (WIDGET_STATE_NORMAL | WIDGET_STATE_DISABLE); textbox = WidgetPrivData_New(widget, sizeof(LCUI_TextBox)); textbox->text = Widget_New( "label" ); textbox->cursor = Widget_New( NULL ); textbox->scrollbar[0] = Widget_New( "scrollbar" ); textbox->scrollbar[1] = Widget_New( "scrollbar" ); /* 不可获得焦点 */ textbox->text->focus = FALSE; textbox->cursor->focus = FALSE; textbox->scrollbar[0]->focus = FALSE; textbox->scrollbar[1]->focus = FALSE; textbox->limit_mode = 0; textbox->block_size = 256; textbox->show_placeholder = FALSE; LCUIWString_Init( &textbox->placeholder ); TextStyle_Init( &textbox->placeholder_style ); TextStyle_FontColor( &textbox->placeholder_style, RGB(100,100,100) ); Label_AutoSize( textbox->text, FALSE, 0 ); Widget_SetSize( textbox->text, "100%", "100%" ); /* 添加至相应的容器 */ Widget_Container_Add( textbox->text, textbox->cursor ); Widget_Container_Add( widget, textbox->text ); Widget_Container_Add( widget, textbox->scrollbar[0] ); Widget_Container_Add( widget, textbox->scrollbar[1] ); /* 设置滚动条的尺寸 */ Widget_SetSize( textbox->scrollbar[0], "10px", NULL ); Widget_SetSize( textbox->scrollbar[1], NULL, "10px" ); Widget_SetAlign( textbox->scrollbar[0], ALIGN_TOP_RIGHT, Pos(0,0) ); Widget_SetAlign( textbox->scrollbar[1], ALIGN_BOTTOM_LEFT, Pos(0,0) ); /* 滚动条设为横向 */ ScrollBar_SetDirection( textbox->scrollbar[1], 1 ); /* 将回调函数与滚动条连接 */ ScrollBar_Connect( textbox->scrollbar[0], TextBox_TextLayer_VertScroll, widget ); ScrollBar_Connect( textbox->scrollbar[1], TextBox_HoriScroll_TextLayer, widget ); Widget_Show( textbox->text ); Queue_Init( &textbox->text_block_buff, sizeof(LCUI_TextBlock), destroy_textblock ); TextLayer_UsingStyleTags( Label_GetTextLayer(textbox->text), FALSE ); Widget_SetPadding( widget, Padding(2,2,2,2) ); Widget_SetBackgroundColor( textbox->cursor, RGB(0,0,0) ); Widget_SetBackgroundTransparent( textbox->cursor, FALSE ); Widget_SetBackgroundTransparent( widget, FALSE ); Widget_Resize( textbox->cursor, Size(1, 14) ); /* 设置可点击区域的alpha值要满足的条件 */ Set_Widget_ClickableAlpha( textbox->cursor, 0, 1 ); Set_Widget_ClickableAlpha( textbox->text, 0, 1 ); /* 设定定时器,每1秒闪烁一次 */ if( __timer_id == -1 ) { __timer_id = set_timer( 500, blink_cursor, TRUE ); } Widget_Event_Connect( widget, EVENT_DRAG, TextBox_TextLayer_Click ); /* 关联 FOCUS_OUT 和 FOCUS_IN 事件 */ Widget_Event_Connect( widget, EVENT_FOCUSOUT, _putout_textbox_cursor ); Widget_Event_Connect( widget, EVENT_FOCUSIN, _putin_textbox_cursor ); /* 关联按键输入事件 */ Widget_Event_Connect( widget, EVENT_KEYBOARD, TextBox_Input ); /* 默认不启用多行文本模式 */ TextBox_Multiline( widget, FALSE ); }
/** 初始化window部件相关数据 */ static void Window_OnInit( LCUI_Widget *window ) { LCUI_Window *wnd; LCUI_Graph btn_bg; LCUI_TextStyle style; LCUI_Border border; wnd = Widget_NewPrivateData( window, LCUI_Window ); wnd->theme_color = COLOR_EMERALD; wnd->theme_color.a = 128; wnd->titlebar = Widget_New(NULL); wnd->client_area = Widget_New(NULL); wnd->btn_close = Widget_New(WIDGET_CLOSE_BUTTON); wnd->icon = Widget_New(NULL); wnd->text = Label_New(); wnd->titlebar->focus = FALSE; wnd->icon->focus = FALSE; wnd->text->focus = FALSE; Widget_SetFocus( wnd->client_area ); Widget_SetClickable( wnd->icon, FALSE ); Widget_SetClickable( wnd->text, FALSE ); Widget_SetClickable( wnd->titlebar, FALSE ); Widget_SetClickable( wnd->client_area, FALSE ); Graph_Init( &btn_bg ); /* 载入按钮背景 */ LoadCloseButtonIMG( &btn_bg ); /* close按钮显示在左上角 */ Widget_SetAlign( wnd->btn_close, ALIGN_TOP_RIGHT, Pos(0,0) ); Widget_Resize( wnd->btn_close, Size(30, 30) ); Widget_SetBackgroundImage( wnd->btn_close, &btn_bg ); Widget_SetBackgroundLayout( wnd->btn_close, LAYOUT_CENTER ); Widget_SetBackgroundTransparent( wnd->icon, TRUE ); Widget_SetBackgroundTransparent( wnd->titlebar, TRUE ); Widget_SetBackgroundTransparent( wnd->client_area, FALSE ); Widget_SetBackgroundTransparent( window, FALSE ); Widget_SetBackgroundColor( window, RGB(255,255,255) ); Widget_SetBackgroundLayout( wnd->icon, LAYOUT_ZOOM ); Widget_SetDock( wnd->titlebar, DOCK_TYPE_TOP ); Widget_SetDock( wnd->client_area, DOCK_TYPE_BOTTOM ); Widget_SetPadding( window, Padding(TOP_PANDDING,1,1,1) ); Widget_SetPadding( wnd->client_area, Padding(1,1,1,1) ); Widget_SetSize( wnd->titlebar, "100%", "35px" ); Border_Init( &border ); border.top_width = 0; border.bottom_width = 1; border.left_width = 1; border.right_width = 1; border.bottom_color = RGB(200,200,200); border.left_color = RGB(255,255,255); border.right_color = RGB(255,255,255); Widget_SetBorder( wnd->titlebar, border ); TextStyle_Init( &style ); TextStyle_FontSize( &style, 18 ); Label_SetTextStyle( wnd->text, style ); /* 放入至容器 */ Widget_Container_Add( wnd->titlebar, wnd->icon ); Widget_Container_Add( wnd->titlebar, wnd->text ); Widget_Container_Add( wnd->titlebar, wnd->btn_close ); Widget_Container_Add( window, wnd->titlebar ); Widget_Container_Add( window, wnd->client_area ); Widget_Resize( window, Size(100, 50) ); Widget_Resize( wnd->icon, Size(24,24) ); Widget_SetAlign( window, ALIGN_MIDDLE_CENTER, Pos(0,0) ); Widget_SetAlign( wnd->icon, ALIGN_MIDDLE_LEFT, Pos(6,0) ); Widget_SetAlign( wnd->text, ALIGN_MIDDLE_LEFT, Pos(6,0) ); /* 关联拖动事件,让鼠标能够拖动标题栏并使窗口移动 */ Widget_ConnectEvent( window, EVENT_DRAG, Window_ExecMove ); /* * 由于需要在窗口获得/失去焦点时进行相关处理,因此需要将回调函数 与部件 * 的FOCUS_IN和FOCUS_OUT事件 进行关联 * */ Widget_ConnectEvent( window, EVENT_FOCUSOUT, Window_OnFocusOut ); Widget_ConnectEvent( window, EVENT_FOCUSIN, Window_OnFocusIn ); Widget_Show( wnd->btn_close ); Widget_Show( wnd->icon ); Widget_Show( wnd->text ); Widget_Show( wnd->titlebar ); Widget_Show( wnd->client_area ); }