mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 10:47:11 -06:00
On a curved path each glyph was placed rigidly (turned to the tangent at
its middle), so its baseline ends stood off the curve and neighbours
turned by different angles: in scripts whose letters join, every join
opened into a notch. Measured with Arial on circles: at 29 pt on a
radius of 110 pt, 0.64 pt at the baseline and 1.24 pt at the height of
the joining stroke (a quarter of the size); 14.7 pt at 72 pt on a radius
of 60. Placing glyphs on the chord alone closes the baseline but leaves
about h (a_i + a_{i+1}) / 2R above it (0.71 pt here), so joined glyphs
are bent instead.
- Shaping marks each glyph of a segment whose script joins (Arabic,
Syriac, N'Ko, Mongolian, Adlam and the other cursive scripts), by the
segment's script, so a word bends as a whole.
- With the Rainbow effect such a glyph's outline is mapped point by
point: pen space (x, y) -> P(s + x step/advance) + (y + rise) N there,
each segment cut into pieces short enough for 0.01 pt (capped). A
glyph the path doesn't turn under stays exactly as it was; Skew, 3D
Ribbon, Stair Step and Gravity, vertical type, inline art and colour
glyphs are unchanged. `PositionedGlyph::bend` records it; `xf` stays
the straight glyph for the caret, hit testing and tools.
- PDF export draws bent glyphs as outlines and writes them again as
invisible text where they stand, so they can be selected, searched
and copied. SVG export outlines them (right-to-left type already was),
never as a <textPath>, and labels the group with its text
(role="img", aria-label) for screen readers and search.
Tests (crates/text/src/tests_path_joins.rs; installed Arabic font, skip
without one): the gap at the baseline and at join height is <= 0.01 pt
at 12, 29 and 72 pt on radii 60, 110 and 300, on both sides of the
path, with finite outlines; Latin on a curve and joined type on a
straight path are byte-for-byte what they were; the chord-only
prediction is checked.
vectorcraft-cli perf (load average 43 before, 34 after: not trustworthy;
the synthetic document has no type on a path, so bending doesn't run):
render fit 113.8 -> 132.7 ms, pan 115.5 -> 140.0 ms, 400% 32.9 -> 43.3
ms, hit test 1.36 -> 1.59 ms, save 81.5 -> 88.2 ms, open 306 -> 401 ms,
SVG 426 -> 439 ms, Pathfinder 93.7 -> 85.5 ms, handle drag 5.5 -> 6.7
ms, segment drag 5.1 -> 6.7 ms.