Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shaping: (wrapping) make whitespace trim bidi-aware #175

Merged
merged 7 commits into from
Dec 17, 2024

Conversation

whereswaldon
Copy link
Member

Our previous implementation of trimming the whitespace off of the end of wrapped lines assumed that the end was always the final logical run, and that the final glyph within that run was visually last. Neither of these assumptions are true in real-world bidi text. The final logical run may be embedded wtihin the center of the visual line of text, and sometimes the final glyph is the first within a run, rather than the last.

Our previous implementation of trimming the whitespace off of the end of wrapped
lines assumed that the end was always the final logical run, and that the final
glyph within that run was visually last. Neither of these assumptions are true
in real-world bidi text. The final logical run may be embedded wtihin the center
of the visual line of text, and sometimes the final glyph is the first within a
run, rather than the last.

Signed-off-by: Chris Waldon <[email protected]>
Copy link
Contributor

@andydotxyz andydotxyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch. Should there be a test added that shows this combination of items wrapping?

This commit adds a test case that ensures a space is trimmed when it appears
at the end of a line (visually), but not when it occurs within the middle of
a line.

Signed-off-by: Chris Waldon <[email protected]>
@whereswaldon
Copy link
Member Author

@andydotxyz Absolutely there should be; I've added one.

@whereswaldon whereswaldon marked this pull request as draft December 16, 2024 19:41
@whereswaldon
Copy link
Member Author

I hit a weird case with the ordering of runs this generates; I'm going to add more tests and see if I can isolate it. The issue may be in Gio instead of typesetting.

This commit adds a test for visual bidi run ordering and fixes the implementation
to pass it. The test itself is migrated from Gio's codebase, where it has been
verifying this functionality for years. It caught some problems with the new
implementation of this visual ordering algorithm, which are also fixed in this
commit.

Signed-off-by: Chris Waldon <[email protected]>
@whereswaldon
Copy link
Member Author

I've fixed the visual ordering of runs, but as I've been looking into including this version of typesetting into Gio, I've realized there's an additional problem. Our advanceSpaceAware() implementation unconditionally subtracts the width of a trailing space from the advance of a candidate run, but that's only safe to do if the candidate run is the same text direction as the overall paragraph. Otherwise, the space that you're subtracting from the end was not likely to be displayed at the end of the line, and you're artificially shortening the run in the middle of the line.

I think the fix is simple, but making it will require some new tests. I'll try to implement those tomorrow.

Copy link
Contributor

@andydotxyz andydotxyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one, thanks :)

@andydotxyz
Copy link
Contributor

Sorry I read the messages out of order. Will review again later if there are more changes :)

@benoitkugler
Copy link
Contributor

Thanks @whereswaldon ! I guess I had totally overlooked the fact that, although glyphs are in visual order, runs are in logical order (that was nicely pointed out in #29). I'll review your fix more carefully (and try to understand it) tomorrow.

Copy link
Contributor

@benoitkugler benoitkugler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice work, thank you.
I've added a question, and I've also took the liberty to add a minor change, simplifying the 'resolveBidi' function.

shaping/output.go Show resolved Hide resolved
When wrapping lines containing bidi runs, a run that progresses in the
opposite direction from the overall paragraph will have its trailing
whitespace in the middle of the line, not at the end. As such, it isn't
valid to ignore the advance of trailing whitespace for such a run. We
can only safely ignore trailing whitespace when the run is the same
progression as the paragraph.

Signed-off-by: Chris Waldon <[email protected]>
@whereswaldon whereswaldon marked this pull request as ready for review December 17, 2024 14:39
@whereswaldon
Copy link
Member Author

Okay, I believe this is now correct. Gio's tests fail because this space-trimming allows much better wrapping that we previously had, and the test text is actually fitting into fewer lines that it used to, but the wrapping is correct. If @benoitkugler is happy with the space aware advance tweak, I think we can merge this.

@benoitkugler
Copy link
Contributor

Yes, this looks great, thank you Chris. I'll wait on @andydotxyz final review to merge it.

Copy link
Contributor

@andydotxyz andydotxyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good yes - thanks for figuring this all out.
I really need to get the bi-di in Fyne worked on so we can be at similar levels of need for this library :).

@andydotxyz andydotxyz merged commit 202cb31 into main Dec 17, 2024
20 checks passed
@andydotxyz andydotxyz deleted the ckw-fix-trim-bidi branch December 17, 2024 21:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants