Commit Graph
4302 Commits
Author SHA1 Message Date
dotCooCoo 4f07313ba4 i18n: move the Catalan antiAlias message into the sorted message block 2026-11-01 14:38:21 -08:00
dotCooCoo da078bf11b Type: test that type past the paint group limit takes the anti-aliasing method
Nine runs with opaque solid fills and strokes make ten groups of paints, past
the eight the renderer draws one at a time. The test checks that the type is
drawn as one group whose outer edges Crisp and Strong reshape, and that None
paints whole pixels.
2026-11-01 09:54:31 -08:00
dotCooCoo 92e71a9fce Type: test that the four anti-aliasing methods draw the same text four different ways 2026-11-01 08:49:19 -08:00
dotCooCoo db40218790 Type: Crisp and Strong reshape the inner edge of a character stroke
A run's solid fill and its stroke no longer share one edge group, so the
stroke's edge inside the characters takes the method. docs/mcp.md says the
native document an SVG, PDF or EPS file carries keeps each frame's method.
2026-11-01 06:08:13 -08:00
dotCooCoo 83227d368d Merge main into feat/character-anti-aliasing-method-r
# Conflicts:
#	crates/engine/src/cmd/panelcmds.rs
#	crates/ui-egui/src/panels/character.rs
2026-10-31 22:16:39 -07:00
dotCooCoo 24b509aca1 i18n: add the antiAlias message in Bulgarian, Bosnian, Danish, Indonesian and Dutch 2026-10-31 21:29:23 -07:00
dotCooCoo d9dc0ea7e7 Merge main into feat/character-anti-aliasing-method-r
# Conflicts:
#	crates/engine/src/cmd/panelcmds.rs
#	crates/ui-egui/src/panels/character.rs
2026-10-31 21:29:22 -07:00
bflatastic a76d9215da Fix #4923: Find Nearest Swatch matches colours to a library's swatches
Object > Plug-ins > Color Effects > Find Nearest Swatch... picks a
library (the document's swatches, a built-in library, or a library or
colour book the user saved or loaded) and Fill and Stroke, and lists
each colour of the selection with its three closest swatches and their
CIEDE2000 difference. Apply gives each colour its nearest swatch as one
undo step.

- addon.color.nearestSwatch (a query): the closest swatches of a
  library to each colour of the selection's fills and strokes (solid
  colours and gradient stops, inside groups and type), or to a colour
  given, with deltaE; count 1..50.
- addon.color.applyNearestSwatch: recolours those paints (and gradient
  meshes) to their nearest swatch; global and spot swatches link, and a
  library's swatches the colours take are added to the document first
  (as swatch.library.add adds them), so a spot colour stays spot.
- The library picker Image Trace's Document Library uses moves to the
  Swatches panel module and is shared.
- No colour book data ships: only libraries VectorCraft computes or the
  user loads are searched.
2026-11-01 11:09:11 +07:00
Don Omondi 6d6757c929 Export All Open Documents: every page and artboard, linked data included
Each format's copy options are given in full, so no remembered option
applies: PDF and .ai copies write every page (range all), SVG copies
the art of every artboard in one file (useArtboards false), native,
.ai and EPS copies include linked files' data.
2026-11-01 11:09:10 +07:00
Don Omondi c101576df3 Fix #4920: one file per copy
Each copy is saved with images embedded and artboards together, so a
document last saved with linked SVG images writes no image files beside
its copy; any other file a save reports is reserved for the copies still
to come.
2026-11-01 11:09:10 +07:00
dotCooCoo 38bb213917 PDF export: a Perceptual gradient that mixes spot and process inks keeps its inks
A Perceptual linear or radial gradient that mixes spot colors with each
other or with CMYK or gray stops was written as an image in process
colors. It is now written as a DeviceN shading of its inks, with the
stops on its Perceptual curve: at each one, the inks of the two stops on
either side are mixed at the weight where the two colors mixed in
display RGB have the OKLab lightness of the color on the curve.

- Gradient::ink_mixes gives the curve's stops as weights between stops,
  under the same 4,096-stop limit as ink_tints.
- Perceptual gradients that mix a spot color with RGB or Lab stops,
  dithered fills and freeform gradients stay images, and the warning
  now names those cases.
2026-11-01 11:09:09 +07:00
dotCooCoo 7e5e099f8e Export for Screens: a second file with a taken name is numbered instead of skipped
Squashed from #5028 onto main.
2026-11-01 11:09:08 +07:00
dotCooCoo ff036557fb Symbols: Edit Symbol opens the symbol in its own editing mode, and every instance follows each edit
Squashed from #5064 onto main.
2026-11-01 11:09:03 +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 94ef9b87c2 Type: Character panel toggles show off for a mixed selection, and text.setFormat checks on/off values
The Character panel's All Caps, Underline and Strikethrough buttons, and
its menu's All Caps, Underline, Strikethrough, Proportional Metrics,
Tate-chu-yoko and No Break, read the first selected character's style.
With only some characters marked they could show on, and choosing one
turned the attribute off for every character. They now show on only
when every selected character has the attribute, and a click on a mixed
selection turns it on for all, as Small Caps and Standard Vertical Roman
Alignment do. type.underline (Cmd+Shift+U) underlines a mixed selection
the same way. The Character Alignment and Digits submenus check no item
while the selected characters differ.

text.setFormat ignored a value that was not true or false for underline,
strikethrough, allCaps, proportionalMetrics, tateChuYoko,
standardVerticalRoman, noBreak, hyphenate, hyphenateCapitalized and
romanHangingPunctuation. It now refuses it with "`<key>` must be true or
false" and changes nothing, as text.setRangeStyle does.
2026-11-01 11:08:56 +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 af133b1ee4 .ai import: envelopes open as live envelopes
An envelope in a .ai's editing data opened as its distorted art, with
its mesh and contents dropped. It now opens as a live envelope of its
contents: a warp with its style, bend, distortions and orientation, a
mesh with its points and handles, or a top object with its outline,
with Envelope Options, Fidelity and Edit Contents.

The envelope replaces its drawn art only when VectorCraft draws it like
that art, with a budget so that live envelopes don't make the file open
from its PDF part. When the layers still differ too much from the page,
the drawn art is put back. An envelope that can't be read, or that
draws differently, keeps its drawn art with a note. Envelopes of type
keep their drawn art and hidden type as before.
2026-11-01 11:08:49 +07:00
dotCooCoo c027947362 .ai import: Objects on Path groups open live with their path, Pivot and Rotate
Squashed from #5059 onto main.
2026-11-01 11:08:47 +07:00
dotCooCoo 70651f585e .ai import: template layers and ruler guides open as they were set
The editing data's layer options set a template layer from the flag four
places after the colour index. The colour index of nine-operand options,
and the colour index and dimming percentage of eleven and twelve operand
options, are read from their own places (they were read one place later).

A straight (N) * guide path directly on a layer that runs across the
whole canvas, or from edge to edge of one artboard, opens as a ruler
guide on that layer (an artboard guide of that artboard); other guide
paths stay guide paths. Guides scale with the document when its editing
data is in the units of a UserUnit page, and an EPS that keeps only its
first artboard keeps only that artboard's guides.

Fixes #779
2026-11-01 11:08:18 +07:00
bflatastic 9b9f0918f0 Fix #4687: the Artboards panel reorders artboards by dragging a row 2026-11-01 10:17:29 +07:00
dotCooCoo faf62c515d Character: Crisp and Strong reshape the edges of each of the type's paints on its own
Crisp and Strong scaled each edge pixel of the composited type by the
share the method gives the characters' coverage. Where translucent
paints overlap, that drew the edges too opaque: two 50% fills at half
coverage came out at 0.875 with Strong instead of 0.75.

Each of the object's own fills and strokes, and each fill and stroke of
a run, is now drawn offscreen on its own and takes the method from its
own coverage, and the results are composited in paint order. Fills and
strokes of consecutive runs in solid colors are drawn together while the
colors are opaque. Type with more than eight such groups is drawn as one
group, as before. A pixel that every group covers wholly or not at all
keeps the pixel Sharp draws, so faint fills composite inside the
characters before their colors are rounded.
2026-10-31 19:51:22 -07:00
bflatastic 2d95cd667b Document Tools: catalog rows for Export All Open Documents, and its failure message as one translatable message 2026-11-01 09:24:25 +07:00
Don Omondi 1e8ac2434c Fix #4920: Document Tools exports every open document
addon.document.exportAllOpen {folder, format?} writes a copy of every
open document to one folder as Save a Copy does, each named after its
document with taken names numbered so no file is replaced. Documents
keep their paths and modified state, the active one stays active, and a
document that can't be written is reported while the others are still
written. Object > Plug-ins > Document Tools gets Export All Open
Documents as PDF and as SVG, which ask for the folder.
2026-11-01 09:24:25 +07:00
dotCooCoo 18b9c6113e .ai import: one object the reader can't read comes in as the page's art, and the layers stay
Squashed from #5050 onto main.
2026-11-01 09:24:23 +07:00
dotCooCoo 8362b7532c Eyedropper: Shift-click samples a blend's steps and an envelope's distorted art
Squashed from #4949 onto main.
2026-11-01 09:24:18 +07:00
dotCooCoo b253356b4d Knife: a straight cut's ends snap to the anchors and paths Smart Guides snap to
Squashed from #5044 onto main.
2026-11-01 09:24:13 +07:00
dotCooCoo c38607a5ae Tests: .doc import fuzzing also damages the compound-file container
A new text_import_fuzz case builds a valid Word 97-2003 document (version
3 or 4 compound file, its streams in the mini stream or in FAT sectors),
checks that it places, and then damages the container itself: header
fields, the sector and mini sector shifts, FAT and mini FAT entries,
directory entry fields and stream sizes, single bytes, and truncation.

Session::execute turns a panic into EngineError::Internal, so the cases
in this file did not fail when an import panicked. They now go through
no_panic, as import_fuzz.rs does.
2026-11-01 09:24:09 +07:00
dotCooCoo 9bb38208c1 Character: type whose method would draw past the pixel budget is drawn as Sharp
None, Crisp and Strong type is drawn offscreen on the output's pixels.
The offscreen drawing was limited to 32,768 pixels a side, but not in
area, so type across a large raster export held several more images of
the export's size. Type whose offscreen drawing would hold more than the
renderer's pixel budget (8.4 million pixels) is now drawn as Sharp draws
it.
2026-10-31 19:17:08 -07:00
bflatastic 84336967aa Fix #4922: Expand Dashes into Paths 2026-11-01 09:08:07 +07:00
bflatastic 317423c514 Fix #4908: Glyphs panel highlights the selected character 2026-11-01 09:08:04 +07:00
dotCooCoo 6708987188 Merge main into feat/character-anti-aliasing-method
# Conflicts:
#	docs/target-app-parity.md
2026-10-31 18:42:12 -07:00
dotCooCoo d72022daf5 Grid tools: F, V, X and C change the divider skews by 10 while a grid is dragged out
Squashed from #5019 onto main.
2026-11-01 08:33:02 +07:00
dotCooCoo f07b9ab765 Live Paint: Live Paint Bucket Options set what a click paints and the highlight
Double-clicking the Live Paint Bucket did nothing, and the tool always
filled on a click, stroked on Shift-click and highlighted in red at
4 px. It now opens Live Paint Bucket Options with Paint Fills, Paint
Strokes, Highlight, Color and Width.

- Paint Fills (on) and Paint Strokes (off) set what a click paints.
  With Paint Strokes alone, a click strokes the edge within 4 px of the
  pointer. With both on, a click strokes an edge within 4 px and
  otherwise fills the face. With both off, a click paints nothing.
- Shift switches Paint Fills alone to Paint Strokes alone and back, and
  switches both to Paint Fills alone. With the defaults, Shift-click
  strokes the edge as before.
- Highlight turns the outline of the face or edge under the pointer on
  or off; Color (a layer color or a custom color) and Width (1 to 20 px)
  set it. With Paint Strokes alone, a selection of ordinary paths no
  longer highlights a region, since a click there paints nothing.
- The options are tool options (tool.setOption {tool:
  "livePaintBucket"}): they last across tool switches and are saved
  with the preferences.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-01 08:32:57 +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
dotCooCoo ac896cfe3d PDF export: a Perceptual gradient of one spot ink's tints keeps its ink
A Perceptual linear or radial gradient was always written as an image,
so a gradient of spot ink tints lost its plate, and no warning named the
spot ink.

PDF export now writes a Perceptual gradient whose stops are tints of one
spot color (and paper white) as a Separation shading in that ink. Its
tints follow the gradient's curve: at each stop the renderer places on
the curve, the tint with the OKLab lightness of the color there.

Dithered fills, freeform gradients and Perceptual gradients that mix a
spot color with other colors are still images, and the export now warns
when such a gradient has stops linked to a spot swatch that its spot
colors are written in process colors.
2026-11-01 08:32:54 +07:00
dotCooCoo 482c011233 Transparency: a layer's art on a locked artboard or in a hidden or locked parent is not taken for an opacity mask
Make Opacity Mask expands a layer among its targets to the art that can
be edited: an object in a sublayer of a hidden or locked layer, or on a
locked artboard, is neither the mask nor masked, so it stays where it is.
2026-11-01 08:32:54 +07:00
dotCooCoo d0834e6834 Transparency: a layer on top gives its topmost object as the opacity mask
Make Opacity Mask took the topmost target as the mask. When that target was
a layer (a targeted layer above the art, or `ids` ending in a layer id), the
whole layer was removed from the layer tree and became the mask art. A layer
on top now stands for its visible, unlocked art, as a layer below the mask
already does: its topmost object is the mask and the rest of its art is
masked with the art below. A top layer with no such art is refused and the
document is left unchanged.
2026-11-01 08:32:54 +07:00
dotCooCoo 6b4ced2b96 Tests: the backtick menu test passes on macOS
menus_and_tooltips_show_the_backtick_key_as_it_types put Edit › Clear on Cmd+~.
craft-keymap reserves Cmd+` on macOS, so the override is refused there and
the menu kept Delete. The test now uses Alt+~, which no platform reserves.
2026-11-01 08:32:52 +07:00
bflatastic cd277d5d84 Fix #4917: Sort Objects sorts the selection by one attribute and applies that order to another
Squashed from #5017 onto main.
2026-11-01 08:11:17 +07:00
dotCooCoo c3b88e3e92 Merge main into feat/character-anti-aliasing-method
# Conflicts:
#	crates/engine/src/cmd/panelcmds.rs
#	crates/ui-egui/src/panels/character.rs
2026-10-31 18:10:03 -07:00
bflatastic ef80709e16 Fix #4925: Randomize Opacity gives each selected object a random opacity in a range 2026-11-01 08:07:33 +07:00
VladimirCericandClaude Opus 5.5 13dd4f9086 Languages: keep other apps' names out of the comments and docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011wCJ9DkszhZKxYL3LgcSfZ
2026-11-01 07:38:03 +07:00
VladimirCericandClaude Opus 5.5 d440b6d32b Languages: cite the quote sources (Pravopis ISBN, CLDR links)
From the CodeRabbit review: the Serbian and Croatian quote marks name
their sources with the Pravopis's ISBN and links to CLDR's sr and hr
data, in the code and in docs/type-parity.md; the quotes test says what
it checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011wCJ9DkszhZKxYL3LgcSfZ
2026-11-01 07:38:03 +07:00
VladimirCericandClaude Opus 5.5 c492d524c5 Languages: Serbian (Cyrillic, Latin) and Croatian, with their quote marks
Document Setup and Character › Language list Serbian: Cyrillic (sr-Cyrl),
Serbian: Latin (sr-Latn) and Croatian (hr). Text tagged Serbian is shaped
in it (#4940, #4959), so fonts draw their Serbian forms, the italic б,
г, д, п, т. Serbian quotes follow the Pravopis (Matica srpska 2010,
т. 168) and CLDR: „…” and ’…’; Croatian per CLDR: „…“ and ‚…‘.
Illustrator lists Croatian but not Serbian.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011wCJ9DkszhZKxYL3LgcSfZ
2026-11-01 07:38:03 +07:00
bflatastic 3d8677a71a Symbols: catalog rows for deleting several symbols and for no unused symbols 2026-11-01 07:38:02 +07:00
Don Omondi 961694cba6 Fix #4918: delete nested picks safely, keep picks per document
symbol.delete {names} expands every instance of the named symbols,
round by round, before it removes any definition, so a symbol and the
one placed inside it delete alike in either order. The Symbols panel's
picks belong to the document they were made in, and a single picked
symbol is deleted only while symbol.unused still lists it.
2026-11-01 07:38:01 +07:00
Don Omondi 5b639169cd Fix #4918: Symbols panel Select All Unused
symbol.unused lists the symbols nothing places: instances in the art
(opacity masks included), graph designs, pattern tiles and brush art
count, and so do instances in a used symbol's art. The Symbols panel
menu's Select All Unused shows them selected, and Delete Symbol asks
once and deletes those still unused in one undo step
(symbol.delete {names}).
2026-11-01 07:38:01 +07:00
dotCooCoo 1e14719c16 i18n: French rows keep the no-break space before punctuation 2026-11-01 07:16:32 +07:00
dotCooCoo 7410b7233e i18n: link, font and export status messages use real plural forms instead of "(s)"
The status bar's messages for relinked, replaced, updated and embedded
images, broken links, linked files that can't be read or changed on
disk, images that can't be decoded, added and unavailable fonts, copied
CSS, downloads and exports with notes read "1 image(s)" and similar.
They now say "1 image" and "2 images", and every catalog translates
both through @msgplural rows in the language's plural forms, as the
Package status does.

- i18n::msg_n writes such a message in English and fills its
  placeholders in one pass; the status bar's translation fills them in
  one pass too, so a path or name that holds "{n}" text stays whole.
- The old "(s)" @msg rows are replaced in all 26 catalogs, with new
  rows for Replaced and Break Link.
- Sites: dialogs/missing_links.rs, dialogs/missing_fonts.rs,
  app/links.rs, panels/css_properties.rs, dialogs/find_links.rs,
  panels/links.rs, place.rs, canvas.rs, io/export.rs and
  dialogs/save_for_web.rs.
2026-11-01 07:16:32 +07:00
dotCooCoo 13628274b7 OpenType: the panel turns Stylistic and Titling Alternates on and off, and offers Proportional Lining figures
The OpenType panel gains Stylistic Alternates (salt) and Titling Alternates
(titl) checkboxes after Swash. The Figure menu lists Default Figure, Tabular
Lining, Proportional Lining, Proportional Oldstyle and Tabular Oldstyle.
Proportional Lining sets pnum and lnum and turns tnum and onum off; Tabular
Lining keeps lnum, Proportional Oldstyle keeps pnum, and Default Figure and
Tabular Oldstyle turn both off. Every catalog has rows for the three new
labels.
2026-11-01 07:16:31 +07:00