Repository navigation
M7: Every-line Composer for ragged text - #587
Merged
bflatastic merged 1 commit intoOct 8, 2026
Merged
Conversation
Illustrator's Every-line Composer balances the breaks of the whole
paragraph for left/centre/right aligned text too, not only justified
text. VectorCraft only composed justified area text; ragged text was
always broken greedily.
- Model: ParaStyle.composer (vectorcraft_doc::Composer, re-exported by
vectorcraft-text), Every-line by default like Illustrator, saved only
when Single-line. layout() reads it from the object;
LayoutOptions.composer is now an Option override for tests.
- Composer: the justified gate is gone. Ragged lines never shrink (a
line that doesn't fit ends the node), badness is 100*r^3 with r = the
line's leftover space over a rag zone of 1/6 of the width (finite for
lines without spaces); the last line is free unless shorter than 1/3
of the width (measured in zones of 1/3), so a lone short word on the
last line pulls a word down. Hyphens cost 25 in ragged text (50 in
justified). Knuth-Plass fitness classes with adjacency demerits
(justified 10000, ragged 1000). Lines past the last width change
share one node key, active nodes are capped (4096) and paragraphs
over 200k glyphs break single-line, so work stays bounded; ragged
tries a tolerance of one rag zone, then any fitting breaks, then
falls back to greedy.
- text.setFormat {composer: "singleLine"|"everyLine"}; the Paragraph
panel menu's composer items work with a check mark (Reset Panel goes
back to Every-line).
- Tests: ragged Every-line moves "or" down in "Destroy all creatures
with toughness X or less." where greedy leaves "less." alone; the rag
of long paragraphs is no worse than greedy (sum of squared leftover
and of neighbour differences); Single-line is greedy; the 10k-char
layout budget covers ragged text; command test with undo; native
format round trip (rich_session's text is now Single-line).
No existing test needed changing: the justified tests and
hyphenated_layout_adds_hyphens (ragged, now Every-line) still pass.
Auto alignment (start of the paragraph direction) is ragged; a wrapped
line's Mojikumi flush opening bracket gives its half em back to the
composer, as in the line loop; tests cover Auto in both directions.
Layout of 10k chars, release: justified Every-line 5.6 ms, ragged
Every-line 5.8 ms, ragged Single-line 4.8 ms.
Haven-King
force-pushed
the
feat/text-engine/text-composer-ragged
branch
from
October 8, 2026 21:05
85aabf2 to
d2aad22
Compare
Member
|
Merged, thank you @Haven-King! The Every-line Composer for ragged text is a real typographic upgrade. The rag-zone badness, the free-unless-short last line, cheaper hyphens in ragged text and fitness-class demerits are all sensible choices, the work bound and greedy fallback keep it safe on huge paragraphs, and the Paragraph panel's composer items finally do something. I checked it with the CLI: a 14 pt left-aligned paragraph at 150 pt wide breaks into a visibly more even rag than Single-line, and at other widths both agree. One thing I flagged in the landing notes: since a missing |
This was referenced Oct 8, 2026
Haven-King
pushed a commit
to Haven-King/vectorcraft
that referenced
this pull request
Oct 8, 2026
…e rich fixture storytold#587 and storytold#600 landed together: the fixture's new area type (Every-line, the default) is a second text object the composer test now sees. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
The Every-line Composer now breaks ragged (left, centre, right and auto aligned) text as well as justified text, and each text object chooses Single-line or Every-line (
ParaStyle.composer, Every-line by default as in Illustrator).What and why
Illustrator's Every-line Composer balances line breaks over the whole paragraph for ragged text too: it will move a short word down to the next line, even when it fits, to avoid a lone word on the last line and an uneven rag. VectorCraft only composed justified area text, so ragged text always broke greedily. The composer choice wasn't stored, and the Paragraph panel's composer menu items were disabled stubs.
ParaStyle.composer(vectorcraft_doc::Composer, re-exported by vectorcraft-text). It's saved only when Single-line, so older files read as Every-line.LayoutOptions.composerbecomes anOptionoverride for tests.100·r³, whereris the line's leftover space over a rag zone of 1/6 of the width.text.setFormat {composer: "singleLine"|"everyLine"}. The Paragraph panel menu items work and show a check mark; Reset Panel returns to Every-line.How it was tested
crates/text/src/tests_typo.rs:every_line_composer_balances_ragged_lines: a word that greedy breaking leaves alone on the last line gets company (Every-line moves the word before it down), in left, centre, right, auto and right-to-left text, also with Standard burasagari.every_line_composer_evens_the_rag: no worse than greedy on leftover space or on neighbouring line differences; every character placed.single_line_composer_is_greedy.tests_panelcmds.rs); native format round trip (native_v3.rs, and therich_sessionfixture uses Single-line).Checklist
cargo xtask cipasses (fmt, clippy, tests, assets, brands, layers, wasm). Run on 85aabf2: fmt, clippy, assets, brands, layers and wasm pass; the test step fails. The only failing test iscmd::typecmd::area_tests::leading_model_is_set_per_paragraph_and_saved_only_when_top_to_top, an upstream test that fails the same way onmain(it depends on the machine's CJK font).unwrap(),expect(),panic!,unreachable!,todo!orunimplemented!outside tests, and no unchecked indexing on data from files, parameters ormessages. Errors are returned as
Resultand shown to the user(why and how). Clippy's no-panic lints pass on 85aabf2.
ASSETS.md(no new assets).