Fix render issues

This commit is contained in:
daa84 2017-09-01 13:14:16 +03:00
parent 40f5492ba8
commit e8b23f18f5
6 changed files with 55 additions and 22 deletions

View File

@ -22,7 +22,7 @@ impl Context {
} }
pub fn itemize(&self, line: &StyledLine) -> Vec<sys_pango::Item> { pub fn itemize(&self, line: &StyledLine) -> Vec<sys_pango::Item> {
sys_pango::pango_itemize(&self.pango_context, &line.line_str, &line.attr_list) sys_pango::pango_itemize(&self.pango_context, line.line_str.trim_right(), &line.attr_list)
} }
} }

View File

@ -52,7 +52,6 @@ pub fn shape_dirty(ctx: &context::Context, ui_model: &mut ui_model::UiModel) {
for i in 0..line.line.len() { for i in 0..line.line.len() {
if line[i].dirty { if line[i].dirty {
// FIXME: dont shape/render empty items(space cells)
if let Some(mut item) = line.get_item_mut(i) { if let Some(mut item) = line.get_item_mut(i) {
let mut glyphs = pango::GlyphString::new(); let mut glyphs = pango::GlyphString::new();
{ {

View File

@ -39,4 +39,8 @@ impl Item {
pub fn offset(&self) -> (usize, usize, usize) { pub fn offset(&self) -> (usize, usize, usize) {
(self.0.offset as usize, self.0.length as usize, self.0.num_chars as usize) (self.0.offset as usize, self.0.length as usize, self.0.num_chars as usize)
} }
pub fn length(&self) -> i32 {
self.0.length
}
} }

View File

@ -13,7 +13,7 @@ use glib::translate::*;
pub fn pango_itemize( pub fn pango_itemize(
context: &pango::Context, context: &pango::Context,
text: &String, text: &str,
attrs: &pango::AttrList attrs: &pango::AttrList
) -> Vec<Item> { ) -> Vec<Item> {
unsafe { unsafe {
@ -29,7 +29,7 @@ pub fn pango_itemize(
} }
pub fn pango_shape( pub fn pango_shape(
text: &String, text: &str,
offset: usize, offset: usize,
length: usize, length: usize,
analysis: &Analysis, analysis: &Analysis,

View File

@ -75,6 +75,13 @@ impl Line {
} }
} }
pub fn copy_to(&self, target: &mut Self, left: usize, right: usize) {
target.line[left..right + 1].clone_from_slice(&self.line[left..right + 1]);
// don't update items, but mark line as dirty to force item recalculation
// all work must be done in merge function
target.dirty_line = true;
}
pub fn clear(&mut self, left: usize, right: usize) { pub fn clear(&mut self, left: usize, right: usize) {
for cell in &mut self.line[left..right + 1] { for cell in &mut self.line[left..right + 1] {
cell.clear(); cell.clear();
@ -93,30 +100,41 @@ impl Line {
} }
} }
fn set_cell_to_item(&mut self, pango_item: &PangoItemPosition) -> bool { fn set_cell_to_item(&mut self, new_item: &PangoItemPosition) -> bool {
let start_item = self.cell_to_item(pango_item.start_cell); let start_item_idx = self.cell_to_item(new_item.start_cell);
let end_item = self.cell_to_item(pango_item.end_cell); let start_item_len = if start_item_idx > 0 {
//FIXME: check start cell self.item_line[start_item_idx as usize]
//FIXME: check length .as_ref()
//FIXME: don't check start_item != end_item .unwrap()
.item
.length()
} else {
-1
};
let end_item_idx = self.cell_to_item(new_item.end_cell);
// start_item == idx of item start cell
// in case different item length was in previous iteration // in case different item length was in previous iteration
// mark all item as dirty // mark all item as dirty
if start_item != end_item || start_item == -1 || end_item == -1 { if start_item_idx != new_item.start_cell as i32 ||
self.initialize_cell_item(pango_item.start_cell, pango_item.end_cell, pango_item.item); new_item.item.length() != start_item_len || start_item_idx == -1 ||
end_item_idx == -1
{
self.initialize_cell_item(new_item.start_cell, new_item.end_cell, new_item.item);
true true
} else { } else {
// update only if cell marked as dirty // update only if cell marked as dirty
if self.line[pango_item.start_cell..pango_item.end_cell + 1] if self.line[new_item.start_cell..new_item.end_cell + 1]
.iter() .iter()
.find(|c| c.dirty) .find(|c| c.dirty)
.is_some() .is_some()
{ {
self.item_line[pango_item.start_cell] self.item_line[new_item.start_cell]
.as_mut() .as_mut()
.unwrap() .unwrap()
.update(pango_item.item.clone()); .update(new_item.item.clone());
self.line[pango_item.start_cell].dirty = true; self.line[new_item.start_cell].dirty = true;
true true
} else { } else {
false false

View File

@ -123,12 +123,24 @@ impl UiModel {
} }
#[inline] #[inline]
fn copy_row(&mut self, row: i64, offset: i64, left: usize, right: usize) { fn copy_row(&mut self, target_row: i64, offset: i64, left_col: usize, right_col: usize) {
for col in left..right + 1 { debug_assert!(offset != 0);
let from_row = (row + offset) as usize;
let from_cell = self.model[from_row][col].clone(); let from_row = (target_row + offset) as usize;
self.model[row as usize][col] = from_cell;
} let (left, right) = if offset > 0 {
self.model.split_at_mut(from_row)
} else {
self.model.split_at_mut(target_row as usize)
};
let (source_row, target_row) = if offset > 0 {
(&right[0], &mut left[target_row as usize])
} else {
(&left[from_row], &mut right[0])
};
source_row.copy_to(target_row, left_col, right_col);
} }
pub fn scroll(&mut self, count: i64) -> ModelRect { pub fn scroll(&mut self, count: i64) -> ModelRect {