Commit Graph
6732 Commits
Author SHA1 Message Date
BFlat 81f119d48a Merge pull request #4753 from dotCooCoo/feat/lock-unselected-objects-key
Object: Cmd/Ctrl+Alt+Shift+2 locks every unselected object
2026-10-31 04:01:26 +07:00
BFlat 70a86c6c38 Merge pull request #4751 from mockydevs/docs/ai-import-audit-records
docs: record the .ai/EPS import fixes from a user's file audit
2026-10-31 04:01:09 +07:00
BFlat 6dbe386eb6 Merge pull request #4752 from mockydevs/fix/eps10-type
EPS import: read layers whose type is in the legacy format beside a page with text
2026-10-31 04:00:53 +07:00
dotCooCoo fc7ef3102f Object: Cmd/Ctrl+Alt+Shift+2 locks inside clip groups and isolation, with no menu item
object.lock.unselected is now reached by its key and as a command only:
the Object > Lock > Unselected Artwork menu item is removed, and the
command stays in the registry, the shortcut editor and automation.

In a partly selected clip group or compound path it now locks the
unselected members, the clipping path included, and leaves the container
and the selected members unlocked. It locks unselected guides while Lock
Guides is on. Hidden art and art on a locked layer stay unlocked, and a
selected layer's art counts as selected.

With a selection in isolation mode the command is enabled and locks only
the unselected art inside the isolated group. The other Lock and Hide
items keep their isolation behavior.

Lock and Hide still share one selector. A lock flag on it selects the
clip group, compound path and guide cases above; Hide > Unselected
Artwork keeps its behavior, and a test covers both directions.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-31 03:34:47 +07:00
dotCooCoo a372d39a31 Object: Cmd/Ctrl+Alt+Shift+2 locks every unselected object
The reference app locks all deselected artwork on Cmd/Ctrl+Alt+Shift+2.
VectorCraft had no command for it: Object > Lock held Selection, All
Artwork Above and Other Layers.

The new command, object.lock.unselected (Object > Lock > Unselected
Artwork), locks in one undo step the objects that Hide > Unselected
Artwork hides: every object that Select All takes and that is neither
selected nor holds a selected object. It returns the count. Hidden
objects stay unlocked. The selection stays as it is, Unlock All unlocks
the objects again and selects them, and with nothing to lock the
command records no undo step. Both commands now share one function,
which locks or hides the objects that the existing unselected helper
returns.

In isolation mode the menu item is disabled, and the command returns
the error "not available in isolation mode" that Hide > Unselected
Artwork returns there, and changes nothing.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-31 03:34:47 +07:00
Don Omondi 7591e35345 docs: record the .ai/EPS import fixes from a user's file audit
Adds the evidence and revision rows that target-app-parity.md and
roadmap.md expect for the .ai/EPS import changes of 2026-10-30 (#4708,
#4664, #4723, #4742, #4658, #4727, #4738, #4744, #4748, #4743). Scores
and estimates unchanged.
2026-10-31 03:34:43 +07:00
Don Omondi bfe509bb38 fix(eps-import): read layers whose type is in the legacy format beside a page with text
An EPS saved for Illustrator 10 keeps its type in the editing data as
legacy text objects (`To` ... `TO`), with no `/AI11Text` slot for the
page's type to go in, so a file whose page had text came in as its page.
Those text objects are now the layers' own: the page's type isn't put
anywhere, and the comparison with the page decides as before. Type the
editing data keeps only as outlines stays outlines, with a note counting
the page's text objects that are.
2026-10-31 03:34:40 +07:00
BFlat 9de15d6599 Merge pull request #4749 from dotCooCoo/feat/panel-fkey-toggles-panel
Panels: a second press of a panel's function key hides its group
2026-10-31 03:33:29 +07:00
BFlat c27e4b51ee Merge pull request #4745 from dotCooCoo/feat/escape-leaves-full-screen
View: Escape in either Full Screen Mode returns to Normal Screen Mode
2026-10-31 03:33:13 +07:00
BFlat f004980e2e Merge pull request #4747 from dotCooCoo/feat/vertical-type-arrow-steps
Type: Alt+arrow spacing steps turn with vertical type
2026-10-31 03:32:56 +07:00
BFlat 4e82d12dae Merge pull request #4748 from mockydevs/fix/eps-mesh-layer-state
.ai/EPS import: a layer's state after its last mesh stays the layer's
2026-10-31 03:32:45 +07:00
BFlat 91e5931919 Merge pull request #4746 from mockydevs/fix/lam-alef-legacy-arial
Type: required lam-alef is not an alternate in fonts that put it in liga (#394)
2026-10-31 03:32:31 +07:00
dotCooCoo 7a16e302d2 Panels: a panel's function key restores only the tabs its group hid
Hiding a group with a panel's function key records the tabs it closed, and the next press reopens only that set with the panel in front. A tab closed on its own before the group was hidden, or reopened and closed again while the group was hidden, stays closed. The record is saved with the workspace.
2026-10-31 02:52:26 +07:00
dotCooCoo 78b01044fc Panels: a panel's function key hides and restores its whole group
When Brushes, Color, Layers, Info, Gradient, Stroke, Attributes, Graphic
Styles, Appearance, Align, Transform, Pathfinder, Transparency or
Symbols is in front of an expanded dock group or a floating group, its
function key now hides the whole group instead of closing only that
tab. The next press brings the group back in the same place with every
tab and the panel in front, and Window > a hidden sibling also restores
the group. A background tab still comes to the front on the first
press, and in an icon column the key opens and closes the flyout.
Other panel shortcuts and plain window.panel calls keep their behavior.
2026-10-31 02:52:26 +07:00
dotCooCoo a535d7b890 Panels: a second press of a panel's function key hides the panel
The function key shortcuts for Brushes, Color, Layers, Info, Gradient,
Stroke, Attributes, Graphic Styles, Appearance, Align, Transform,
Pathfinder, Transparency and Symbols now run window.panel with
toggle: true, as the Window menu items do. A second press hides an
active panel in the expanded dock, and the next press restores it in
its group. A chord the user assigns to one of these panels toggles the
same way. Plain window.panel calls still only show the panel.
2026-10-31 02:52:25 +07:00
dotCooCoo d792557bbe View: Escape during a canvas pan or zoom drag keeps full screen
A Hand or Space drag, a middle-button pan, a Zoom tool drag, a Rotate View
drag or a touch gesture is held in the canvas's drag state, which the tool
busy check does not see. Escape pressed while one is held no longer leaves
Full Screen Mode, closes the Edit Toolbar drawer or ends another action; an
Escape after the release does.
2026-10-31 02:52:22 +07:00
dotCooCoo 030baab798 View: Escape that cancels a ruler or Tools move ends nothing else
An Escape press that cancels a ruler-origin drag or a floating Tools
panel move no longer also closes Edit Toolbar's drawer, leaves pattern
edit, isolation or Global Edit, closes the tool flyout or resets a
rotated view. A later Escape does that action as usual.
2026-10-31 02:52:22 +07:00
dotCooCoo dcd4b437a5 View: Escape that ends a field, ruler or Tools move keeps full screen
In Full Screen Mode and Full Screen Mode with Menu Bar, an Escape that
leaves a focused text field, cancels a ruler-origin drag or cancels a
floating Tools panel move no longer also returns to Normal Screen Mode;
the next Escape does. Tests cover a dialog, a focused field, a tool that
claims Escape, pattern edit, Global Edit, a tool flyout and the rotation
reset pair in both modes.
2026-10-31 02:52:22 +07:00
dotCooCoo 38a68c3b85 View: Escape returns full screen modes to Normal
In Full Screen Mode and Full Screen Mode with Menu Bar, an unmodified
Escape that nothing earlier in the Escape chain takes (a popup, dialog,
field, drawer, tool gesture, edit mode, flyout or the view rotation
reset) runs view.screenMode with mode 0. Presentation Mode and the F
cycle are unchanged.
2026-10-31 02:52:22 +07:00
dotCooCoo 86f88dfc96 Type: Alt+arrow spacing steps turn with vertical type
In vertical type, Alt+Down/Up (with or without Shift) steps kerning at a
caret or tracking of selected text, Alt+Left/Right steps leading, and
Alt+Shift+Right/Left steps baseline shift; Cmd/Ctrl makes five steps.
Horizontal type keeps its mapping. Selected type objects follow the same
rule when all of them are vertical, and a selection that mixes horizontal
and vertical type takes the horizontal mapping in one undo step.
2026-10-31 02:52:17 +07:00
Don Omondi ef3b5b0c95 fix(eps): a layer's state after its last mesh stays the layer's
An Xy right after a gradient mesh's /End X! is the mesh's only when the
mesh's own 6 () XW follows. When the layer's LB follows (directly or
after the layer's Xd and 7 () XW) it is the layer's, as before, and the
mesh keeps the state it had. Also corrects the revision-history row that
still said meshes with handle weights of 0 aren't read.
2026-10-31 02:52:13 +07:00
Don Omondi c1971284ce Type: required lam-alef is not an alternate in fonts that put it in liga (#394)
Highlight Alternate Glyphs compares each glyph with required shaping
alone, which turns liga and calt off. Older Arabic fonts (such as the
legacy Arial of the Microsoft core fonts) put the mandatory lam-alef
ligature in liga instead of rlig, so every lam-alef was highlighted.
A lam + alef cluster (any alef form, marks allowed) is now never an
alternate candidate, whatever feature the font uses.

Adds a test font built in code (lam-alef under liga or rlig) and
host-independent regressions. Also two equivalent one-line repairs
strict Clippy needs on main: a nonminimal_bool in the Path Precision
Tools inspect check and is_none() in a gradient panel test.
2026-10-31 02:52:05 +07:00
BFlat 0e7e41e786 Merge pull request #4665 from storytold/dependabot/cargo/cargo-patch-7373e1a9e8
chore(deps): bump the cargo-patch group across 2 directories with 4 updates
2026-10-31 02:42:29 +07:00
dependabot[bot] 414aad10bd chore(deps): bump the cargo-patch group across 2 directories with 4 updates
Bumps the cargo-patch group with 3 updates in the / directory: [rustix](https://github.com/bytecodealliance/rustix), [clipboard-win](https://github.com/DoumanAsh/clipboard-win) and [smallvec](https://github.com/servo/rust-smallvec).
Bumps the cargo-patch group with 1 update in the /crates/plugins/example directory: [serde_json](https://github.com/serde-rs/json).


Updates `rustix` from 1.1.5 to 1.1.6
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGES.md)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v1.1.5...v1.1.6)

Updates `clipboard-win` from 5.4.1 to 5.4.3
- [Commits](https://github.com/DoumanAsh/clipboard-win/commits)

Updates `smallvec` from 1.16.3 to 1.16.4
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.16.3...v1.16.4)

Updates `serde_json` from 1.0.151 to 1.0.154
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.151...v1.0.154)

Updates `serde_json` from 1.0.151 to 1.0.154
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.151...v1.0.154)

---
updated-dependencies:
- dependency-name: clipboard-win
  dependency-version: 5.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-patch
- dependency-name: rustix
  dependency-version: 1.1.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-patch
- dependency-name: serde_json
  dependency-version: 1.0.154
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-patch
- dependency-name: serde_json
  dependency-version: 1.0.154
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-patch
- dependency-name: smallvec
  dependency-version: 1.16.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-31 02:23:04 +07:00
BFlat 5a4313ccf5 Merge pull request #4741 from storytold/feat/addon-cleanup-text
Add-ons: Artwork Cleanup — text tools
2026-10-31 02:22:21 +07:00
BFlat 998da41a23 Merge pull request #4733 from dotCooCoo/fix/swatch-anchor-doc-switch
Swatches: a Shift-click after switching documents starts a new range
2026-10-31 02:22:02 +07:00
BFlat 9c12aaa078 Merge pull request #4743 from mockydevs/fix/ai-path-type-spacing
.ai import: space type on a path round curves as the file lays it out
2026-10-31 02:21:46 +07:00
BFlat c3de273f0b Merge pull request #4742 from mockydevs/fix/ai-placed-closer-placement
.ai import: put placed files where they draw closer to the page
2026-10-31 02:21:30 +07:00
BFlat 6cbf1fa093 Merge pull request #4740 from mockydevs/fix/ai-rank5
.ai/EPS import: crop marks after the layers and type inside placed PDFs no longer lose the layers
2026-10-31 02:21:17 +07:00
BFlat ff62b8cd64 Merge pull request #4744 from mockydevs/fix/eps-mesh-transparency
.ai/EPS import: a gradient mesh takes the transparency written after it
2026-10-31 02:21:02 +07:00
BFlat 198aec3014 Merge pull request #4738 from mockydevs/fix/ai-mesh-weights
.ai/EPS import: read gradient mesh corners whose handle weights are 0
2026-10-31 02:20:46 +07:00
bflatastic e556dacbb6 Add-ons: Artwork Cleanup — text tools
Object › Plug-ins › Artwork Cleanup and a hideable Text row in its panel
gain text tools, each one undo step:
- Break Text into Lines / Paragraphs / Words / Glyphs: point type pieces
  placed by the glyph of their first character, keeping their styles.
- Combine Point Text: one-line point type merged into as few objects as
  it can, every glyph staying where it was (tracking and spaces, checked
  against the layout).
- Split Text at Cursor, Remove Line Breaks, Remove Paragraph Breaks,
  Set Alignment, Keep Position, Reset Text Transform and Replace
  Missing Fonts.
2026-10-31 02:05:58 +07:00
dotCooCoo a0da3faffe Swatches: a Shift-click after switching documents starts a new range
The panel cleared its swatch selection when the active document or the
selected art changed, but kept the Shift-click range anchor. A Shift-click
in the other document then selected every swatch from a name clicked in
the first document (for example White) to the clicked one. The anchor is
now cleared with the selection, so the Shift-click selects only the
clicked swatch.
2026-10-31 02:05:55 +07:00
Don Omondi 1a5f0fb099 fix(ai-import): space type on a path round curves as the file lays it out
Type on a path from the editing data's text document came in at the
font's advances, while the file's own layout (and its page) closes the
glyphs up round the outside of a curve and opens them up round the
inside, even where the frame keeps no spacing. Round a circle the type
ran on past where the page ends it.

The spacing (Type on a Path Options > Spacing) that reproduces the
layout is now fitted from the layout's glyph positions, advances and
turns, using the text engine's own model, and set on the imported text
object. Corners and straight runs are left out of the fit.
2026-10-31 02:05:52 +07:00
Don Omondi 7b4a65e231 fix(ai-import): put placed files where they draw closer to the page
The corner placement of placed files was tried only when the first
placement failed the comparison with the page. A small logo in the wrong
place differs too little to fail, so it stayed there. When the corner
placement draws closer to the page and still matches it, use it.
2026-10-31 02:05:48 +07:00
Don Omondi 67c8d86c6f .ai import: a page's type inside placed files needs no text object
A .ai whose layers hold placed (linked) PDFs and no text object came in as
its PDF part, saying its layers had no text objects for its page's text.
The PDF part draws each placed file, type and all, where the layers show
its preview, so type that lies inside the placed files (at either of their
placements) is theirs and needs no text object. Type outside them still
does.
2026-10-31 02:05:43 +07:00
Don Omondi 2d4e9dc9c9 EPS import: the printer's crop marks after the layers aren't art outside them
An Illustrator EPS draws its crop marks after the last layer, between
%AI3_BeginCrops and %AI3_EndCrops (inside userdict /AI3_noCropMarks known
not { ... } if). The reader took them for art outside the layers, and the
whole file came in as its page in one layer. The section is now skipped,
as other non-art sections are; the crop area is %AI3_Cropmarks.
2026-10-31 02:05:42 +07:00
Don Omondi e5481bda98 fix(eps): a gradient mesh takes the transparency written after it
In the editing data of a .ai or EPS file, a gradient mesh's own state
(`Xy`) comes right after its `/End X!`, before its `Xd` and `XW`, as a
group's comes after its `U`. The reader took it as the next object's, so
a Multiply shadow mesh came in as Normal and painted opaque white over
the art under it, while the file's page shows the shadow.

An `Xy` read straight after a mesh ends now also applies to that mesh.
An `Xy` after the mesh's `Xd` and `XW` stays the next object's.
2026-10-31 02:05:39 +07:00
Don Omondi dc6af04dcc fix(ai-import): read mesh corners whose handle weights are 0
Some files write a handle weight of 0 on some gradient mesh corners. The
reader took only weights of 1, so the mesh and the whole file's layers
were unread. A weight of 0 draws as the same cubic edge against the files'
pages; other weights still leave the mesh unread.
2026-10-31 02:05:35 +07:00
BFlat 8614c9dfe8 Merge pull request #4722 from nine-codes/bosnian-language-support
bs: Add Bosnian (bs) to the interface languages
2026-10-31 02:03:44 +07:00
BFlat aa90b104c6 Merge pull request #4737 from storytold/fix/testkit-fresh-temp-dirs
Testkit: temp_dir starts empty in each process, so a reused process id can't fail a test
2026-10-31 02:03:29 +07:00
bflatastic 63a5889895 bs: language names keep their own name in the picker 2026-10-31 01:31:09 +07:00
nine-codesandClaude Opus 5.5 64b92627c2 Add Bosnian (bs) to the interface languages
bs.tsv: Bosnian (Latin script, Ijekavian) catalog covering every key of
VectorCraft's other catalogs, its wording shared with storytold/craft-i18n
locales/bs/ and the strings craft-i18n lacks translated new. Every bs-*
locale selects it; counts use one/few/other. Locale and plural tests,
localization docs and an attribution entry (AI-assisted, not yet
reviewed by a native speaker).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Tayw8nmxoLLmKv13jK93z
2026-10-31 01:17:11 +07:00
bflatastic f38cdaeaa7 Testkit: temp_dir starts empty in each process, so a reused process id can't fail a test 2026-10-31 01:17:06 +07:00
BFlat 2166aca02e Merge pull request #4734 from storytold/feat/addon-duotone
Add-ons: Color Effects — Duotone effect and Print Ink Fixes
2026-10-31 00:52:57 +07:00
BFlat 41c3f71880 Merge pull request #4735 from storytold/fix/4711-drag-modifiers
Canvas: Shift, Alt and Cmd/Ctrl pressed or released mid-drag apply with the pointer held still
2026-10-31 00:52:41 +07:00
BFlat 259faa3dba Merge pull request #4705 from dotCooCoo/fix/trace-library-global-swatch-same-color
Image Trace: Document Library links to a global swatch that shares a process swatch's color
2026-10-31 00:52:27 +07:00
BFlat a5b3d2cf6d Merge pull request #4714 from dotCooCoo/feat/perspective-selection-copy-drag
Perspective Selection: Cmd/Ctrl+Alt-drag copies objects in perspective
2026-10-31 00:52:06 +07:00
BFlat 071a94ce4a Merge pull request #4729 from mockydevs/fix/ai-import-review-followups
.ai import: outlines from the editing data keep their look and threads; mesh corners with non-numbers are unread
2026-10-31 00:51:49 +07:00
BFlat e8b3d1a6cb Merge pull request #4727 from mockydevs/fix/ai-cropped-page-units-and-pages
.ai import: pages cropped to the art in UserUnit units, and their copies' type
2026-10-31 00:51:31 +07:00