Repository navigation
Type: a burasagari mark hangs only where it is drawn at the line's right end - #7810
Merged
bflatastic merged 6 commits intoNov 15, 2026
Conversation
…e frame A right-to-left paragraph draws a comma or full stop inside its line, but the breaker still kept an overflowing mark on the line as if it hung, so the line was drawn past the frame. The breaker now ends such a line at a break where it fits with the mark. In a left-to-right line with right-to-left text and a tab, the breaker hung an overflowing mark without measuring the line as drawn. It now hangs the mark only when the mark is drawn at the line's right end and the line before it fits as drawn; otherwise the line ends at the latest legal break that fits as drawn.
On a tabbed line measured as drawn, a full stop or comma now hangs when it is last in the visual order of the line's levels (UAX storytold#9 L2, with each tab and the spaces before it at the paragraph's level), whatever its own level. A mark at level 2, or a lone right-to-left mark after left-to-right text, hangs again; a mark inside a right-to-left run still ends the line at an earlier break. A mark that No Break or Bunri-Kinshi keeps with the characters after it no longer ends the line as if it hung: the line would end with those characters, which are drawn inside it, so it ends at an earlier break.
Contributor
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 35 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
Member
|
Merged, thanks @dotCooCoo! It passed its CI checks. |
Nissaar
pushed a commit
to Nissaar/vectorcraft
that referenced
this pull request
Nov 15, 2026
storytold#7814 made SubPath::anchors an Anchors, and storytold#7810's seam fills, merged in the same batch, passed it to SubPath::new, which takes a Vec, so vectorcraft-trace doesn't compile on main. A closed subpath whose every segment is marked is its own run: clone it.
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.
What and why
The help page describes Burasagari as letting single-byte and double-byte periods and commas fall outside the paragraph bounding box, and its Regular setting as hanging that punctuation without pushing ragged lines out to the edge of the box (the help page). In three cases the line breaker kept an overflowing mark on the line as if it hung, but the line was not drawn that way:
prepare_line_geometry(crates/text/src/layout/flow.rs) never hangs the mark, so the mark was drawn inside the line at full width and the line ran past the frame, with or without a tab.break_line(crates/text/src/layout/breaking.rs) skipped the drawn-width check. The line before the mark could be too wide as drawn, and the mark could be drawn inside the line instead of at its right end.Changes:
place_flow_linepasses Burasagari None tobreak_linefor a right-to-left paragraph, so the line ends at a break where it fits with the mark.break_linehangs a mark only when the mark is all the characters kept together at that break.break_linehangs a mark only when the newdrawn_lastfinds the mark's cluster last in the line's visual order (the levels reordered as UAX Raster export: refuse sizes the renderer can't produce instead of crashing #9 L2, with each tab and the spaces before it at the paragraph's level, as the drawer reorders them), the line before the mark has no line-end trim on its last glyph, and it fits as drawn. Otherwise the line ends at the latest legal break that fits as drawn.push_inalready returns nothing for a line with a tab and right-to-left text, so Push In First cannot end such a line past the measure; a test now covers that.docs/target-app-parity.mdhas one line for the change next to the Line-end Punctuation Half Width entry.The help page does not say which side a mark hangs on in right-to-left text or how hanging works with tabs; both rules above are VectorCraft's own. Lines that change: a right-to-left paragraph, a tabbed line with right-to-left text, and a mark kept with the next character by No Break or Bunri-Kinshi now break earlier instead of drawing past the frame. Other burasagari lines, Force included, break as before. No user-visible string changed.
How it was tested
New tests in
vectorcraft-text:layout::wrapping_tests::a_tabbed_burasagari_mark_hangs_only_at_the_drawn_end_of_a_fitting_line: on a tabbed line with right-to-left text, 。 hangs when it is drawn at the right end of a line that fits (also at level 2 after a left-to-right glyph, and alone at level 1 after one), and the line ends before 漢 when the line before 。 is too wide as drawn, fits only with 漢 trimmed, or 。 is drawn inside a right-to-left run. Fails without the change.layout::wrapping_tests::a_burasagari_mark_kept_with_the_next_character_does_not_hang: 。 alone hangs, and with No Break on 。漢 the line ends at an earlier break. Fails without the change.tests::hang::right_to_left_burasagari_keeps_the_line_inside_the_frame: a right-to-left paragraph in a frame narrower than the whole line by half the stop breaks into two lines, and every glyph other than spaces stays inside the frame. Fails without the change.layout::wrapping_tests::push_in_leaves_a_tabbed_right_to_left_line_to_push_out: Push In First, Push Out First and Push Out Only all push the closing bracket out on a tabbed line with right-to-left text, where the same widths without them push it in. It covers existing behavior and passes without the change.The visual-order check and the check that the mark is alone were each removed from the final
break_linecode, and a test failed each time.Focused checks on the final tree,
mainatdf984b2merged:cargo fmt --all -- --checkcargo clippy -p vectorcraft-text --all-targets -- -D warningscargo check --workspace --testscargo test -p vectorcraft-text --libfiltered toburasagari,wrapping_tests::,hang::,push_in_leaves_a_tabbedandno_break: 55 passed, 0 failed.cargo xtask brands,layers(30 crates) andassets(337 files)cargo xtask ciruns in this pull request's CI.Checklist
cargo xtask cipasses (fmt, clippy, tests, assets, brands, layers, wasm).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).
ASSETS.md.