Repository navigation
feat(text): native justification, min-content width on request, and textFeatures() - #16
Merged
Merged
Conversation
… does, `layoutMetrics(handle, { minWidth: false })` leaves the min-content width to `layoutMinWidth`, and `textFeatures()` says what a layout takes — where a caller justified each paragraph by spacing its words itself, in three layouts, and every layout ran the line breaker a second time for a width nobody asked for
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sidorares
added a commit
to sidorares/react-x11
that referenced
this pull request
Oct 4, 2026
…ped one laid out once and only as far as its cap, and a layout's min-content width asked for when it is read — Zen Garden 001's resize frames from 59.7ms to 15.3ms at the median, 005's from 99.5ms to 58.6ms - `justifies` is `'rest'` where the bridge says it justifies (`textFeatures`, windowkit/win32#16): DirectWrite sets every line but a paragraph's last to fill its width, which is ntk's `justify: true`, and the engine passes that mode on. <Html> justified each paragraph on this engine by spacing its words itself, three layouts each. - A capped paragraph is laid out as a prefix long enough to reach past its cap (`_prefixLaidOut`), and its first lines kept and drawn clipped to them (`_keep`), where it was laid out whole and then again cut. <Html> lays a paragraph beside a float out a line at a time, each line `maxLines: 1` over the rest of the paragraph, so a paragraph cost the square of its length. - `layoutMetrics` is asked to leave out the min-content width, which the `minWidth` getter asks for the first time it is read. Measured dragging each window from 1180px to a quarter and back in 8px steps, on Windows 11. Co-Authored-By: Claude Opus 5.5 <[email protected]>
sidorares
added a commit
to sidorares/react-x11
that referenced
this pull request
Oct 4, 2026
…ped one laid out once and only as far as its cap, and a layout's min-content width asked for when it is read — Zen Garden 001's resize frames from 59.7ms to 15.3ms at the median, 005's from 99.5ms to 58.6ms (#878) - `justifies` is `'rest'` where the bridge says it justifies (`textFeatures`, windowkit/win32#16): DirectWrite sets every line but a paragraph's last to fill its width, which is ntk's `justify: true`, and the engine passes that mode on. <Html> justified each paragraph on this engine by spacing its words itself, three layouts each. - A capped paragraph is laid out as a prefix long enough to reach past its cap (`_prefixLaidOut`), and its first lines kept and drawn clipped to them (`_keep`), where it was laid out whole and then again cut. <Html> lays a paragraph beside a float out a line at a time, each line `maxLines: 1` over the rest of the paragraph, so a paragraph cost the square of its length. - `layoutMetrics` is asked to leave out the min-content width, which the `minWidth` getter asks for the first time it is read. Measured dragging each window from 1180px to a quarter and back in 8px steps, on Windows 11. Co-authored-by: Claude Opus 5.5 <[email protected]>
sidorares
added a commit
to sidorares/react-x11
that referenced
this pull request
Oct 4, 2026
…ce names, font widths, letter spacing, OpenType features, x-heights and DirectWrite's justification (#879) The range admitted 0.0.7 alone (a caret on 0.0.x is exact), so what #874 asks the bridge for was answered by none: no link showed the hand on Windows, Arial Black and Segoe UI Light fell back to the default face, a `letter-spacing` was set tight and an `ex` had no face to be measured in. 0.0.8 (windowkit/win32#14) and 0.0.9 (windowkit/win32#16, the justification and the min-content width on request #878 switches on). Co-authored-by: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is performance work for react-x11's
<Html>on Windows, measured with a Zen Garden page whose window is dragged from 1180 px to a quarter of that and back.justify: trueonlayoutCreatesetsDWRITE_TEXT_ALIGNMENT_JUSTIFIED: every line but a paragraph's last fills the width at its word separators. Until now<Html>justified a paragraph by giving every space its own span and laying it out again with letter spacing, three layouts each time. On Zen Garden 001, justified paragraphs were 57% of a resize frame.layoutMetrics(handle, { minWidth: false })skipsDetermineMinWidth, andlayoutMinWidth(handle)answers it when someone actually asks. Only yoga's floors pass needs it, and a layout made to be drawn never does.textFeatures()returns{ justify: true, lazyMinWidth: true }, so react-x11 can ask instead of keying on a version, which also coversWINDOWKIT_WIN32_PATHbuilds.With the react-x11 half (the core PR that follows), Zen Garden 001's resize frame goes from a 59.7 ms median to 15.3 ms, and its layout share from 53 ms to 9 ms.
test/text.js:textFeatures; a justified column's lines fill the width while its last line stays as laid out, and justifying moves no break;minWidthis left out when asked andlayoutMinWidthgives the same number.npm run test:unitandtest:windowpass on Windows 11.🤖 Generated with Claude Code