diff --git a/crates/gpui/examples/text_layout.rs b/crates/gpui/examples/text_layout.rs new file mode 100644 index 0000000000000000000000000000000000000000..d855b6434857754a366cb39e6c81a92d4e76d0a4 --- /dev/null +++ b/crates/gpui/examples/text_layout.rs @@ -0,0 +1,64 @@ +use gpui::{ + div, prelude::*, px, size, App, Application, Bounds, Context, Window, WindowBounds, + WindowOptions, +}; + +struct HelloWorld {} + +impl Render for HelloWorld { + fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { + div() + .bg(gpui::white()) + .flex() + .flex_col() + .gap_3() + .p_4() + .size_full() + .child(div().child("Text left")) + .child(div().text_center().child("Text center")) + .child(div().text_right().child("Text right")) + .child( + div() + .flex() + .gap_2() + .justify_between() + .child( + div() + .w(px(400.)) + .border_1() + .border_color(gpui::blue()) + .p_1() + .whitespace_nowrap() + .overflow_hidden() + .text_center() + .child("A long non-wrapping text align center"), + ) + .child( + div() + .w_32() + .border_1() + .border_color(gpui::blue()) + .p_1() + .whitespace_nowrap() + .overflow_hidden() + .text_right() + .child("100%"), + ), + ) + } +} + +fn main() { + Application::new().run(|cx: &mut App| { + let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx); + cx.open_window( + WindowOptions { + window_bounds: Some(WindowBounds::Windowed(bounds)), + ..Default::default() + }, + |_, cx| cx.new(|_| HelloWorld {}), + ) + .unwrap(); + cx.activate(true); + }); +} diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index 6460172168c255b80661a76f78e651db3d65f56b..26c43df702bd8efbadab59544ae877d53dc22394 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -1684,7 +1684,7 @@ impl Interactivity { .ok() .and_then(|mut text| text.pop()) { - text.paint(hitbox.origin, FONT_SIZE, TextAlign::Left, window, cx) + text.paint(hitbox.origin, FONT_SIZE, TextAlign::Left, None, window, cx) .ok(); let text_bounds = crate::Bounds { diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 21913af93f2770d69629a107afb4a6a00d31d80b..132135d4d604bb7927025c4df4f54a6fe31cfe88 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -392,8 +392,15 @@ impl TextLayout { let mut line_origin = bounds.origin; let text_style = window.text_style(); for line in &element_state.lines { - line.paint(line_origin, line_height, text_style.text_align, window, cx) - .log_err(); + line.paint( + line_origin, + line_height, + text_style.text_align, + Some(bounds), + window, + cx, + ) + .log_err(); line_origin.y += line.size(line_height).height; } } diff --git a/crates/gpui/src/text_system/line.rs b/crates/gpui/src/text_system/line.rs index 5c14565c1572f75c188c5610e9f9d3e23d2a604f..27da7d66c59a87f896fc18591f0d8d26deb84e6f 100644 --- a/crates/gpui/src/text_system/line.rs +++ b/crates/gpui/src/text_system/line.rs @@ -107,15 +107,21 @@ impl WrappedLine { origin: Point, line_height: Pixels, align: TextAlign, + bounds: Option>, window: &mut Window, cx: &mut App, ) -> Result<()> { + let align_width = match bounds { + Some(bounds) => Some(bounds.size.width), + None => self.layout.wrap_width, + }; + paint_line( origin, &self.layout.unwrapped_layout, line_height, align, - self.layout.wrap_width, + align_width, &self.decoration_runs, &self.wrap_boundaries, window, @@ -222,7 +228,7 @@ fn paint_line( glyph_origin.x = aligned_origin_x( origin, align_width.unwrap_or(layout.width), - prev_glyph_position.x, + glyph.position.x, &align, layout, wraps.peek(), @@ -426,17 +432,7 @@ fn aligned_origin_x( wrap_boundary: Option<&&WrapBoundary>, ) -> Pixels { let end_of_line = if let Some(WrapBoundary { run_ix, glyph_ix }) = wrap_boundary { - if layout.runs[*run_ix].glyphs.len() == glyph_ix + 1 { - // Next glyph is in next run - layout - .runs - .get(run_ix + 1) - .and_then(|run| run.glyphs.first()) - .map_or(layout.width, |glyph| glyph.position.x) - } else { - // Get next glyph - layout.runs[*run_ix].glyphs[*glyph_ix + 1].position.x - } + layout.runs[*run_ix].glyphs[*glyph_ix].position.x } else { layout.width };