aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/text.rs124
-rw-r--r--src/text/rich.rs126
2 files changed, 157 insertions, 93 deletions
diff --git a/src/text.rs b/src/text.rs
index 9c132ad..911c0cc 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -818,60 +818,92 @@ fn highlight_line(
) -> impl Iterator<Item = (f32, f32)> + '_ {
let layout = line.layout_opt().map(Vec::as_slice).unwrap_or_default();
- layout.iter().map(move |visual_line| {
- let start = visual_line
- .glyphs
- .first()
- .map(|glyph| glyph.start)
- .unwrap_or(0);
- let end = visual_line
- .glyphs
- .last()
- .map(|glyph| glyph.end)
- .unwrap_or(0);
-
- let mut range = start.max(from)..end.min(to);
-
- let x_offset = visual_line
- .glyphs
- .first()
- .map(|glyph| glyph.x)
- .unwrap_or_default();
+ // Check for multi codepoint glyphs for each previous visual line
+ let mut previous_diff = 0;
+ let previous_lines_diff = line
+ .layout_opt()
+ .map(Vec::as_slice)
+ .unwrap_or_default()
+ .iter()
+ .enumerate()
+ .map(move |(line_nr, visual_line)| {
+ if line_nr == 0 {
+ let current_diff = previous_diff
+ + visual_line
+ .glyphs
+ .iter()
+ .fold(0, |d, g| d + g.start.abs_diff(g.end) - 1);
+ previous_diff = current_diff;
+ 0
+ } else {
+ let current_diff = previous_diff
+ + visual_line
+ .glyphs
+ .iter()
+ .fold(0, |d, g| d + g.start.abs_diff(g.end) - 1);
+ let previous_diff_temp = previous_diff;
+ previous_diff = current_diff;
+ previous_diff_temp
+ }
+ });
- if range.is_empty() {
- (x_offset, 0.0)
- } else if range.start == start && range.end == end {
- (x_offset, visual_line.w)
- } else {
- let mut x = 0.0;
- let mut width = 0.0;
- for glyph in &visual_line.glyphs {
- let glyph_count = glyph.start.abs_diff(glyph.end);
+ layout.iter().zip(previous_lines_diff).map(
+ move |(visual_line, previous_lines_diff)| {
+ let start = visual_line
+ .glyphs
+ .first()
+ .map(|glyph| glyph.start)
+ .unwrap_or(0);
+ let end = visual_line
+ .glyphs
+ .last()
+ .map(|glyph| glyph.end)
+ .unwrap_or(0);
+
+ let to = to + previous_lines_diff;
+ let mut range = start.max(from)..end.min(to);
+
+ let x_offset = visual_line
+ .glyphs
+ .first()
+ .map(|glyph| glyph.x)
+ .unwrap_or_default();
+
+ if range.is_empty() {
+ (x_offset, 0.0)
+ } else if range.start == start && range.end == end {
+ (x_offset, visual_line.w)
+ } else {
+ let mut x = 0.0;
+ let mut width = 0.0;
+ for glyph in &visual_line.glyphs {
+ let glyph_count = glyph.start.abs_diff(glyph.end);
+
+ // Check for multi codepoint glyphs before or within the range
+ if glyph_count > 1 {
+ if range.start > glyph.start {
+ range.start += glyph_count - 1;
+ range.end += glyph_count - 1;
+ } else if range.end > glyph.start {
+ range.end += glyph_count - 1;
+ }
+ }
- // Check for multi codepoint glyphs before or within the range
- if glyph_count > 1 {
if range.start > glyph.start {
- range.start += glyph_count - 1;
- range.end += glyph_count - 1;
- } else if range.end > glyph.start {
- range.end += glyph_count - 1;
+ x += glyph.w;
}
- }
- if range.start > glyph.start {
- x += glyph.w;
+ if range.start <= glyph.start && range.end > glyph.start {
+ width += glyph.w;
+ } else if range.end <= glyph.start {
+ break;
+ }
}
- if range.start <= glyph.start && range.end > glyph.start {
- width += glyph.w;
- } else if range.end <= glyph.start {
- break;
- }
+ (x_offset + x, width)
}
-
- (x_offset + x, width)
- }
- })
+ },
+ )
}
fn visual_lines_offset(line: usize, buffer: &cosmic_text::Buffer) -> i32 {
diff --git a/src/text/rich.rs b/src/text/rich.rs
index 22be56d..44c6f3e 100644
--- a/src/text/rich.rs
+++ b/src/text/rich.rs
@@ -965,60 +965,92 @@ fn highlight_line(
) -> impl Iterator<Item = (f32, f32)> + '_ {
let layout = line.layout_opt().map(Vec::as_slice).unwrap_or_default();
- layout.iter().map(move |visual_line| {
- let start = visual_line
- .glyphs
- .first()
- .map(|glyph| glyph.start)
- .unwrap_or(0);
- let end = visual_line
- .glyphs
- .last()
- .map(|glyph| glyph.end)
- .unwrap_or(0);
-
- let mut range = start.max(from)..end.min(to);
-
- let x_offset = visual_line
- .glyphs
- .first()
- .map(|glyph| glyph.x)
- .unwrap_or_default();
-
- if range.is_empty() {
- (x_offset, 0.0)
- } else if range.start == start && range.end == end {
- (x_offset, visual_line.w)
- } else {
- let mut x = 0.0;
- let mut width = 0.0;
- for glyph in &visual_line.glyphs {
- let glyph_count = glyph.start.abs_diff(glyph.end);
+ // Check for multi codepoint glyphs for each previous visual line
+ let mut previous_diff = 0;
+ let previous_lines_diff = line
+ .layout_opt()
+ .map(Vec::as_slice)
+ .unwrap_or_default()
+ .iter()
+ .enumerate()
+ .map(move |(line_nr, visual_line)| {
+ if line_nr == 0 {
+ let current_diff = previous_diff
+ + visual_line
+ .glyphs
+ .iter()
+ .fold(0, |d, g| d + g.start.abs_diff(g.end) - 1);
+ previous_diff = current_diff;
+ 0
+ } else {
+ let current_diff = previous_diff
+ + visual_line
+ .glyphs
+ .iter()
+ .fold(0, |d, g| d + g.start.abs_diff(g.end) - 1);
+ let previous_diff_temp = previous_diff;
+ previous_diff = current_diff;
+ previous_diff_temp
+ }
+ });
+
+ layout.iter().zip(previous_lines_diff).map(
+ move |(visual_line, previous_lines_diff)| {
+ let start = visual_line
+ .glyphs
+ .first()
+ .map(|glyph| glyph.start)
+ .unwrap_or(0);
+ let end = visual_line
+ .glyphs
+ .last()
+ .map(|glyph| glyph.end)
+ .unwrap_or(0);
+
+ let to = to + previous_lines_diff;
+ let mut range = start.max(from)..end.min(to);
+
+ let x_offset = visual_line
+ .glyphs
+ .first()
+ .map(|glyph| glyph.x)
+ .unwrap_or_default();
+
+ if range.is_empty() {
+ (x_offset, 0.0)
+ } else if range.start == start && range.end == end {
+ (x_offset, visual_line.w)
+ } else {
+ let mut x = 0.0;
+ let mut width = 0.0;
+ for glyph in &visual_line.glyphs {
+ let glyph_count = glyph.start.abs_diff(glyph.end);
+
+ // Check for multi codepoint glyphs before or within the range
+ if glyph_count > 1 {
+ if range.start > glyph.start {
+ range.start += glyph_count - 1;
+ range.end += glyph_count - 1;
+ } else if range.end > glyph.start {
+ range.end += glyph_count - 1;
+ }
+ }
- // Check for multi codepoint glyphs before or within the range
- if glyph_count > 1 {
if range.start > glyph.start {
- range.start += glyph_count - 1;
- range.end += glyph_count - 1;
- } else if range.end > glyph.start {
- range.end += glyph_count - 1;
+ x += glyph.w;
}
- }
- if range.start > glyph.start {
- x += glyph.w;
+ if range.start <= glyph.start && range.end > glyph.start {
+ width += glyph.w;
+ } else if range.end <= glyph.start {
+ break;
+ }
}
- if range.start <= glyph.start && range.end > glyph.start {
- width += glyph.w;
- } else if range.end <= glyph.start {
- break;
- }
+ (x_offset + x, width)
}
-
- (x_offset + x, width)
- }
- })
+ },
+ )
}
fn visual_lines_offset(line: usize, buffer: &cosmic_text::Buffer) -> i32 {