mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 07:46:07 +00:00
Type on a path: overflowing right-to-left type shows the longest start that fits
Right-to-left type on a path that overflows searched for the start of its text that fits with a binary search, which assumed that a longer start never fits once a shorter one does not. A letter tracked to a negative advance breaks that: with steps of 6, 6, -3 and 6 points in a 10 point span, the first three letters fit while the first two do not, and the search showed only the first letter. - Without hanging punctuation, and with no spacing or on a path of one straight segment, every start is measured in O(n log n): each glyph keeps its place in the whole text's visual order, except the trailing whitespace and controls that UAX #9 rule L1 sets to the paragraph's level. - With hanging punctuation, or spacing on a curve, when a letter has a negative advance, a start is a candidate only when its glyphs, in its own visual order and each at the least step it can take, reach no farther than the path's length. This lower bound holds with negative advances. - At most 32 candidates are arranged from the longest. When none of them fits, a binary search over the rest shows a start that fits, which is not always the longest. - With hanging punctuation, or spacing on a curve, text with no negative advance keeps the binary search. Right-aligned and centered type on a curve with Spacing was placed using the width its glyphs have at the start bracket, while the steps were measured where the line was placed, so a line that fits could end past the end bracket and lose glyphs. It is now placed using the width of the steps it has where it is placed.
This commit is contained in:
@@ -1313,6 +1313,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
The frames of threaded text share one writing direction: Type › Type Orientation (`type.orientation.vertical`, `type.orientation.horizontal`) in one frame sets every frame, threading frames gives the thread its first frame's direction, frames taken out of a thread keep theirs, and the story flows through every frame in the thread's direction.
|
||||
Type › Optical Margin Alignment (`type.opticalMarginAlignment`) hangs the punctuation and letter edges at the ends of a type object's lines outside its margins: at the left of left-aligned lines, at the right of right-aligned lines, and at both ends of centered and justified lines, in point and area type of left-to-right paragraphs. Quotation marks, hyphens, full stops and commas hang wholly; asterisks, tildes, ellipses, en and em dashes, colons and semicolons hang by half; and A, V, W, Y, v, w and y hang by a tenth of their width. It is off by default and saved with the type object. Justification's Glyph Scaling leaves the glyphs that hang at their width, so they hang exactly their share, and Standard burasagari counts what hangs at a line's start as room before hanging a comma; `crates/text/src/tests/hang.rs` checks whole paragraphs with both composers, ragged, centred and justified, with Line-end Punctuation Half Width and bidirectional lines.
|
||||
Optical Margin Alignment and Roman Hanging Punctuation hang right-to-left paragraphs of point and area type, and type on a path whose first paragraph runs right to left, too. Auto aligns a right-to-left line at its right, or at the end bracket of a path, so it hangs there. A right-to-left line is read from right to left: where it hangs at its left margin, `."` ending it hangs both glyphs.
|
||||
Type on a path with right-to-left text that does not fit shows the longest start of its text whose glyphs fit, also where tracking gives a letter a negative advance and a shorter start does not fit; the rest overflows or flows to the next threaded object (VectorCraft's own rule). Without hanging punctuation, and on a straight path or with no spacing, every start is measured without arranging it on the path again. With hanging punctuation, or spacing on a curve, when a letter has a negative advance, at most 32 of the starts that could fit are arranged one by one from the longest; when none of them fits, a binary search over the rest shows a start that fits, which is not always the longest (`overflowing_rtl_type_on_a_path_shows_the_longest_start_that_fits`, `the_longest_rtl_start_on_a_path_is_found_without_arranging_each_start`, `the_longest_rtl_start_on_a_path_is_the_one_each_start_gives` and `rtl_type_on_a_curve_whose_letters_take_the_line_back_is_arranged_a_bounded_number_of_times` in `crates/text/src/tests/bidi.rs`). Right-aligned and centered type on a curve with Spacing is placed by what its glyphs take where the line ends up, so text that fits is not cut off at the end bracket (`on_path_aligned_spaced_text_that_fits_shows_whole` in `crates/text/src/tests.rs`).
|
||||
The Paragraph panel menu's Kinsoku Shori Type (`text.setFormat {kinsokuType}`, with the East Asian options) picks Push In First, Push Out First or Push Out Only for each paragraph: a character the Kinsoku Set keeps off a line's start or end is set on the line, with the line's gaps next to CJK characters closed by at most a tenth of an em each to fit, or moved to the next line with the character before it. Push Out First pushes in only when pushing out would leave the line more than an em short. Push Out Only is the default, the setting is saved only when it is not, and paragraph styles carry it.
|
||||
The Paragraph panel menu's Bunri-Kinshi (`text.setFormat {bunriKinshi}`, with the East Asian options, and the East Asian Composition Settings section of Paragraph Style Options) keeps inseparable pairs on one line in each paragraph that has it: two em dashes, two ellipses, two two-dot leaders and the two halves of a vertical kana repeat mark (the pairs of W3C JLREQ's class cl-08, VectorCraft's set). Both composers and vertical type follow it, and justification adds no space inside a pair. It works with a Kinsoku Set only, is off by default and is saved only when on; editing the set of pairs is not available.
|
||||
The Paragraph panel menu's Korean Line Break Anywhere (`text.setFormat {koreanLineBreakAnywhere}`, with the East Asian options, and the East Asian Composition Settings section of Paragraph Style Options) sets for each paragraph whether a line may break between any two Hangul syllables. When it is off, a word that contains Hangul breaks only at its spaces and after punctuation, or where the word is wider than the line, and takes no hyphen. New type has it off; paragraphs saved before the option read as on, so their lines do not move.
|
||||
|
||||
Reference in New Issue
Block a user