Пример #1
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;
}
Пример #2
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;
}
Пример #3
0
/** 对指定行的文本进行排版 */
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;
		}
	}
}
Пример #4
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;
		}
	}
}