Commit Graph
11025 Commits
Author SHA1 Message Date
Brandon Thomas cbae540edf Merge pull request #5120 from dotCooCoo/fix/paste-beside-compound-member
Paste: in front or back of a compound path's member, other art goes beside the compound path
2026-11-01 15:27:36 -05:00
dotCooCoo 9726e691f5 .ai import: names that aren't UTF-8 can be read in a legacy code page
A legacy .ai stores layer, object, color, gradient, pattern, style and
swatch names as bytes, without saying which code page they are in.
Names that aren't UTF-8 are still read as Windows-1252 by default, and
now each gives a warning naming it and the encoding it was read in (the
first three, then a count).

document.open takes legacyNameEncoding (windows-1252, macintosh,
windows-949 or euc-kr, shift_jis, gbk, big5) and vectorcraft-cli
convert takes --legacy-name-encoding, to read those names in another
code page. Definitions and the fills that name them are read alike, so
they still match. Type, comments, dictionary keys and PDF layer names
are read as before.

encoding_rs becomes a direct dependency of vectorcraft-eps.

Part of #2831
2026-11-01 12:17:42 -08:00
Brandon ThomasandClaude Opus 5.5 872effcf77 Recolor: docs say a map row's model can't be null either
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 15:12:13 -05:00
dotCooCoo 39e69e8446 Tests: move the lock params text test next to the lock test 2026-11-01 11:48:41 -08:00
Brandon ThomasandClaude Opus 5.5 5628de96f8 Release 0.20.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.20.0
2026-11-01 13:59:17 -05:00
datatimp 4a8b40ac8b Color Halftone: test older files at 72 and 300 ppi (#3260) 2026-11-01 13:57:22 -05:00
dotCooCoo b104efc53c Graph data: a dropped empty row adds no blank series
Dropping rows with neither a label nor a value read the data padded to
the widest row, so a dropped row wider than the rest (`,,`) left every
kept row one blank cell wider. The graph then had an extra blank series,
and a right-axis assignment to that index was kept. Each kept row now
keeps its own width. This applies to graph.setData and to a graph
variable's data set.
2026-11-01 10:19:45 -08:00
dotCooCoo 637229931f Paste: Paste in Back keeps a clip group's clipping path at the bottom
With the clipping path of a clip group or a clipping layer selected, or a
member of a compound path that is the clipping path, Paste in Back put the
clipboard's objects below it. The bottom pasted object then became the
clipping path. With nothing selected in a clipping layer, Paste in Back did
the same at the bottom of the layer.

Paste in Back now puts the objects right above the clipping path, as Send to
Back keeps art above it.
2026-11-01 10:18:06 -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
Dylan M. Taylor 77274ac5ff docs: sync Craft App Suite list with ArtCraft Launcher 2026-11-01 12:29:58 -05:00
dotCooCoo be20929877 Variables: a text value on threaded type replaces the whole story
Applying a data set wrote a text value into the bound frame only, and the
thread's reflow then joined it with the other frames' old text. The art no
longer matched the row it had just applied, a captured row applied back lost
text, and a value bound to a later frame deleted the rest of the story.

- A text value bound to any frame of threaded text replaces the whole story,
  which then flows through the frames again. `overflow` names the story's
  last frame.
- Capture Data Set, Update Data Set and the Variables panel's match check
  read such a frame as the whole story, frames joined in thread order.
- When any frame of the story is locked, the text value is skipped and
  counted in `skipped`, and the story is not read.
- Two text variables bound in one story apply in definition order, as for
  two on one object: the one defined last wins.

Docs: docs/mcp.md.
2026-11-01 08:58:35 -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 e49e102032 Variables: Lock Variables' description names the refused import
variable.lock's params text and the doc comment on Variables::locked said every
dataset command still runs while the variables are locked. dataset.import is
refused when its header would define a variable; both texts now say so, as
docs/mcp.md and dataset.import's params already do.
2026-11-01 08:43:56 -08:00
dotCooCoo 07282d95e0 Variables: a graph variable's data set applies its CSV as graph.setData does
Choosing a data set gave a graph variable's CSV to the graph without the
two steps graph.setData takes after new data: rows with neither a label
nor a value were kept and drawn as empty slots, and a right-axis series
the new data no longer had stayed assigned, so a series added by a later
row started on the right axis. The data set now goes through the same
steps.
2026-11-01 08:43:16 -08:00
dotCooCoo 0465fb8336 Type: push-in closes no gap inside a cluster and measures along the line
A push-in no longer counts or closes the gap between two glyphs of one
shaped character, and CJK justification adds no space there either.
The share of an em each gap closes by is measured along the line: at
the character's Horizontal Scale, or at its Vertical Scale for an
upright character in vertical type whose font's vertical metrics set
its length down the column. Before, horizontal text at 200% Vertical
Scale closed its gaps by twice as much.
2026-11-01 08:36:32 -08:00
dotCooCoo f98b086c5f Variables: Rename reports a missing variable or data set before a taken name
variable.rename and dataset.rename checked whether newName was taken before
checking that name exists, so renaming a missing name onto a taken one said
the new name already exists. Both now report the missing name first.
2026-11-01 08:23:40 -08:00
dotCooCoo 932426eaad Type: a line holding right-to-left text pushes out
A line with right-to-left text is reordered before it is drawn, and
justification closes the gaps between its glyphs in that order, which
can differ from the gaps the push-in counted. Such a line could be
taken as fitting and then run past its frame. Kinsoku Shori Type now
pushes it out.
2026-11-01 08:22:06 -08:00
dotCooCoo 3698a76c5d File formats: JPEG XL refuses colors left in a profile that is not an RGB one
A color JPEG XL image whose embedded ICC profile the decoder cannot convert to sRGB kept its samples as stored and lost the profile when that profile was not an RGB one, so the image drew those samples as sRGB. It is now refused as unreadable, as a gray image in such a profile already is.
2026-11-01 08:09:11 -08:00
dotCooCoo 7f843e1e4a .ai import: objects with a variable-width stroke come in as their drawn outline
The editing data keeps each styled object's drawn look, the outline as
the file draws it, next to the editable path. An object whose art style
was one stroke with a width profile came in as a live stroke instead, and
VectorCraft's width profile does not draw these strokes at the widths the
file draws them, so outlines no longer met the fills built against them.

Such an object now comes in as its drawn look, as other styles that
VectorCraft cannot draw the same way already do. Type keeps the stroke
and its profile live, since its drawn look cannot be retyped. The import
warning for drawn looks now names variable-width strokes.
2026-11-01 07:59:14 -08:00
dotCooCoo e6ae67154d Merge main into feat/jxl-import 2026-11-01 07:56:25 -08:00
dotCooCoo baeef1ec05 Blend: an edit merged into an open undo group drops the first pick
An edit merged into the newest undo step (an undo group) left
History::step unchanged, so a first pick made while the group was open
survived the edit. The newest step now takes a new number whenever it is
extended.
2026-11-01 07:12:43 -08:00
dotCooCoo f1fd255120 .ai import: version 7 palettes keep their swatches without names
Version 7 files write each palette swatch as its paint and `Pc`, with no
name. The reader only kept a swatch with a name before `Pc`, so such a
palette gave no swatches and the document got the default set.

A swatch without a name is now named by its spot color, gradient or
pattern, or by its values in the format the swatch import already uses
for unnamed colors ("Gray K=25", "C=25 M=0 Y=0 K=0"). `Pn` and a `Pc`
with no paint before it add nothing. Named swatches keep their names.

An operator the reader does not know, or a `Pg`, now ends the paint
before it, so a later `(name) Pc` no longer takes that paint. The
swatch limit is kept with a running count instead of summing every
group at each `Pc`.
2026-11-01 06:55:53 -08:00
dotCooCoo 4b663906e9 Blend: tests for a pick dropped by Redo and for the history step
A Redo made outside the Blend tool drops its first pick, as an edit or an
Undo does, and two picks with no edit between them blend. History::step
changes with each new step, Undo and Redo, also when an Undo and a new
edit leave as many steps as before, and stays the same for a selection
change and for an edit merged into an undo group.
2026-11-01 06:53:56 -08:00
dotCooCoo 52061b1029 Undo: tests for the default history budget with no memory reading, 0, small and large memory
history_budget_for takes the memory reading itself, so the 1 GiB fallback for no reading
or 0 is tested with the quarter, the 64 MiB floor and a reading of 2 GiB, as a cgroup limit
lower than the installed memory gives. The budget is unchanged.
2026-11-01 06:52:08 -08:00
dotCooCoo 827e137b5c Paste: in front or back of a compound path's member, other art goes beside the compound path
With a member of a compound path selected, Paste in Front and Paste in Back
put the clipboard's objects next to that member, inside the compound path,
whatever they were. A pasted group, compound path or type object then sat
inside a compound path, which holds only paths. The model-based test
`random_command_sequences` stops on this with "compound #N has a non-path
child".

When the clipboard holds anything other than paths, the objects now go
right above or below the compound path. Paths still go next to the member,
inside the compound path.
2026-11-01 06:42:33 -08:00
dotCooCoo a4436388cc Batch: a folder source's file name keeps a backslash on Linux and macOS
Output stems for a folder batch went through safe_file_name, which turns
`\` and `:` into `-`, so `a\b.svg` on Linux was written as `a-b.svg`.
The stem now only loses trailing periods and spaces and gets `-` after a
Windows device name, and keeps every other character.
2026-11-01 06:35:40 -08:00
dotCooCoo b5cf31950b Merge main into feat/kinsoku-shori-type 2026-11-01 06:26:35 -08:00
dotCooCoo fd973bdf48 Tests: Outline Stroke with Round Corners, no effect, hidden effects, blur and undo 2026-11-01 06:23:42 -08:00
dotCooCoo 1f24099dd9 .ai save: test that a file opens from its VectorCraft document when the editing copy differs
A .ai whose editing copy for other apps holds no transparency, while the VectorCraft document it carries holds 50% opacity, opens in VectorCraft with the opacity of the VectorCraft document. Read with native: false, the same file gives the editing copy.
2026-11-01 06:22:13 -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
vangel76andClaude Sonnet 5.5 6241ef6e2b Merge upstream/main into fix/2414-svg-classes
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 14:56:38 +01:00
dotCooCoo 01798d86ab Native format: tests for exact saves, rounding halves, closed and tiny paths
Without `precision` 500 coordinates of every size reopen bit for bit and a
second save writes the same bytes. Halves round away from zero, a closed
path keeps its closing anchor on its first one, a shape smaller than one
step collapses onto one point, coordinates at the edge of the canvas round
to the asked places, and saving a rounded file again at the same precision
writes the same bytes. docs/mcp.md states these rules.
2026-11-01 05:38:12 -08:00
dotCooCoo fc6178d021 Recolor Artwork: spell color the American way in the new comments and test names 2026-11-01 05:26:35 -08:00
dotCooCoo 74b8d31183 Merge main into feat/character-anti-aliasing-method-r 2026-11-01 05:13:53 -08:00
dotCooCoo 9b853004d5 Recolor Artwork: a slider edit changes the color mode of its own row only
The color sliders now mark the row they edit with `model: "new"`
instead of a dialog-wide flag, and `recolor.apply` reads a row's own
`model` before the command's. Rows the sliders did not edit keep each
color's model, so with RGB art and a CMYK color group, a slider edit of
one row no longer turns the other rows' art CMYK. Another edit of the
row's new color, Reset and rows reduced again remove the mark, and
`recolor.randomize` moves it with its new color.
2026-11-01 02:06:46 -08:00
05d5f99fd7 ci: run the desktop printing check through the shared gate (#5062)
* ci: run the desktop printing check through the shared gate

print.yml ran its own Windows job, which the CI workflow rules phase out, and each PR saved its
own ~1.3 GB cache. The same commands now run through craft-common-actions' gate.yml on
windows-2022, without craft-fonts, nextest or the wasm target as before. The gate never saves
from a pull request; a manual run on main seeds the cache. storytold/craft-common-actions#118.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: call the shared gate at main

storytold/craft-common-actions#119 is merged, so main's gate takes an empty packages list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:55:12 +01:00
dotCooCoo 1323965312 Recolor Artwork: Tint shows only with art and previews the color the art takes
A dialog opened on a color group or on loose colors no longer offers Tint for a spot color of
the library: OK saves only the new colors, so a tint set there was lost. The row shows the
process modes instead.

The Tint rail and a tinted row's new color chip show a Lab spot color as art linked to it shows
it: the working-CMYK equivalent while the Spot Colors options use CMYK values, with its inks
scaled.
2026-11-01 01:40:08 -08:00
dotCooCoo 333450b862 Recolor Artwork: rebuilt rows discard a slider edit's color mode
Changing the color count, a Preserve option or Limit to Library rebuilds the rows from the art's colors, which discards a slider edit. The dialog now also forgets that edit, so preview and OK give the art the rebuilt rows' colors in the art's own model instead of the rows' models.
2026-11-01 01:18:07 -08:00
dotCooCoo f242b9caa6 Recolor Artwork: a row's tint stays with its spot color
A wheel drag or a harmony rule on the Edit tab now removes a row's tint
when it gives the row another new color, as the color sliders, the hex
field and the Color Picker already do. With Limit to Library, an edit
that snaps back to the row's own color keeps the tint.

recolor.randomize moves each row's tint with its new color when it
shuffles the order, and removes the tint from a color that saturation
and brightness changes.
2026-11-01 01:55:46 -07:00
dotCooCoo 5e1a50c75a Linux: hold spawning while the title bar test starts its child process
On Linux and the BSDs, the_titlebar_variable_decides_the_frame_before_the_window_opens now
holds spawning() while it starts each child test process, as the portal save test does around
dbus-daemon, so the child does not keep a copy of a GPU start test's locked start file.
2026-11-01 01:52:37 -07:00
dotCooCoo a1c908fbd2 Linux: test VECTORCRAFT_TITLEBAR read from the environment with System Title Bar off and on
Runs the test binary again with VECTORCRAFT_TITLEBAR set to app, system,
desktop and an unknown value, and checks titlebar_override, custom_titlebar
with no saved preferences and with System Title Bar off and on, and the
window decorations native_options sets before the window opens. On macOS
and Windows the variable is not read.
2026-11-01 00:06:04 -07:00
dotCooCoo c50fe0220d Recolor Artwork: Reset discards slider edits and reads the art's own colors
Reset now also clears the slider edit, so the preview and OK keep each
color's model again instead of sending model "new". Changing the Colors
count, a Preserve flag or Limit to Library, or pressing Reset, with the
preview on reduced the previewed colors, so the rows no longer matched
the art; the preview is now rolled back before the colors are reduced.

The Tint mode follows the swatch recolor.apply links: the first library
swatch of the library color nearest the row's new color, shown as Tint
only when that swatch is a spot color.
2026-10-31 23:52:06 -07:00
dotCooCoo e725c4920c Tests: nested clip groups in isolation mode and Direct Selection drags
- isolation_reaches_hidden_art_only_for_the_isolated_clip_group: with the
  outer clip group isolated, clicks and marquees take the art its own mask
  hides, while an inner clip group's mask still clips that group's art;
  isolating the inner group or its art reaches the inner hidden art.
- isolation_lets_direct_selection_take_the_art_a_clip_group_hides now
  continues the press with a drag on the same tool and checks the Move
  step and its preview, for Direct Selection and Group Selection.
2026-10-31 22:26:08 -07: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 46cb088eae Recolor Artwork: color sliders edit the selected row's new color in a chosen mode
The Assign tab gets a Color Mode menu (HSB, RGB, CMYK, Lab, and Tint when
the row's new color is a spot color of the Limit to Library library) and
its sliders under the rows. They edit the first selected row's new color
and are disabled with no row selected. Once they have edited a color in a
mode, the preview and OK send recolor.apply with model "new", so the art
takes the color in that mode.

recolor.apply rows take an optional tint (percent, default 100): art linked
to the row's global or spot library swatch takes that share of its tint.
recolor.randomize keeps a row's tint.
2026-10-31 21:42:42 -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
BFlat 1c4a7831eb Merge pull request #5067 from storytold/feat/nearest-swatch-4923
Fix #4923: Find Nearest Swatch in the document or a swatch library
2026-11-01 11:28:39 +07:00
BFlat d94392db1f Merge pull request #5055 from mockydevs/fix/export-all-one-file-4920
Export All Open Documents: one file per copy (#4920 follow-up)
2026-11-01 11:28:23 +07:00
BFlat f77dcc8ec4 Merge pull request #5056 from dotCooCoo/fix/pdf-perceptual-gradient-mixed-inks
PDF export: a Perceptual gradient that mixes spot and process inks keeps its inks
2026-11-01 11:28:01 +07:00