Skip to content

Commit

Permalink
Hang trailing whitespace before explicit newline
Browse files Browse the repository at this point in the history
  • Loading branch information
wfdewith committed Feb 17, 2025
1 parent f435705 commit 29e479e
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 17 deletions.
29 changes: 22 additions & 7 deletions parley/src/layout/line/greedy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,14 +535,29 @@ impl<'a, B: Brush> BreakLines<'a, B> {
line.metrics.trailing_whitespace = run
.filter(|item| item.is_text_run())
.and_then(|run| {
let cluster = if self.layout.is_rtl() {
self.layout.data.clusters[run.cluster_range.clone()].first()
if self.layout.is_rtl() {
// An RTL layout that has a line that ends with a space followed by a
// forced line break will always have a separate run that looks like:
// [" ", "\n"]. This means that the first cluster of a run with trailing
// white space is always a space, regardless of whether the forced line
// break follows, so we don't have to check for forced line breaks
// explicitly.
self.layout.data.clusters[run.cluster_range.clone()]
.first()
.filter(|cluster| cluster.info.whitespace().is_space_or_nbsp())
.map(|cluster| cluster.advance)
} else {
self.layout.data.clusters[run.cluster_range.clone()].last()
};
cluster
.filter(|cluster| cluster.info.whitespace().is_space_or_nbsp())
.map(|cluster| cluster.advance)
match &self.layout.data.clusters[run.cluster_range.clone()] {
[.., a, b]
if a.info.whitespace().is_space_or_nbsp()
&& b.info.whitespace() == Whitespace::Newline =>
{
Some(a.advance + b.advance)
}
[.., a] if a.info.whitespace().is_space_or_nbsp() => Some(a.advance),
_ => None,
}
}
})
.unwrap_or(0.0);

Expand Down
52 changes: 42 additions & 10 deletions parley/src/tests/test_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,50 @@ fn full_width_inbox() {
fn trailing_whitespace() {
let mut env = testenv!();

let text = "AAA BBB";
let mut builder = env.ranged_builder(text);
let mut layout = builder.build(text);
layout.break_all_lines(Some(45.));
layout.align(None, Alignment::Start, false);
{
let text = "AAA BBB";
let mut builder = env.ranged_builder(text);
let mut layout = builder.build(text);
layout.break_all_lines(Some(45.));
layout.align(None, Alignment::Start, false);

assert!(
layout.width() < layout.full_width(),
"Trailing whitespace should cause a difference between width and full_width"
);
env.with_name("soft_wrap").check_layout_snapshot(&layout);
}

env.check_layout_snapshot(&layout);
{
let text = "AAA \nBBB";
let mut builder = env.ranged_builder(text);
let mut layout = builder.build(text);
layout.break_all_lines(None);
layout.align(None, Alignment::Start, false);

env.with_name("hard_wrap").check_layout_snapshot(&layout);
}
}

#[test]
fn trailing_whitespace_rtl() {
let mut env = testenv!();

{
let text = "بببب ااااا";
let mut builder = env.ranged_builder(text);
let mut layout = builder.build(text);
layout.break_all_lines(Some(45.));
layout.align(None, Alignment::Start, false);

env.with_name("soft_wrap").check_layout_snapshot(&layout);
}

{
let text = "بببب \nااااا";
let mut builder = env.ranged_builder(text);
let mut layout = builder.build(text);
layout.break_all_lines(None);
layout.align(None, Alignment::Start, false);

env.with_name("hard_wrap").check_layout_snapshot(&layout);
}
}

#[test]
Expand Down
3 changes: 3 additions & 0 deletions parley/tests/snapshots/trailing_whitespace-soft_wrap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions parley/tests/snapshots/trailing_whitespace_rtl-hard_wrap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions parley/tests/snapshots/trailing_whitespace_rtl-soft_wrap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 29e479e

Please sign in to comment.