Detailed changes
@@ -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<Self>) -> 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);
+ });
+}
@@ -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 {
@@ -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;
}
}
@@ -107,15 +107,21 @@ impl WrappedLine {
origin: Point<Pixels>,
line_height: Pixels,
align: TextAlign,
+ bounds: Option<Bounds<Pixels>>,
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
};