While a document's composite fonts are lent, type naming a composite font
the document does not define is set as in a missing font, even when the
front document or the document a placed document sits in defines one of
that name. A document that defines no composite font gets an empty scope
too, so a document in the back, a tiled window, a thumbnail or an export
made while another document is in front no longer borrows the front
document's definitions. A temporary document drawn while a document draws
keeps that document's fonts, and type laid out with nothing lent still uses
the registered ones.
- FontDb::composite_font looks only in the latest loan of the database.
- lend_composite_fonts lends an empty set at the top level when the
database holds composite fonts; lend_document_composite_fonts also lends
one inside another loan, for placed documents, back-document measuring
and threaded reflow on open.
- A loan that leaves out a registered font gets its own generation, so
layouts made with that font are not reused under it.
A radial gradient whose circles both have the same negative radius (as a
variable font's instance can give) draws no circle. A glyph painted with
only that gradient was read as no colour glyph, so layout drew its
outline instead. It is now colour art that draws nothing.
With Invert Wrap and a positive offset, a line's band was cut into at
most 64 pieces, and anchor cuts were dropped when a shape had more than
64 of them. Beside a notch the offset fills, a line could stop at the
notch instead of at the grown edge: 20 pt short beside a 0.5625 pt notch
with an offset of 1, and short beside sloped notch sides and tall bands.
The grown shape is now measured exactly: the shape near the band is cut
into trapezoids, each grown by the offset into a convex polygon, and the
line keeps the x at which those polygons hold every height of its band.
The work is capped; a shape that needs more steps than the cap, for
example one whose edges cross one another tens of thousands of times,
keeps the 64-piece measure, which keeps the line inside the grown shape.
A band of no height exactly the offset past a shape's tip now holds a
line too.
Character panel > Tsume, shown with Show East Asian Options, takes away a
percentage of the blank space on each side of a character's ink, inside
its own width, in horizontal type. The value is from 0 to 100, 0 by
default. 50 halves that space and 100 sets the ink against the
characters before and after it; the glyph keeps its shape. A character
without ink, such as a space, keeps its width, and a ligature or a
letter with its marks takes the value of its first character. The
font's pair kerning, tracking, manual kerning and Insert Aki are added
after it, and justification keeps it. Vertical type keeps its spacing.
- text.setFormat and text.setRangeStyle take `tsume`; a value that is
not a number or is outside 0 to 100 is refused, naming the key.
Character styles carry it, and a file holding a value outside the
range opens with the nearer end.
- The Character panel's Tsume field has 0, 25, 50, 75 and 100 in its
menu, and Reset Panel sets it to 0. Character Style Options shows it
in Advanced Character Formats.
- Live SVG text places each character Tsume moves, and type on a path
with Tsume is written as outlines.
Docs: docs/mcp.md (Tsume, Character Style Options fields),
docs/target-app-parity.md.
A paragraph whose characters differ in line metrics, in area type that is
not a rectangle or that wraps around an object, was broken line by line
with the Single-line Composer when the frame could not hold all of it.
The lines the frame holds are now composed with the whole paragraph: a
line the frame has no room for, and every line after it, is measured as
wide as the span of the last line set in the frame, less its indents.
Those lines overflow, or go on in the next threaded frame, which composes
them again at its own widths. A paragraph whose first line has no room,
and a search that passes its limits, still fall back to Single-line.
Docs: docs/mcp.md, docs/target-app-parity.md.
A radial gradient whose color line runs past 0 or 1 can get a circle
with a negative radius once its stops are normalized to 0..1. Circles of
a negative radius are not drawn: only the side of the circle of radius 0
(the tip of the cone) where the radius is positive is painted
(https://learn.microsoft.com/en-us/typography/opentype/spec/colr, Radial
gradients). Before:
- As vector art, a padded gradient with a stop before 0 and its centers
apart was focused on the start circle's center instead of the tip, and
one with its centers together got stop offsets below 0.
- Drawn into an image (a glyph with a sweep gradient, a Porter-Duff
composite or a repeating gradient), any such gradient filled the glyph
with its first stop's color.
Both now recast the circles so neither radius is negative. With pad, the
stops on the side that is not drawn become one stop at the tip with the
color there; stops at the tip stay, so a sharp change of color there
keeps the color on the drawn side. With repeat and reflect, the circles
move by whole periods of the color line to the drawn side. When no
circle is drawn, nothing is painted.
Two intervals at the middle of a band joined whenever their crossings
came out at the same x, even when the two edges are not along one line
and only round to that x. A slanted edge whose crossings of the band all
round to the x of a separate contour's edge then let a line run across
the gap between the contours.
The crossings now carry the line they were found along. Intervals join
at an x only when both crossings are along one line (contours that meet
along an edge) or both lie exactly at that x.
An edge that two contours of an area type frame share lies inside the
frame, and lines already run across it. Inset Spacing still kept text
clear of it, so a frame of contours that meet along an edge left a gap
of twice the inset at the seam. The inset now applies only beside the
stretches of edges that bound the frame, counted by parity as the line
spans are. A negative text wrap offset no longer shrinks a wrap object
beside an edge two of its contours share.
In area type of a shape other than a rectangle, or with text wrap, the
Single-line Composer placed each line at the metrics of its first
character and broke it in the room there. When a later character on the
line was taller, the baseline moved down by the difference without
measuring the room again, so the line could reach into a narrower part
of the frame or into a wrap object.
- A line that turns out taller than it was placed is placed again at
metrics that hold both and broken again in the room there.
- When that leaves the taller character for the next line, the line is
set at its own metrics where the room there is no narrower, and takes
the words before that character that fit there. Otherwise it stays
where it was placed.
Tests: crates/text/src/tests/combos.rs (a stepped frame and text wrap;
the two mixed-size tests now expect the Single-line Composer to break
as the Every-line Composer does there).
Docs: docs/mcp.md, docs/target-app-parity.md.
A justified line opened no gap before a right-to-left warichu block: the
glyph drawn first after the text before it is not the block's first
glyph, and it was taken as continuing the block. The block now starts at
the first of its glyphs the line draws, and blocks the bidi order
interleaves keep their starts.
The caret next to a character of a block spanned the whole line. It now
spans the band of the character's block line, as the selection does.
A glyph with a negative advance can draw a later break narrower than an
earlier one, so bisecting the breaks past the 256 measured one by one
could end a tabbed right-to-left line at an earlier break than the
latest that fits. Such a line now measures up to 1,024 breaks, or
hyphenation points, one by one before bisecting the rest.
A right-to-left line draws its last character before its tabs. When that
character loses its Japanese-Latin space at the line's end, the layout drew
it narrower before placing the tabs, but measured the line with the full
advance and took the trim off afterwards. The measured line was narrower
than the drawn one by the trim: a right-aligned line ended past the
frame's right edge (305 pt in a 300 pt frame), and a line that did not fit
as drawn was kept whole.
drawn_width now takes the end trim off the glyph it belongs to, so the tabs
drawn after it take their stops from where it ends, both where lines break
and where a line is measured for alignment.
A COLRv1 linear or radial gradient whose color line repeats or reflects
made the whole glyph an image. Such a gradient now reads into a vector
gradient with the same spread. The COLR specification repeats the
interval from the first color stop to the last, so one run of the stops
spans the gradient's vector:
https://learn.microsoft.com/en-us/typography/opentype/spec/colr
A repeating or reflecting radial gradient that starts at a circle stays
an image, and so does a repeating or reflecting gradient with a stop
whose palette index is outside the palette. A color line with an extend
value the specification does not define now pads, as the specification
says, instead of making the glyph an image.
Changing Preferences › Hyphenation › Exceptions bumped each open
document's revision, but the caches of laid-out type outside the text
crate were keyed on the font generation alone. The renderer kept the
glyph geometry, raster-effect pixels, live-effect and envelope art,
pattern tiles and placed symbol art of unchanged type objects, so
hyphenated area type kept its old line breaks on the canvas. The
hit-test art of blends and envelopes, the Fit to Artwork Bounds answer,
the layout caches of the Type and Touch Type tools and the out port's
overflow mark were keyed the same way.
vectorcraft_text::layout_inputs() returns a number that changes with
the fonts and with the hyphenation exceptions. Every one of those
caches now keys on it instead of FontDb::generation(), and envelope ink
uses it in place of the private envelope_ink_inputs(). The hit-test key
hashes it together with the plug-in revision.
Tests: a renderer that drew hyphenated area type, alone, with a drop
shadow, in a group with a Transform effect, in a symbol instance and in
an envelope, draws it as a new renderer does after the exceptions
change; the out port of selected area type shows the overflow that the
new exceptions cause. The render test helpers that run a step again
when the fonts change during it now also run it again when the
exceptions change.