コード例 #1
0
ファイル: textlayer.c プロジェクト: oyjGit/LCUI
/** 对指定行的文本进行排版 */
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;
		}
	}
}
コード例 #2
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;
}
コード例 #3
0
ファイル: textlayer.c プロジェクト: oyjGit/LCUI
/** 删除指定行列的文字及其右边的文本 */
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;
}
コード例 #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;
		}
	}
}