Skip to content

Text break Improvements - #955

Closed
nat3Github wants to merge 5 commits into
david-vanderson:mainfrom
nat3Github:text-break
Closed

Text break Improvements#955
nat3Github wants to merge 5 commits into
david-vanderson:mainfrom
nat3Github:text-break

Conversation

@nat3Github

Copy link
Copy Markdown
Collaborator
  • word breaking: break on hyphen/slash in addition to space, and collapse trailing whitespace at wrap points so the next line doesn't start with leading spaces.
  • chines-japanese-korean-aware keep-with punctuation: don't start a wrapped line with closing punctuation (、。」) or end one with opening punctuation (「(), matching how text is conventionally wrapped.
  • test against a subset of Unicode's LineBreakTest.txt

Break on hyphen/slash in addition to space (matching browser convention),
and collapse trailing whitespace runs at a break point so the next line
doesn't start with leading whitespace.
When no space/hyphen/slash break point exists (the common case for CJK,
which has no interword spacing), the width cutoff already breaks between
any two codepoints. Add keep-with rules so that break doesn't start the
next line with closing punctuation (、。」 etc.) or end the current line
with opening punctuation (「( etc.).
Curated subset of Unicode's public-domain LineBreakTest.txt (real test
lines, hand-picked to cover the classes dvui's break rules support:
whitespace, hyphen, and CJK opening/closing punctuation) referenced via
@embedfile in the test file. Add legalBreakBefore(), a pure
boundary-legality predicate built from the same isCjkClosingPunct /
isCjkOpeningPunct helpers the real width-cutoff algorithm uses, so the
test stays in sync with production logic by construction. Boundaries
outside dvui's supported classes (e.g. plain letter-letter, where dvui
deliberately breaks mid-word as a fallback, unlike strict UAX david-vanderson#14) are
filtered out rather than asserted on.
CJK brackets are unambiguous glyphs (always open or always close), but
Western quotation marks aren't: " is closing in German but opening in
English, and „ (German opening low quote) wasn't handled at all. Rather
than guessing a direction, treat quotation marks as a separate class
with a symmetric no-break rule on both sides, matching UAX david-vanderson#14's
LB19/LB19a. Removes the previously-wrong '/'" from the CJK
opening/closing sets and adds isQuotationMark() instead.

Oracle test extended with two more verbatim LineBreakTest.txt lines
covering both directions of the rule.
@nat3Github

nat3Github commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

note: whats still missing is correct breaking behavior for emojis glyphs. i have that in a seperate branch but it's not really relevant currently.

@nat3Github

nat3Github commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

edit:
@ reviewers: closing this PR, since i am working on a much bigger / broader solution to font engine related issues.

my verdict is that all font related issues in dvui (arabic/asian lang support, correct shaping, font discovery, bidi, text breaking, styling, var fonts, emoji fonts) cover such an ambious spectrum that it would be more efficient combining effort and outsourcing this into a seperate library.
the alternative is adding it piece by piece causing a lot of churn, managing overhead and have low locality of behavior.

@nat3Github nat3Github closed this Aug 19, 2026
@david-vanderson

Copy link
Copy Markdown
Owner

Sounds good. I am hoping that kb_text_shape (see #666) gives us shaping, bidi, breaking, and part of emoji support, but haven't gotten that far yet.

@nat3Github

Copy link
Copy Markdown
Collaborator Author

i am working on a lib with similar scope to kb_text_shape but its a bit more ambitious, will try to integerate / co develop with dvui when its ready, i think it will solve a lot of issues

@david-vanderson

Copy link
Copy Markdown
Owner

i am working on a lib with similar scope to kb_text_shape but its a bit more ambitious, will try to integerate / co develop with dvui when its ready, i think it will solve a lot of issues

Sounds awesome!

One thing I've been trying to wrap my head around is how to achieve the current dvui textSizeEx semantics. We want to pass a large amount of text, but only measure/layout until we get to a max width (either for soft line wrap or to find where the mouse click was). This is easy currently, but I'm not sure how to do it when adding another byte can shorten the total width (either a ligature or some other combination).

kb_text_shape doesn't have that kind of api - you have to pass all the bytes up front (unless I'm totally missing something).

As you are investigating this, any information on how to do this in a streaming fashion would be super useful!

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.

2 participants