Commit Graph
29 Commits
Author SHA1 Message Date
dotCooCoo c94aec3fff Envelopes: type maps from its glyph outline bounds
An envelope mapped type from its laid-out box: ascent to descent for
point type, the frame for area type. The distorted glyphs then filled
less of the envelope than other art does, with room above the capitals
and below the baseline.

The envelope now maps type from the bounds of its glyph outlines,
underlines and strikethroughs when the type is on its own, in groups
and layers, or used as a clipping path. Inline graphics count by their
boxes. Rotated type and type in perspective map from their outlines as
they are drawn. Make with Mesh,
Make with Top Object and Reset with Mesh without Maintain Shape use
those bounds. Type that draws nothing keeps its laid-out box, and so
does type inside any other object, such as a blend, a repeat or a
symbol instance. Shrink Text to Fit type is measured as it is laid out
on the page.

vectorcraft-text's envelope_ink measures the type, and
register_envelope_ink registers it with the document crate. The engine
session, Renderer::new, live evaluation in vectorcraft-effects and the
.ai reader register it. The document crate keeps the measured boxes per
thread, by object and by a hash of the content, and measures again when
the type, the fonts, the hyphenation exceptions or the transform's
scale or rotation change.

This is VectorCraft's own rule. Envelopes of type made in VectorCraft
and in saved files map from the glyph outline bounds instead of the
type's laid-out box, so they redraw differently.
2026-11-08 13:20:19 +07:00
dotCooCoo f42fdf900f Type: layout looks up each style run's face once
Layout kept no record of a run's face, so each paragraph looked up the face
of its first character three times for its line metrics and once more to
shape it. The layout now keeps each run's face the first time it is looked
up and uses it for shaping, for paragraph metrics, for on-path type's empty
line and for the column offset of vertical point type. Glyphs, positions,
bounds and baselines do not change.

A test-only helper lays text out looking every face up at each use, and a
new test requires point, vertical point, area and path type laid out both
ways to match exactly.

The layouts of 5,000 short point type objects take a median of 215 million
CPU cycles of the laying-out thread instead of 236 million in a release
build (11 alternating runs of each build on Windows 11, measured while
other builds were running).
2026-11-08 12:21:32 +07:00
dotCooCoo dbcdbf2466 Open: the first frame uses the layouts the open made for type objects
Opening a document laid out every type object for its bounds and
baselines and threw the layouts away, and the first frame laid the same
objects out again. The open now keeps them, up to 128 MiB, and a frame
takes each one once.

A frame takes a layout only for a text object equal to the one laid out,
and only while the fonts, the system fallback setting and the hyphenation
exceptions are unchanged. When the last frame being drawn ends, the rest
are dropped if a frame took one, and all of them are dropped after eight
frames that take none. A layout with bitmap or color glyphs and a text
object with a gradient are not kept.
2026-11-08 11:42:45 +07:00
ruchirguitar 5bb21cdddf Add hyphenation for eleven Indian languages
Squashed from #5946 onto main.
2026-11-07 05:15:17 +07:00
jayzed80andClaude Opus 5.5 7d465d4fa3 fix(text): a gutter too huge to step past no longer stalls area type layout
Past a gutter of 1e300 a step no longer moves the baseline, so every cell of
a 100 x 100 frame was searched for all MAX_STEPS steps: over 40 s per layout.
AreaOptions::gutter has no limit, so a saved file can do this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 23:04:37 +07:00
jo-quast bddb834231 Part of #394: each run hyphenates in its own language; Default Language sets new type's
Squashed from #2818 onto main.
2026-11-05 12:17:33 +07:00
dotCooCoo befc4b959d SVG export: type with Mojikumi and no Japanese characters is laid out once
To find the characters that justification or Mojikumi moves, SVG export
without Fewer <tspan> Elements laid out every live type object a second
time, as point type with
Mojikumi None and default Justification options, whenever its paragraph
had Mojikumi on. New type gets Line-end Punctuation Half Width, so every
new type object was laid out twice. Mojikumi only spaces Japanese
punctuation and Japanese letters, so type without them lays out the same
either way.

- TextLayout::mojikumi_applies says whether the text or a list marker
  holds a character Mojikumi spaces.
- reader_advances keeps such a paragraph's Mojikumi, and reads the glyphs
  from the layout it was given when the object it would lay out is the
  same; otherwise it lays the object out again as before.

The SVG is unchanged. Exporting 5,000 point type objects takes a median
of 109.4 ms instead of 171.5 ms on Windows 11.
2026-11-05 08:24:33 +07:00
dotCooCoo e0ebc13a2e Type: right-to-left manual kerning keeps whole-point spacing on both sides
With System Layout on or Fractional Widths off, each advance is rounded
to whole points, but a right-to-left character with manual kerning
still moved by the unrounded kerning value. The difference between the
two changed the space after the character before it in reading order.
The character now moves by the change the kerning makes to its rounded
advance, so only the space before the next character changes.
2026-11-04 22:29:14 +07:00
dotCooCoo 63ac1395fd Type: control Kashidas for selected characters 2026-11-03 23:29:52 +07:00
dotCooCoo 2b63bf1b67 Type: keep composition spacing along the line when characters rotate 2026-11-03 21:38:02 +07:00
dotCooCoo e1ea0ecad1 Type: the caret, a click and the arrow keys reach the characters inside a ligature
Squashed from #5225 onto main.
2026-11-03 16:38:36 +07:00
dotCooCoo e13cf73ae0 Type: Tate-chu-yoko Settings move a block up, down, left or right
Squashed from #5206 onto main.
2026-11-02 14:32:59 +07:00
dotCooCoo 0895eccfe1 Type: right-to-left manual kerning moves a rotated character along the line
Right-to-left manual kerning was added to the glyph's offset, which
Character Rotation turns, so a rotated character with kerning moved
across the line (up at 90 degrees) instead of away from the next
character in reading order. The shift is now applied to the pen
position along the baseline, outside the rotation, and the rotation
turns the glyph about that moved pen position.
2026-11-02 14:32:54 +07:00
dotCooCoo beb89ebec4 .ai import: vertical type keeps its orientation and Tate-chu-yoko runs
Squashed from #5086 onto main.
2026-11-02 12:04:08 +07:00
dotCooCoo f46427167c .ai import: area type keeps its rows, columns, gutters and first baseline
Area type made from the editing data's text document came in with one
row, one column, the 18 pt gutter and the Ascent first baseline,
whatever its frame kept. Each area frame now keeps its rows and columns,
the gutter between rows and the gutter between columns, and its first
baseline (Fixed, Cap Height, Leading or x Height) with its minimum,
scaled with the art's units. Each frame of a thread keeps its own, and a
key that is missing or can't be read leaves that option as it was. A
first baseline the frame keeps is no longer replaced by the fixed one
that matches the file's first line.

AreaOptions gets row_gutter (rowGutter, left out while unset), which
layout spaces rows by; text.areaOptions takes and reports rowGutter, a
gutter given alone sets both, and the Area Type Options dialog shows
Row Gutter.
2026-11-02 12:04:07 +07:00
dotCooCoo 5716a996ab Type: Touch Type moves a character rotated near 90 degrees across its line
Baseline shift now moves a character in the line's frame, outside
Character Rotation, so a positive shift moves a character up from its
line at any rotation, and the character turns about its shifted pen
position. The Touch Type tool splits a drag into its part along the line
(kerning) and its part up from the line (baseline shift) at every
rotation; before, within about 6 degrees of a quarter turn it dropped
the cross-line part.

Characters that already combine a rotation with a baseline shift are
drawn in a new position. Their stored values do not change.

- text: glyph transform order, PositionedGlyph::pivot (the turning
  point), tab leaders in the same order
- tools: Touch Type splits drags against the line's up axis and measures
  rotate-handle turns about the shifted pen position
- engine: text.touchType description; dy is up from the line
- docs: mcp.md Touch Type paragraph, target-app-parity.md progress line
2026-11-01 11:08:57 +07:00
dotCooCoo 427bce12b0 Character: Font Size can measure the cap height, x-height or ICF box
Squashed from #5026 onto main.
2026-11-01 11:08:55 +07:00
dotCooCoo ece78f052f Type: Standard Vertical Roman Alignment stands half-width characters upright in vertical type
Character panel menu > Standard Vertical Roman Alignment, with Show East
Asian Options, is now a check item. It sets a new character attribute,
`standardVerticalRoman` (text.setFormat, text.setRangeStyle), off by
default and saved only when on. In vertical type the marked Latin
letters, digits and other characters that would lie on their side stand
upright one below the other, each in its upright cell. Spaces keep their
width and tate-chu-yoko blocks stay across the column. Horizontal type
keeps the mark and does not change. A combining mark shaped as its own
glyph turns with its letter, in Latin and CJK upright type alike.

Character Style Options labels the Character Alignment row "Character
Alignment" and gives Standard Vertical Roman Alignment its own checkbox.
Reset Panel turns the attribute off. PDF and SVG export place the glyphs
from the layout and need no change.
2026-11-01 08:32:55 +07:00
bflatastic 7d8f1d4e06 Fix #4978: Area Type Options › Text Flow by rows or by columns 2026-11-01 06:11:11 +07:00
bflatastic 513b02233f Align: Align to Glyph Bounds for point and area type (#4231) 2026-10-30 02:01:58 +07:00
bflatastic 084f4f3240 Text: a line ending at the paragraph's start can't underflow 2026-10-29 20:36:07 +07:00
Taha-Mahmoodi 7511f84d5d Layout: end manual tate-chu-yoko at soft return, and use separator metrics for empty continuation line 2026-10-29 20:36:05 +07:00
Taha-Mahmoodi b6df1ef0b1 Type: handle soft return in no-break runs, event modifiers, trailing breaks, and tabs 2026-10-29 20:36:05 +07:00
Taha-Mahmoodi d89031848c Fix #2754: Shift+Enter inserts a soft return (forced line break)
In typography and Illustrator, Shift+Enter inserts a soft return (forced
line break) rather than ending the paragraph. Text wraps to the next line
without applying paragraph-level spacing (space before/after, first-line
indents), list continuation lines keep their parent item without repeating
markers, and justified text does not stretch lines ending with a soft return.

- Forward active modifier keys for Enter in ui-egui shortcuts so the tool
  detects Shift+Enter.
- Type tool inserts U+2028 (LINE SEPARATOR) on Shift+Enter.
- Text shaping and layout treat U+2028 as an invisible zero-advance control
  character, breaking the line in point and area type.
- Paragraph spacing and list markers apply once per paragraph as intended.
2026-10-29 20:36:05 +07:00
dotCooCoo bbf01223cb Snap to Glyph: the x-height guide stays on the glyphs' x-height
Character Rotation turned a glyph's baseline shift and scaling with the glyph, and the Skew path effect slants a glyph's height away from the path's normal, so the x-height guide moved off the glyphs. Each positioned glyph now carries the transform that removes its Character Rotation (PositionedGlyph::unturned), and the guide goes through the glyph's x-height point placed without it, measured across the baseline. Snap to Glyph also takes Smart Guides being on in the tools, as View › Snap to Glyph already does in the engine.
2026-10-29 11:18:38 +07:00
Dylan M. Taylor 86c81f21d2 Restore RTL Mojikumi condition, dropped layout comments and xtask root
- flow.rs: an opening bracket starting a wrapped line is set flush unless the paragraph is
  right to left, as before the split (it had become !vertical, so vertical text with
  LineEndHalf lost the flush and RTL paragraphs gained it). PlacementContext carries rtl.
- flow.rs, ruby.rs: put back the comments the split dropped (JLREQ, burasagari, Optical
  Margin Alignment, kashidas, ruby phases).
- xtask root(): the parent directory, not .../xtask/..
2026-10-28 17:20:12 -04:00
Dylan M. Taylor 0e2815629f refactor(text): split flow and ruby layout phases 2026-10-27 17:47:12 +00:00
aiongg 3d39bbb31e refactor(text): move layout.rs wrapping_tests to layout/wrapping_tests.rs 2026-10-26 22:01:25 +00:00
aiongg a8935c0ada refactor(text): move layout.rs items to layout/{bidi,breaking,driver,flow,on_path,region,ruby,vertical}.rs 2026-10-26 22:01:25 +00:00