From 5d1aa8b81439b458aee1a515a553f6682acd66ef Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 26 Oct 2022 19:56:13 -0600 Subject: [PATCH] Add simple per-glyph wrapping option --- examples/syntax/src/main.rs | 1 + src/buffer.rs | 24 +++++++++---- src/shape.rs | 67 +++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/examples/syntax/src/main.rs b/examples/syntax/src/main.rs index 4657c9f..d258335 100644 --- a/examples/syntax/src/main.rs +++ b/examples/syntax/src/main.rs @@ -153,6 +153,7 @@ fn main() { } line.attrs_list = attrs_list; + line.wrap_simple = true; line.reset(); } diff --git a/src/buffer.rs b/src/buffer.rs index c85ded4..624a1b9 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -178,6 +178,7 @@ pub struct TextBufferLine<'a> { pub attrs_list: AttrsList<'a>, shape_opt: Option, layout_opt: Option>, + pub wrap_simple: bool, } impl<'a> TextBufferLine<'a> { @@ -187,6 +188,7 @@ impl<'a> TextBufferLine<'a> { attrs_list, shape_opt: None, layout_opt: None, + wrap_simple: false, } } @@ -210,13 +212,21 @@ impl<'a> TextBufferLine<'a> { pub fn layout(&mut self, font_system: &'a FontSystem<'a>, font_size: i32, width: i32) -> &[LayoutLine] { if self.layout_opt.is_none() { let mut layout = Vec::new(); - let shape = self.shape(font_system); - shape.layout( - font_size, - width, - &mut layout, - 0, - ); + if self.wrap_simple { + self.shape(font_system).layout_simple( + font_size, + width, + &mut layout, + 0, + ); + } else { + self.shape(font_system).layout( + font_size, + width, + &mut layout, + 0, + ); + } self.layout_opt = Some(layout); } self.layout_opt.as_ref().unwrap() diff --git a/src/shape.rs b/src/shape.rs index 5e5c877..b1eb56c 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -472,6 +472,73 @@ impl ShapeLine { Self { rtl, spans } } + //TODO: combine with layout function + pub fn layout_simple( + &self, + font_size: i32, + line_width: i32, + layout_lines: &mut Vec, + mut layout_i: usize, + ) { + let mut push_line = true; + let mut glyphs = Vec::new(); + + let start_x = if self.rtl { line_width as f32 } else { 0.0 }; + let end_x = if self.rtl { 0.0 } else { line_width as f32 }; + let mut x = start_x; + let mut y = 0.0; + for span in self.spans.iter() { + for word in span.words.iter() { + for glyph in word.glyphs.iter() { + let x_advance = font_size as f32 * glyph.x_advance; + let y_advance = font_size as f32 * glyph.y_advance; + + let wrap = if self.rtl { + x - x_advance < end_x + } else { + x + x_advance > end_x + }; + + if wrap { + let mut glyphs_swap = Vec::new(); + std::mem::swap(&mut glyphs, &mut glyphs_swap); + layout_lines.insert( + layout_i, + LayoutLine { + glyphs: glyphs_swap, + }, + ); + layout_i += 1; + + x = start_x; + y = 0.0; + } + + if self.rtl { + x -= x_advance + } + + glyphs.push(glyph.layout(font_size, x, y, span.rtl)); + push_line = true; + + if !self.rtl { + x += x_advance; + } + y += y_advance; + } + } + } + + if push_line { + layout_lines.insert( + layout_i, + LayoutLine { + glyphs, + }, + ); + } + } + pub fn layout( &self, font_size: i32,