Commit Graph
465 Commits
Author SHA1 Message Date
BFlat bac95f9902 Merge pull request #7631 from dotCooCoo/fix/composite-font-lent-document-only
Type: a document draws only its own composite font definitions
2026-11-15 03:20:55 +07:00
BFlat e8a65c97ef Merge pull request #7409 from dotCooCoo/fix/rtl-tab-end-trim
Type: right-to-left tabbed lines are measured with their line-end trim where it is drawn
2026-11-15 03:20:46 +07:00
BFlat 280cc9a488 Merge pull request #7455 from dotCooCoo/fix/followup-7303
Area type: contours whose crossings round to one x keep the gap between them
2026-11-15 03:19:29 +07:00
dotCooCoo c51d14262f Merge main into fix/composite-font-lent-document-only 2026-11-14 09:42:51 -08:00
BFlat a3b81947ff Merge pull request #7413 from dotCooCoo/fix/line-break-latest-fitting
Type: a tabbed line that steps back ends at the latest break that fits as drawn
2026-11-15 00:41:19 +07:00
BFlat 12b09b921c Merge pull request #7439 from dotCooCoo/fix/single-line-composer-remeasure
Type: the Single-line Composer measures a line's room across its tallest character
2026-11-15 00:41:01 +07:00
BFlat e76692b0f1 Merge pull request #7475 from dotCooCoo/fix/colr-radial-negative-start-radius
Type: COLR radial gradients with a negative radius draw from their circle of radius 0
2026-11-15 00:39:49 +07:00
BFlat e5a99a5284 Merge pull request #7561 from dotCooCoo/fix/invert-wrap-offset-band-exact
Text wrap: Invert Wrap with an offset lets a line use all the room the grown shape holds
2026-11-15 00:39:39 +07:00
dotCooCoo 46c9f922c2 Type: a document draws only its own composite font definitions
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.
2026-11-14 08:16:02 -08:00
BFlat 01a796e817 Merge pull request #7415 from dotCooCoo/fix/warichu-rtl-gap-caret
Type: justification spaces a right-to-left warichu block, and the caret keeps to its block line
2026-11-14 21:55:12 +07:00
BFlat bde7be4390 Merge pull request #7447 from dotCooCoo/fix/text-inset-skips-seams
Type: area type insets stop at the frame's edges, not at an edge its contours share
2026-11-14 21:53:24 +07:00
dotCooCoo 11225df118 Type: tests expect the Single-line Composer to break mixed-size overflow lines as the Every-line Composer does 2026-11-14 05:55:44 -08:00
dotCooCoo 648aedbe37 Type: a COLR glyph whose radial gradient draws no circle draws nothing
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.
2026-11-14 05:45:32 -08:00
dotCooCoo b0961a29af Merge main into fix/single-line-composer-remeasure 2026-11-14 05:29:48 -08:00
dotCooCoo 7aad123a00 Merge main into fix/invert-wrap-offset-band-exact 2026-11-14 05:11:42 -08:00
dotCooCoo 443ca3cb4a Merge main into fix/colr-radial-negative-start-radius 2026-11-14 05:05:29 -08:00
dotCooCoo 7be61fb446 Merge main into fix/followup-7303 2026-11-14 04:39:47 -08:00
dotCooCoo 3c562254e8 Text wrap: Invert Wrap with an offset lets a line use all the room the grown shape holds
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.
2026-11-14 03:44:29 -08:00
dotCooCoo 0bb290e617 Merge main into fix/colr-radial-negative-start-radius 2026-11-14 02:31:23 -08:00
dotCooCoo a45be8907b Merge main into fix/followup-7303 2026-11-14 02:20:12 -08:00
dotCooCoo 0f135f8f09 Merge main into fix/single-line-composer-remeasure 2026-11-14 02:16:06 -08:00
dotCooCoo 35a9045612 Merge main into fix/text-inset-skips-seams 2026-11-14 02:15:45 -08:00
dotCooCoo 61f0ca99f5 Merge main into fix/rtl-tab-end-trim 2026-11-14 02:09:43 -08:00
dotCooCoo 6897e1ca07 Merge main into fix/line-break-latest-fitting 2026-11-14 02:09:28 -08:00
dotCooCoo c752edc902 Merge main into fix/warichu-rtl-gap-caret 2026-11-14 02:04:02 -08:00
dotCooCoo fb13d2045d Merge main into feat/cjk-tsume 2026-11-14 01:56:33 -08:00
BFlat 78cb105961 Merge pull request #7481 from dotCooCoo/feat/every-line-composer-shaped-overflow
Type: the Every-line Composer sets the visible lines of a mixed-size paragraph that overflows a shaped frame
2026-11-14 16:51:54 +07:00
BFlat 2985970a84 Merge pull request #7403 from dotCooCoo/feat/colr-gradient-repeat
Type: COLR glyphs with repeating or reflecting gradients draw as vector art
2026-11-14 16:50:37 +07:00
ruchirguitar 22fc487cb5 #6613: reconcile main and preserve Czech parameter literals 2026-11-14 14:05:01 +05:30
dotCooCoo aff1bda696 Merge main into fix/colr-radial-negative-start-radius 2026-11-13 23:21:05 -08:00
dotCooCoo bfdf50ffb0 Merge main into fix/text-inset-skips-seams 2026-11-13 23:05:09 -08:00
dotCooCoo ae05540f70 Merge main into feat/cjk-tsume 2026-11-13 22:46:57 -08:00
dotCooCoo 1d9ebeef56 Merge main into fix/rtl-tab-end-trim 2026-11-13 22:43:03 -08:00
dotCooCoo 7bb88deb2c Merge main into fix/warichu-rtl-gap-caret 2026-11-13 22:42:56 -08:00
dotCooCoo 1494e2c230 Type: Tsume narrows the space around each character's ink
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.
2026-11-13 21:50:05 -08:00
dotCooCoo 396796ff9b Type: the Every-line Composer sets the visible lines of a mixed-size paragraph that overflows a shaped frame
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.
2026-11-13 21:46:30 -08:00
dotCooCoo 660acb12ff Type: COLR radial gradients with a negative radius draw from their circle of radius 0
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.
2026-11-13 21:31:39 -08:00
dotCooCoo 2d0bb80a52 Area type: contours whose crossings round to one x keep the gap between them
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.
2026-11-13 21:14:06 -08:00
dotCooCoo ab0ae9f880 Type: area type insets stop at the frame's edges, not at an edge its contours share
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.
2026-11-13 21:00:03 -08:00
dotCooCoo cf7a72e21b Type: the Single-line Composer measures a line's room across its tallest character
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.
2026-11-13 20:46:39 -08:00
ruchirguitar 6f6746bd72 #6613: reconcile Gujarati catalog and complete current interface coverage 2026-11-14 09:44:24 +05:30
dotCooCoo be8fafde78 Type: justification spaces a right-to-left warichu block, and the caret keeps to its block line
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.
2026-11-13 19:58:57 -08:00
dotCooCoo 6b54622e72 Type: a tabbed line that steps back ends at the latest break that fits as drawn
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.
2026-11-13 19:50:50 -08:00
dotCooCoo 5f196fdfff Type: right-to-left tabbed lines are measured with their line-end trim where it is drawn
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.
2026-11-13 19:47:46 -08:00
dotCooCoo 3d40ba6c8e Type: COLR glyphs with repeating or reflecting gradients draw as vector art
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.
2026-11-13 19:30:58 -08:00
dotCooCoo 1dc8b72bbf Type: hyphenated type lays out again when the hyphenation exceptions change
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.
2026-11-13 18:56:48 -08:00
BFlat 239152b6c8 Merge pull request #7303 from dotCooCoo/fix/slanted-seam-tolerance
Area type: lines stop at a gap between slanted contours however narrow
2026-11-14 07:32:55 +07:00
BFlat f6e84df143 Merge pull request #7306 from dotCooCoo/fix/path-type-rtl-fit
Type on a path: overflowing right-to-left type shows the longest start that fits
2026-11-14 06:26:48 +07:00
BFlat efba8bfd89 Merge pull request #7295 from dotCooCoo/fix/negative-wrap-offset
Text Wrap: a negative Offset lets text run into the wrap object
2026-11-14 06:26:39 +07:00
dotCooCoo 0fc37a0ddf Merge main into fix/slanted-seam-tolerance 2026-11-13 15:17:12 -08:00