Skip to content

Commit 7c3eedb

Browse files
committed
identify the cause of #3
1 parent ee7e0e0 commit 7c3eedb

3 files changed

Lines changed: 23 additions & 17 deletions

File tree

src/pix_grid.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,17 +148,19 @@ pub fn cursor_x(
148148
return (space_width, x, 0.0);
149149
};
150150

151-
// FIXME (#3): cursor on multibyte char isn't visible. (e.g. on 2nd byte of "é")
152-
// the issue comes from "cursor_width", which is set to `0`.
153151
if col + n > cursor_col {
154-
let m = cursor_col - col;
155-
let text = line.to_string(col, col + n);
156152
let analysis = item.analysis();
157-
let (start, end) = (
158-
unscale!(glyph_string.index_to_x(&text, analysis, m as i32, false)),
159-
unscale!(glyph_string.index_to_x(&text, analysis, m as i32, true)),
160-
);
161-
cursor_width = end - start;
153+
154+
// We can't use the same technique as in PixLine::update, because items are typically grouped in words and here we need to analyse position and width inside a word.
155+
// TODO: optimize
156+
let mut s = String::new();
157+
for cell in line.line[col..cursor_col].iter() {
158+
s.push_str(&cell.ch);
159+
}
160+
let start = unscale!(glyph_string.index_to_x(&s, analysis, s.len() as i32, false));
161+
let mut glyphs = pango::GlyphString::new();
162+
pango::shape(&line.line[cursor_col].ch, analysis, &mut glyphs);
163+
cursor_width = unscale!(glyphs.width());
162164
x += start;
163165
prefix = start;
164166
}

src/ui_model/item.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ impl Item {
5757
}
5858
}
5959

60+
pub fn width(&self) -> i32 {
61+
self.glyphs().as_ref().map(|g| g.width()).unwrap_or(0)
62+
}
63+
6064
pub fn new_render_node(
6165
&self,
6266
color: &color::Color,

src/ui_model/line.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,6 @@ impl Line {
3535
}
3636
}
3737

38-
pub fn to_string(&self, start_index: usize, end_index: usize) -> String {
39-
let mut s = String::new();
40-
for i in self.line[start_index..end_index].iter() {
41-
s.push_str(&i.ch);
42-
}
43-
s
44-
}
45-
4638
pub fn swap_with(&mut self, target: &mut Self, left: usize, right: usize) {
4739
// swap is faster then clone
4840
target.line[left..=right].swap_with_slice(&mut self.line[left..=right]);
@@ -220,6 +212,14 @@ impl Line {
220212
pub fn is_binded_to_item(&self, cell_idx: usize) -> bool {
221213
self.cell_to_item[cell_idx] >= 0
222214
}
215+
216+
pub fn width(&self, index: usize) -> i32 {
217+
if let Some(item_line) = self.item_line.get(index).map(|i| i.first()) {
218+
item_line.iter().map(|i| i.width()).sum()
219+
} else {
220+
0
221+
}
222+
}
223223
}
224224

225225
impl Index<usize> for Line {

0 commit comments

Comments
 (0)