Skip to content

Commit 958ba51

Browse files
committed
Fix trailing white space with inline boxes
1 parent d89e0e1 commit 958ba51

File tree

4 files changed

+57
-21
lines changed

4 files changed

+57
-21
lines changed

parley/src/layout/data.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -483,16 +483,23 @@ impl<B: Brush> LayoutData<B> {
483483
}
484484

485485
fn calculate_content_widths(&mut self) {
486+
fn whitespace_advance(cluster: Option<&ClusterData>) -> f32 {
487+
cluster
488+
.filter(|cluster| cluster.info.whitespace().is_space_or_nbsp())
489+
.map_or(0.0, |cluster| cluster.advance)
490+
}
491+
486492
let mut max_width = 0.0;
493+
let mut prev_cluster: Option<&ClusterData> = None;
487494
for item in &self.items {
488495
match item.kind {
489496
LayoutItemKind::TextRun => {
490497
let run = &self.runs[item.index];
491498
let mut min_width = 0.0;
492-
let mut trailing_whitespace = 0.0;
493499
for cluster in &self.clusters[run.cluster_range.clone()] {
494500
let boundary = cluster.info.boundary();
495501
if matches!(boundary, Boundary::Line | Boundary::Mandatory) {
502+
let trailing_whitespace = whitespace_advance(prev_cluster);
496503
self.min_content_width =
497504
self.min_content_width.max(min_width - trailing_whitespace);
498505
min_width = 0.0;
@@ -501,23 +508,22 @@ impl<B: Brush> LayoutData<B> {
501508
}
502509
}
503510
min_width += cluster.advance;
504-
trailing_whitespace = if cluster.info.whitespace().is_space_or_nbsp() {
505-
cluster.advance
506-
} else {
507-
0.0
508-
};
511+
prev_cluster = Some(cluster);
509512
}
513+
let trailing_whitespace = whitespace_advance(prev_cluster);
510514
self.min_content_width =
511515
self.min_content_width.max(min_width - trailing_whitespace);
512-
max_width += run.advance - trailing_whitespace;
516+
max_width += run.advance;
513517
}
514518
LayoutItemKind::InlineBox => {
515519
let ibox = &self.inline_boxes[item.index];
516520
self.min_content_width = self.min_content_width.max(ibox.width);
517521
max_width += ibox.width;
522+
prev_cluster = None;
518523
}
519524
}
520-
self.max_content_width = self.max_content_width.max(max_width);
525+
let trailing_whitespace = whitespace_advance(prev_cluster);
526+
self.max_content_width = self.max_content_width.max(max_width - trailing_whitespace);
521527
}
522528
}
523529
}

parley/src/tests/test_basic.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2024 the Parley Authors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

4-
use crate::{testenv, Alignment, InlineBox};
4+
use crate::{testenv, util::nearly_eq, Alignment, InlineBox};
55

66
#[test]
77
fn plain_multiline_text() {
@@ -150,16 +150,40 @@ fn content_widths() {
150150
fn inbox_content_width() {
151151
let mut env = testenv!();
152152

153-
let text = "Hello world!";
154-
let mut builder = env.builder(text);
155-
builder.push_inline_box(InlineBox {
156-
id: 0,
157-
index: 3,
158-
width: 100.0,
159-
height: 10.0,
160-
});
161-
let mut layout = builder.build(text);
162-
layout.break_all_lines(Some(layout.min_content_width()));
163-
layout.align(None, Alignment::Start, false);
164-
env.check_layout_snapshot(&layout);
153+
{
154+
let text = "Hello world!";
155+
let mut builder = env.builder(text);
156+
builder.push_inline_box(InlineBox {
157+
id: 0,
158+
index: 3,
159+
width: 100.0,
160+
height: 10.0,
161+
});
162+
let mut layout = builder.build(text);
163+
layout.break_all_lines(Some(layout.min_content_width()));
164+
layout.align(None, Alignment::Start, false);
165+
166+
env.with_name("full_width").check_layout_snapshot(&layout);
167+
}
168+
169+
{
170+
let text = "A ";
171+
let mut builder = env.builder(text);
172+
builder.push_inline_box(InlineBox {
173+
id: 0,
174+
index: 2,
175+
width: 10.0,
176+
height: 10.0,
177+
});
178+
let mut layout = builder.build(text);
179+
layout.break_all_lines(Some(layout.max_content_width()));
180+
layout.align(None, Alignment::Start, false);
181+
182+
assert!(
183+
nearly_eq(layout.width(), layout.max_content_width()),
184+
"Layout should be as wide as the max content width"
185+
);
186+
187+
env.with_name("trailing_whitespace").check_layout_snapshot(&layout);
188+
}
165189
}
Loading
Loading

0 commit comments

Comments
 (0)