Skip to content

Commit adafe0d

Browse files
committed
fix text-input overflow problem when input Unicode char
1 parent f601be8 commit adafe0d

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

renderer/src/text/layout.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ pub struct HitPoint {
188188
pub line: usize,
189189
/// First-byte-index of glyph at cursor (will insert behind this glyph)
190190
pub index: usize,
191+
/// Code-point index of glyph at cursor (use with String::chars())
192+
pub char_index: usize,
191193
/// Whether or not the point was inside the bounds of the layout object.
192194
///
193195
/// A click outside the layout object will still resolve to a position in the
@@ -354,15 +356,32 @@ impl TextLayout {
354356
if let Some(cursor) = self.hit(point.x as f32, point.y as f32) {
355357
let size = self.size();
356358
let is_inside = point.x <= size.width && point.y <= size.height;
359+
360+
// FIXME: It seems that there is no API to get the char-point index of the text directly
361+
// So it have to calculate it manually.
362+
let char_index = {
363+
let mut byte_index = 0;
364+
self.buffer
365+
.lines
366+
.iter()
367+
.flat_map(|x| x.text().chars())
368+
.take_while(|x| {
369+
byte_index += x.len_utf8();
370+
byte_index <= cursor.index
371+
})
372+
.count()
373+
};
357374
HitPoint {
358375
line: cursor.line,
359376
index: cursor.index,
377+
char_index,
360378
is_inside,
361379
}
362380
} else {
363381
HitPoint {
364382
line: 0,
365383
index: 0,
384+
char_index: 0,
366385
is_inside: false,
367386
}
368387
}

src/views/text_input.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,12 @@ impl TextInput {
356356
}
357357
self.cursor_x = cursor_x;
358358

359-
let clip_start = virt_text.hit_point(Point::new(clip_start_x, 0.0)).index;
359+
let clip_start = virt_text
360+
.hit_point(Point::new(clip_start_x, 0.0))
361+
.char_index;
360362
let clip_end = virt_text
361363
.hit_point(Point::new(clip_start_x + node_width, 0.0))
362-
.index;
364+
.char_index;
363365

364366
let new_text = self
365367
.buffer

0 commit comments

Comments
 (0)