Add simple per-glyph wrapping option

This commit is contained in:
Jeremy Soller 2022-10-26 19:56:13 -06:00
parent 57feeb2901
commit 5d1aa8b814
3 changed files with 85 additions and 7 deletions

View file

@ -153,6 +153,7 @@ fn main() {
}
line.attrs_list = attrs_list;
line.wrap_simple = true;
line.reset();
}

View file

@ -178,6 +178,7 @@ pub struct TextBufferLine<'a> {
pub attrs_list: AttrsList<'a>,
shape_opt: Option<ShapeLine>,
layout_opt: Option<Vec<LayoutLine>>,
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()

View file

@ -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<LayoutLine>,
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,