[DO NOT MERGE] Hang trailing whitespace (conditionally for last line in paragraph) - #3
[DO NOT MERGE] Hang trailing whitespace (conditionally for last line in paragraph)#3conor-93 wants to merge 6 commits into
Conversation
…t of overflow). Add visreg tests for this
djmcnab-canva
left a comment
There was a problem hiding this comment.
This looks pretty good. I definitely understand how this resolves.
One question: Did you evaluate using linebender#485 instead? In my reading, that looks like it solves the same issues with very similar approaches, but also handles the hanging clusters issue.
| // Hanging whitespace is an alignment/positioning concern, orthogonal to text | ||
| // directionality. The RTL handling here doesn't interact with bidi reordering: | ||
| // it simply shifts the line's origin so that hung trailing whitespace (which | ||
| // sits at the *start* edge in visual order for RTL) overflows into the start | ||
| // margin rather than displacing visible content. |
There was a problem hiding this comment.
This smells like a Claude artifact to me. I'd lean towards reverting this section.
There was a problem hiding this comment.
I actually included this intentionally while I was working through the solution, as I was trying to figure out the implication the change would have on text directionality. Revisiting it now, it seems a bit overbearing, and I prefer the old comment.
| // TODO: can this be hoisted out of the conditional? | ||
| self.state.cluster_idx += 1; |
There was a problem hiding this comment.
I'm slightly surprised that this actually gets all the remaining space clusters in the line; my impression was previously that the reason we were seeing the wrapping behaviour was because this is +1. That is, do we not need to consume clusters until we reach the last cluster on the line? We might need to do more digging
There was a problem hiding this comment.
You're right, and though this was technically out of scope of this PR, I got this working (which correctly hangs leading whitespace, which is a separate issue we've been facing) by taking some inspiration from linebender#485 (see my main comment).
There was a problem hiding this comment.
It isn't clear to me why this snapshot has been regenerated. Do you have that clear?
I can't see any actual changes, so I'm not overly worried.
There was a problem hiding this comment.
Sub-pixel shifting in the horizontal position of "amet" on line two; all else looks the same.
…just a single cluster (+ test demonstrating this bug)
…at a time without ever committing a new line until the contiguous whitespace section ends
Yes, early on when researching this task; it's targeting a different issue: breaking with extra, trailing whitespace would let the trailing whitespace form its own lines, which isn't an issue I'm able to re-create in our application. The PR does achieve some of what we need, though; the main issue is that it doesn't implement conditional vs non-conditional whitespace hanging (i.e. hanging whitespace on all but the final line before a paragraph break, at which point whitespace is preserved up until the visible portion of a line collides with the margin, then it is hung). However, looking at this again with fresh eyes inspired me to simplify the whitespace cluster handling logic in |
|
This looks like the right basic approach. A note that we should probably follow css-text-4 https://www.w3.org/TR/css-text-4/#white-space-phase-2 rather than css-text-3. The actual logic hasn't changed, but the spec has been rewritten in terms of the decomposed |
Latest branch (rebased off parley v11.0) here: linebender/parley@main...conor-93:parley:conor/upstream/withHangingWhitespaceFixes20260625 (removes extra
cluster_idxbump)Implements CSS Text 3 §4.1.2 trailing whitespace hanging behaviour:
These behaviours are forced. This should not be merged as-is, but it could be used as inspiration for implementing configurable CSS
white-space-collapsebehaviours (issue: linebender#619), specifically:WhiteSpaceCollapse::Collapse,WhiteSpaceCollapse::Preserve,WhiteSpaceCollapse::PreserveBreaks,WhiteSpaceCollapse::PreserveSpacesBreakReason::ExplicitorBreakReason::None) linesWhiteSpaceCollapse::PreserveandWhiteSpaceCollapse::PreserveSpaces