Esempio n. 1
0
/** 更新数据 */
void TextLayer_Update( LCUI_TextLayer layer, LinkedList *rect_list )
{
	if( layer->task.update_bitmap ) {
		TextLayer_InvalidateRowsRect( layer, 0, -1 );
		TextLayer_ReloadCharBitmap( layer );
		TextLayer_InvalidateRowsRect( layer, 0, -1 );
		layer->task.update_bitmap = FALSE;
		layer->task.redraw_all = TRUE;
	}
	if( layer->task.update_typeset ) {
		TextLayer_TextTypeset( layer, layer->task.typeset_start_row );
		layer->task.update_typeset = FALSE;
		layer->task.typeset_start_row = 0;
	}
	layer->width = TextLayer_GetWidth( layer );
	/* 如果坐标偏移量有变化,记录各个文本行区域 */
	if( layer->new_offset_x != layer->offset_x
	 || layer->new_offset_y != layer->offset_y ) {
		TextLayer_InvalidateRowsRect( layer, 0, -1 );
		layer->offset_x = layer->new_offset_x;
		layer->offset_y = layer->new_offset_y;
		TextLayer_InvalidateRowsRect( layer, 0, -1 );
		layer->task.redraw_all = TRUE;
	}
	if( rect_list ) {
		LinkedList_Concat( rect_list, &layer->dirty_rect );
	 }
}
Esempio n. 2
0
/** 从指定行开始,对文本进行排版 */
static void TextLayer_TextTypeset( LCUI_TextLayer *layer, int start_row )
{
	int row;
	/* 记录排版前各个文本行的矩形区域 */
	TextLayer_InvalidateRowsRect( layer, start_row, -1 );
	for( row=start_row; row<layer->row_list.rows; ++row ) {
		TextLayer_TextRowTypeset( layer, row );
	}
	/* 记录排版后各个文本行的矩形区域 */
	TextLayer_InvalidateRowsRect( layer, start_row, -1 );
}
Esempio n. 3
0
/** 清空文本 */
void TextLayer_ClearText( LCUI_TextLayer layer )
{
	layer->length = 0;
	layer->insert_x = 0;
	layer->insert_y = 0;
	layer->width = 0;
	TextLayer_InvalidateRowsRect( layer, 0, -1 );
	TextRowList_Destroy( &layer->rowlist );
	LinkedList_Clear( &layer->style_cache, (FuncPtr)TextStyle_Destroy );
	TextRowList_InsertNewRow( &layer->rowlist, 0 );
	layer->task.redraw_all = TRUE;
}
Esempio n. 4
0
/** 对文本进行预处理 */ 
static int TextLayer_ProcessText( LCUI_TextLayer *layer, const wchar_t *wstr,
			TextAddType add_type, LCUI_StyleTagStack *tag_stack )
{
	EOLChar eol;
	int cur_col, cur_row, start_row, ins_x, ins_y;
	const wchar_t *p_end, *p, *pp;
	TextRowData *p_row;
	TextCharData char_data;
	LCUI_StyleTagStack tmp_tag_stack;
	LCUI_BOOL is_tmp_tag_stack, need_typeset, rect_has_added;

	if( !wstr ) {
		return -1;
	}
	is_tmp_tag_stack = FALSE;
	need_typeset = FALSE;
	rect_has_added = FALSE;
	/* 如果是将文本追加至文本末尾 */
	if( add_type == TEXT_ADD_TYPE_APPEND ) {
		if( layer->row_list.rows > 0 ) {
			cur_row = layer->row_list.rows - 1;
		} else {
			cur_row = 0;
		}
		p_row = TextRowList_GetRow( &layer->row_list, cur_row );
		if( !p_row ) {
			p_row = TextRowList_AddNewRow( &layer->row_list );
		}
		cur_col = p_row->string_len;
	} else { /* 否则,是将文本插入至当前插入点 */
		cur_row = layer->insert_y;
		cur_col = layer->insert_x;
		p_row = TextRowList_GetRow( &layer->row_list, cur_row );
		if( !p_row ) {
			p_row = TextRowList_AddNewRow( &layer->row_list );
		}
	}
	start_row = cur_row;
	ins_x = cur_col;
	ins_y = cur_row;
	/* 如果没有可用的标签栈,则使用临时的标签栈 */
	if( !tag_stack ) {
		is_tmp_tag_stack = TRUE;
		StyleTagStack_Init( &tmp_tag_stack );
		tag_stack = &tmp_tag_stack;
	}
	p_end = wstr + wcslen(wstr);
	for( p=wstr; p<p_end; ++p ) {
		if( layer->is_using_style_tags ) {
			/* 处理样式的结束标签 */ 
			pp = StyleTagStack_ScanEndingTag( tag_stack, p );
			if( pp ) {
				p = pp;
				/* 抵消本次循环后的++p,以在下次循环时还能够在当前位置 */
				--p; 
				continue;
			}
			/* 处理样式标签 */
			pp = StyleTagStack_ScanBeginTag( tag_stack, p );
			if( pp ) {
				p = pp - 1;
				continue;
			}
		}
		
		if( *p == '\r' || *p == '\n' ) {
			/* 如果后面还有 \n,则说明是CR/LF换行模式 */
			if( *p == 'r' ) {
				if( p+1 < p_end && *(p+1) == '\n' ) {
					eol = EOL_CR_LF;
				} else {
					/* 否则是CR换行模式 */
					eol = EOL_CR;
				}
			} else {
				eol = EOL_LF;
			}
			/* 如果没有记录过文本行的矩形区域 */
			if( !rect_has_added ) {
				TextLayer_InvalidateRowsRect( layer, ins_y, -1 );
				rect_has_added = TRUE;
				start_row = ins_y;
			}
			/* 将当前行中的插入点为截点,进行断行 */
			TextLayer_BreakTextRow( layer, ins_y, ins_x, eol );
			need_typeset = TRUE;
			ins_x = 0;
			++ins_y;
			p_row = TextRowList_GetRow( &layer->row_list, ins_y );
			continue;
		}

		char_data.char_code = *p;
		/* 获取当前文本样式数据 */
		char_data.style = StyleTagStack_GetTextStyle( tag_stack );
		/* 更新字体位图 */
		TextChar_UpdateBitmap( &char_data, &layer->text_style );
		TextRow_InsertCopy( p_row, ins_x, &char_data );
		++ins_x;
	}
	/* 更新当前行的尺寸 */
	TextRow_UpdateSize( p_row, layer->text_style.pixel_size );
	if( add_type == TEXT_ADD_TYPE_INSERT ) {
		layer->insert_x = ins_x;
		layer->insert_y = ins_y;
	}
	/* 若启用了自动换行模式,则标记需要重新对文本进行排版 */
	if( layer->is_autowrap_mode || need_typeset ) {
		TaskData_AddUpdateTypeset( &layer->task, cur_row );
	} else {
		TextLayer_InvalidateRowRect( layer, cur_row );
	}
	/* 如果已经记录过文本行矩形区域 */
	if( rect_has_added ) {
		TextLayer_InvalidateRowsRect( layer, start_row, -1 );
		rect_has_added = TRUE;
	}
	/* 如果使用的是临时标签栈,则销毁它 */
	if( is_tmp_tag_stack ) {
		StyleTagStack_Destroy( tag_stack );
	}
	return 0;
}
Esempio n. 5
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;
}
Esempio n. 6
0
/** 删除指定行列的文字及其右边的文本 */
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;
}
Esempio n. 7
0
/** 对文本进行预处理 */
static int TextLayer_ProcessText( LCUI_TextLayer layer, const wchar_t *wstr,
				  int add_type, LinkedList *tags )
{
	EOLChar eol;
	TextRow txtrow;
	TextCharRec txtchar;
	LinkedList tmp_tags;
	LCUI_TextStyle *style = NULL;
	const wchar_t *p_end, *p, *pp;
	int cur_col, cur_row, start_row, ins_x, ins_y;
	LCUI_BOOL is_tmp_tag_stack, need_typeset, rect_has_added;

	if( !wstr ) {
		return -1;
	}
	need_typeset = FALSE;
	rect_has_added = FALSE;
	is_tmp_tag_stack = FALSE;
	/* 如果是将文本追加至文本末尾 */
	if( add_type == TAT_APPEND ) {
		if( layer->rowlist.length > 0 ) {
			cur_row = layer->rowlist.length - 1;
		} else {
			cur_row = 0;
		}
		txtrow = TextLayer_GetRow( layer, cur_row );
		if( !txtrow ) {
			txtrow = TextRowList_AddNewRow( &layer->rowlist );
		}
		cur_col = txtrow->length;
	} else { /* 否则,是将文本插入至当前插入点 */
		cur_row = layer->insert_y;
		cur_col = layer->insert_x;
		txtrow = TextLayer_GetRow( layer, cur_row );
		if( !txtrow ) {
			txtrow = TextRowList_AddNewRow( &layer->rowlist );
		}
	}
	start_row = cur_row;
	ins_x = cur_col;
	ins_y = cur_row;
	/* 如果没有可用的标签栈,则使用临时的标签栈 */
	if( !tags ) {
		is_tmp_tag_stack = TRUE;
		StyleTags_Init( &tmp_tags );
		tags = &tmp_tags;
	}
	p_end = wstr + wcslen( wstr );
	for( p = wstr; p < p_end; ++p ) {
		/* 如果启用的样式标签支持,则处理样式的结束标签 */
		if( layer->is_using_style_tags ) {
			pp = StyleTags_ScanEndingTag( tags, p );
			if( pp ) {
				/* 抵消本次循环后的++p,以在下次循环时还能够在当前位置 */
				p = pp - 1;
				style = StyleTags_GetTextStyle( tags );
				LinkedList_Append( &layer->style_cache, style );
				continue;
			}
			pp = StyleTags_ScanBeginTag( tags, p );
			if( pp ) {
				p = pp - 1;
				style = StyleTags_GetTextStyle( tags );
				LinkedList_Append( &layer->style_cache, style );
				continue;
			}
		}

		if( *p == '\r' || *p == '\n' ) {
			/* 判断是哪一种换行模式 */
			if( *p == '\r' ) {
				if( p + 1 < p_end && *(p + 1) == '\n' ) {
					eol = EOL_CR_LF;
				} else {
					eol = EOL_CR;
				}
			} else {
				eol = EOL_LF;
			}
			/* 如果没有记录过文本行的矩形区域 */
			if( !rect_has_added ) {
				TextLayer_InvalidateRowsRect( layer, ins_y, -1 );
				rect_has_added = TRUE;
				start_row = ins_y;
			}
			/* 将当前行中的插入点为截点,进行断行 */
			TextLayer_BreakTextRow( layer, ins_y, ins_x, eol );
			layer->width = max( layer->width, txtrow->width );
			need_typeset = TRUE;
			++layer->length;
			ins_x = 0;
			++ins_y;
			txtrow = TextLayer_GetRow( layer, ins_y );
			continue;
		}
		txtchar.style = style;
		txtchar.char_code = *p;
		TextChar_UpdateBitmap( &txtchar, &layer->text_style );
		TextRow_InsertCopy( txtrow, ins_x, &txtchar );
		++layer->length;
		++ins_x;
	}
	/* 更新当前行的尺寸 */
	TextLayer_UpdateRowSize( layer, txtrow );
	layer->width = max( layer->width, txtrow->width );
	if( add_type == TAT_INSERT ) {
		layer->insert_x = ins_x;
		layer->insert_y = ins_y;
	}
	/* 若启用了自动换行模式,则标记需要重新对文本进行排版 */
	if( layer->is_autowrap_mode || need_typeset ) {
		TextLayer_AddUpdateTypeset( layer, cur_row );
	} else {
		TextLayer_InvalidateRowRect( layer, cur_row, 0, -1 );
	}
	/* 如果已经记录过文本行矩形区域 */
	if( rect_has_added ) {
		TextLayer_InvalidateRowsRect( layer, start_row, -1 );
		rect_has_added = TRUE;
	}
	/* 如果使用的是临时标签栈,则销毁它 */
	if( is_tmp_tag_stack ) {
		StyleTags_Clear( tags );
	}
	return 0;
}