/** 对指定行的文本进行排版 */ static void TextLayer_TextRowTypeset( LCUI_TextLayer* layer, int row ) { int col, row_width; TextRowData *p_row, *p_next_row; TextCharData *p_char; p_row = layer->row_list.rowdata[row]; row_width = 0; for( col=0; col<p_row->string_len; ++col ) { p_char = p_row->string[col]; if( !p_char->bitmap ) { continue; } /* 累加行宽度 */ row_width += p_char->bitmap->advance.x; /* 如果是当前行的第一个字符,或者行宽度没有超过宽度限制 */ if( layer->max_width <= 0 || !layer->is_autowrap_mode || (layer->is_autowrap_mode && !layer->is_mulitiline_mode) || col < 1 || p_row->max_width <= layer->max_width ) { continue; } TextLayer_BreakTextRow( layer, row, col, EOL_NONE ); return; } TextRow_UpdateSize( p_row, layer->text_style.pixel_size ); /* 如果本行有换行符,或者是最后一行 */ if( p_row->eol != EOL_NONE || row == layer->row_list.rows-1 ) { return; } row_width = p_row->max_width; /* 本行的文本宽度未达到限制宽度,需要将下行的文本转移至本行 */ while( p_row->eol != EOL_NONE ) { /* 获取下一行的指针 */ p_next_row = TextRowList_GetRow( &layer->row_list, row+1 ); if( !p_next_row ) { return; } for( col=0; col<p_next_row->string_len; ++col ) { p_char = p_next_row->string[col]; /* 忽略无字体位图的文字 */ if( !p_char->bitmap ) { TextRow_Insert( p_row, p_row->string_len, p_char ); p_next_row->string[col] = NULL; continue; } row_width += p_char->bitmap->advance.x; /* 如果没有超过宽度限制 */ if( !layer->is_autowrap_mode || layer->max_width <= 0 || (layer->is_autowrap_mode && !layer->is_mulitiline_mode) || p_row->max_width <= layer->max_width ) { TextRow_Insert( p_row, p_row->string_len, p_char ); p_next_row->string[col] = NULL; continue; } /* 如果插入点在下一行 */ if( layer->insert_y == row+1 ) { /* 如果插入点处于被转移的几个文字中 */ if( layer->insert_x < col ) { layer->insert_y = row; layer->insert_x += p_row->string_len; } else { /* 否则,减去被转移的文字数 */ layer->insert_x -= col; } } /* 将这一行剩余的文字向前移 */ TextRow_LeftMove( p_next_row, col ); TextRow_UpdateSize( p_row, layer->text_style.pixel_size ); return; } TextRow_UpdateSize( p_row, layer->text_style.pixel_size ); TextLayer_InvalidateRowRect( layer, row ); TextLayer_InvalidateRowRect( layer, row+1 ); _DEBUG_MSG("remove row %d\n", row+1); /* 删除这一行,因为这一行的内容已经转移至当前行 */ TextRowList_RemoveRow( &layer->row_list, row+1 ); /* 如果插入点当前行在后面 */ if( layer->insert_y > row ) { --layer->insert_y; } } }
/** 删除指定行列的文字及其右边的文本 */ static int TextLayer_TextDeleteEx( LCUI_TextLayer layer, int char_y, int char_x, int n_char ) { int end_x, end_y, i, j, len; TextRow txtrow, end_txtrow, prev_txtrow; if( char_x < 0 ) { char_x = 0; } if( char_y < 0 ) { char_y = 0; } if( n_char <= 0 ) { return -1; } if( char_y >= layer->rowlist.length ) { return -2; } txtrow = layer->rowlist.rows[char_y]; if( char_x > txtrow->length ) { char_x = txtrow->length; } i = n_char; end_x = char_x; end_y = char_y; /* 计算结束点的位置 */ for( ; end_y < layer->rowlist.length && n_char > 0; ++end_y ) { txtrow = layer->rowlist.rows[end_y]; if( end_x + n_char <= txtrow->length ) { end_x += n_char; n_char = 0; break; } n_char -= (txtrow->length - end_x); if( txtrow->eol == EOL_NONE ) { end_x = 0; } else { n_char -= 1; end_x = 0; } } if( n_char >= 0 ) { layer->length -= i - n_char; } else { layer->length -= n_char; } if( end_y >= layer->rowlist.length ) { end_y = layer->rowlist.length - 1; end_txtrow = layer->rowlist.rows[end_y]; end_x = end_txtrow->length; } else { end_txtrow = layer->rowlist.rows[end_y]; } if( end_x > end_txtrow->length ) { end_x = end_txtrow->length; } if( end_x == char_x && end_y == char_y ) { return 0; } /* 获取上一行文本 */ prev_txtrow = layer->rowlist.rows[char_y - 1]; // 计算起始行与结束行拼接后的长度 // 起始行:0 1 2 3 4 5,起点位置:2 // 结束行:0 1 2 3 4 5,终点位置:4 // 拼接后的长度:2 + 6 - 4 = 4 len = char_x + end_txtrow->length - end_x; if( len < 0 ) { return -3; } /* 如果是同一行 */ if( txtrow == end_txtrow ) { if( end_x > end_txtrow->length ) { return -4; } TextLayer_InvalidateRowRect( layer, char_y, char_x, -1 ); TextLayer_AddUpdateTypeset( layer, char_y ); for( i = char_x, j = end_x; j < txtrow->length; ++i, ++j ) { txtrow->string[i] = txtrow->string[j]; } /* 如果当前行为空,也不是第一行,并且上一行没有结束符 */ if( len <= 0 && end_y > 0 && prev_txtrow->eol != EOL_NONE ) { TextRowList_RemoveRow( &layer->rowlist, end_y ); } /* 调整起始行的容量 */ TextRow_SetLength( txtrow, len ); /* 更新文本行的尺寸 */ TextLayer_UpdateRowSize( layer, txtrow ); return 0; } /* 如果结束点在行尾,并且该行不是最后一行 */ if( end_x == end_txtrow->length && end_y < layer->rowlist.length - 1 ) { ++end_y; end_txtrow = TextLayer_GetRow( layer, end_y ); end_x = -1; len = char_x + end_txtrow->length; } TextRow_SetLength( txtrow, len ); /* 标记当前行后面的所有行的矩形需区域需要刷新 */ TextLayer_InvalidateRowsRect( layer, char_y + 1, -1 ); /* 移除起始行与结束行之间的文本行 */ for( i = char_y + 1, j = i; j < end_y; ++j ) { TextLayer_InvalidateRowRect( layer, i, 0, -1 ); TextRowList_RemoveRow( &layer->rowlist, i ); } i = char_x; j = end_x + 1; end_y = char_y + 1; /* 将结束行的内容拼接至起始行 */ for( ; i < len && j < end_txtrow->length; ++i, ++j ) { txtrow->string[i] = end_txtrow->string[j]; } TextLayer_UpdateRowSize( layer, txtrow ); TextLayer_InvalidateRowRect( layer, end_y, 0, -1 ); /* 移除结束行 */ TextRowList_RemoveRow( &layer->rowlist, end_y ); /* 如果起始行无内容,并且上一行没有结束符(换行符),则 * 说明需要删除起始行 */ if( len <= 0 && char_y > 0 && prev_txtrow->eol != EOL_NONE ) { TextLayer_InvalidateRowRect( layer, char_y, 0, -1 ); TextRowList_RemoveRow( &layer->rowlist, char_y ); } TextLayer_AddUpdateTypeset( layer, char_y );; return 0; }
/** 删除指定行列的文字及其右边的文本 */ static int TextLayer_DeleteText( LCUI_TextLayer* layer, int char_y, int char_x, int n_char ) { int end_x, end_y, i, j, len; TextRowData *p_row, *p_end_row, *p_prev_row; if( char_x < 0 ) { char_x = 0; } if( char_y < 0 ) { char_y = 0; } if( n_char <= 0 ) { return -1; } if( char_y >= layer->row_list.rows ) { return -2; } p_row = layer->row_list.rowdata[char_y]; if( char_x > p_row->string_len ) { char_x = p_row->string_len; } end_x = char_x; end_y = char_y; --n_char; /* 计算结束点的位置 */ for( end_y=char_y; end_y<layer->row_list.rows && n_char>0; ++end_y ) { p_row = layer->row_list.rowdata[end_y]; if( p_row->eol == EOL_NONE ) { if( end_x + n_char < p_row->string_len ) { end_x += n_char; n_char = 0; break; } } else { if( end_x + n_char <= p_row->string_len ) { end_x += n_char; n_char = 0; break; } } n_char -= (p_row->string_len - end_x); end_x = 0; } if( end_y >= layer->row_list.rows ) { end_y = layer->row_list.rows-1; } p_end_row = layer->row_list.rowdata[end_y]; if( end_x > p_end_row->string_len ) { end_x = p_end_row->string_len; } /* 获取上一行文本 */ p_prev_row = layer->row_list.rowdata[char_y-1]; // 计算起始行与结束行拼接后的长度 // 起始行:0 1 2 3 4 5,起点位置:2 // 结束行:0 1 2 3 4 5,终点位置:4 // 拼接后的长度:2 + 6 - 4 - 1 = 3 len = char_x + p_end_row->string_len - end_x - 1; if( len < 0 ) { return -3; } /* 如果是同一行 */ if( p_row == p_end_row ) { if( end_x >= p_end_row->string_len ) { return -4; } TextLayer_InvalidateRowRectEx( layer, char_y, char_x, -1 ); TaskData_AddUpdateTypeset( &layer->task, char_y ); for( i=char_x, j=end_x+1; j<p_row->string_len; ++i,++j ) { p_row->string[i] = p_row->string[j]; } /* 如果当前行为空,也不是第一行,并且上一行没有结束符 */ if( len <= 0 && end_y > 0 && p_prev_row->eol != EOL_NONE ) { TextRowList_RemoveRow( &layer->row_list, end_y ); } /* 调整起始行的容量 */ TextRow_SetLength( p_row, len ); /* 更新文本行的尺寸 */ TextRow_UpdateSize( p_row, layer->text_style.pixel_size ); return 0; } /* 如果结束点在行尾,并且该行不是最后一行 */ if( end_x == p_end_row->string_len && end_y < layer->row_list.rows-1 ) { ++end_y; p_end_row = TextRowList_GetRow( &layer->row_list, end_y ); end_x = -1; len = char_x + p_end_row->string_len; } TextRow_SetLength( p_row, len ); /* 标记当前行后面的所有行的矩形需区域需要刷新 */ TextLayer_InvalidateRowsRect( layer, char_y+1, -1 ); /* 移除起始行与结束行之间的文本行 */ for( i=char_y+1, j=i; j<end_y; ++j ) { TextLayer_InvalidateRowRect( layer, i ); TextRowList_RemoveRow( &layer->row_list, i ); } end_y = char_y + 1; /* 将结束行的内容拼接至起始行 */ for( i=char_x, j=end_x+1; i<len && j<p_end_row->string_len; ++i,++j ) { p_row->string[i] = p_end_row->string[j]; } TextRow_UpdateSize( p_row, layer->text_style.pixel_size ); TextLayer_InvalidateRowRect( layer, end_y ); /* 移除结束行 */ TextRowList_RemoveRow( &layer->row_list, end_y ); /* 如果起始行无内容,并且上一行没有结束符(换行符),则 * 说明需要删除起始行 */ if( len <= 0 && char_y > 0 && p_prev_row->eol != EOL_NONE ) { TextLayer_InvalidateRowRect( layer, char_y ); TextRowList_RemoveRow( &layer->row_list, char_y ); } TaskData_AddUpdateTypeset( &layer->task, char_y );; return 0; }
/** 对指定行的文本进行排版 */ static void TextLayer_TextRowTypeset( LCUI_TextLayer layer, int row ) { TextRow txtrow; TextChar txtchar; LCUI_BOOL not_autowrap; int col, row_width = 0; int max_width; if( layer->fixed_width > 0 ) { max_width = layer->fixed_width; } else { max_width = layer->max_width; } if( max_width <= 0 || !layer->is_autowrap_mode || (layer->is_autowrap_mode && !layer->is_mulitiline_mode) ) { not_autowrap = TRUE; } else { not_autowrap = FALSE; } txtrow = layer->rowlist.rows[row]; for( col = 0; col < txtrow->length; ++col ) { txtchar = txtrow->string[col]; if( !txtchar->bitmap ) { continue; } /* 累加行宽度 */ row_width += txtchar->bitmap->advance.x; /* 如果是当前行的第一个字符,或者行宽度没有超过宽度限制 */ if( not_autowrap || col < 1 || row_width <= max_width ) { continue; } TextLayer_BreakTextRow( layer, row, col, EOL_NONE ); return; } TextLayer_UpdateRowSize( layer, txtrow ); /* 如果本行有换行符,或者是最后一行 */ if( txtrow->eol != EOL_NONE || row == layer->rowlist.length - 1 ) { return; } row_width = txtrow->width; /* 本行的文本宽度未达到限制宽度,需要将下行的文本转移至本行 */ while( txtrow->eol == EOL_NONE ) { /* 获取下一行的指针 */ TextRow next_txtrow = TextLayer_GetRow( layer, row + 1 ); if( !next_txtrow ) { break; } for( col = 0; col < next_txtrow->length; ++col ) { txtchar = next_txtrow->string[col]; /* 忽略无字体位图的文字 */ if( !txtchar->bitmap ) { TextRow_Insert( txtrow, -1, txtchar ); next_txtrow->string[col] = NULL; continue; } row_width += txtchar->bitmap->advance.x; /* 如果没有超过宽度限制 */ if( not_autowrap || row_width <= max_width ) { TextRow_Insert( txtrow, -1, txtchar ); next_txtrow->string[col] = NULL; continue; } /* 如果插入点在下一行 */ if( layer->insert_y == row + 1 ) { /* 如果插入点处于被转移的几个文字中 */ if( layer->insert_x < col ) { layer->insert_y = row; layer->insert_x += txtrow->length; } else { /* 否则,减去被转移的文字数 */ layer->insert_x -= col; } } /* 将这一行剩余的文字向前移 */ TextRow_LeftMove( next_txtrow, col ); TextLayer_UpdateRowSize( layer, txtrow ); return; } txtrow->eol = next_txtrow->eol; TextLayer_UpdateRowSize( layer, txtrow ); TextLayer_InvalidateRowRect( layer, row, 0, -1 ); TextLayer_InvalidateRowRect( layer, row + 1, 0, -1 ); /* 删除这一行,因为这一行的内容已经转移至当前行 */ TextRowList_RemoveRow( &layer->rowlist, row + 1 ); /* 如果插入点当前行在后面 */ if( layer->insert_y > row ) { --layer->insert_y; } } }