Commit Graph
10741 Commits
Author SHA1 Message Date
BFlat df7a185cb2 Merge pull request #6534 from dotCooCoo/fix/reshape-earlier-steps
Reshape: a step recorded without focal points plays by the earlier rule
2026-11-11 14:48:26 +07:00
BFlat 05f2be5588 Merge pull request #6528 from dotCooCoo/fix/insert-anchor-keeps-selection
Paths: Add Anchor Point keeps the same anchors and segments selected
2026-11-11 14:48:16 +07:00
BFlat 7771355529 Merge pull request #6535 from jmverges/fix/3179-half-stroke-box
.ai import: stroked type in an envelope maps from its glyphs grown by half its stroke
2026-11-11 14:39:40 +07:00
BFlat 0127ed3ec9 Merge pull request #6536 from dotCooCoo/feat/script-include-directives
Scripts: #include and the other preprocessor lines run, and $.evalFile runs a file
2026-11-11 14:31:44 +07:00
BFlat 6a5854ec5f Merge pull request #6533 from dotCooCoo/fix/char-style-tint-names
Character Styles: the Fill and Stroke Tint fields have distinct names
2026-11-11 14:23:48 +07:00
BFlat 3e642efce6 Merge pull request #6530 from dotCooCoo/fix/vertical-path-sideways-glyphs
Type: on a vertical path, letters lie a quarter turn clockwise from upright glyphs, in a column centered on the path
2026-11-11 14:22:33 +07:00
BFlat dac55268e3 Merge pull request #6529 from dotCooCoo/fix/store-put-size-bound
Stores: saving a preset, profile or plug-in reads at most one byte past it from the file it replaces
2026-11-11 14:17:50 +07:00
BFlat 298523348d Merge pull request #6531 from dotCooCoo/docs/roadmap-duplicate-rows
Docs: the roadmap lists each milestone once
2026-11-11 14:13:17 +07:00
BFlat fe346e53be Merge pull request #6527 from dotCooCoo/fix/dimension-follow-both-ends
Dimension tool: both ends of a dimension follow the art it measures
2026-11-11 14:03:40 +07:00
dotCooCoo 9bfd6b7be5 Paths: describe the anchor added on a selected segment as an end of its halves
A selected segment that path.insertAnchor splits stays selected as its
two halves. The new anchor is the end both halves share, so it moves
with them, and Delete cuts both halves. docs/mcp.md and the comment on
renumber_after_insert called it a direct-selected anchor; they now
describe it as an end of the halves that moves with them.
2026-11-10 23:00:40 -08:00
jmvergesandClaude Opus 5.5 6701a1f8e5 .ai import: stroked type in an envelope maps from its glyphs grown by half its stroke
With Distort Appearance, the stroked candidate for type in an envelope
mapped from the type's bounds with strokes, which for a stroke on the
type's appearance (or on a group round it) reach as far as a miter join
may at a corner, the miter limit times half the weight. In users' files
the drawn art maps from the glyphs grown by what the strokes paint along
a side: half the weight of a centred stroke. The candidate now uses that
box. Character strokes keep the measure the type's bounds with strokes
already give them (they have no miter allowance), and other objects in
the contents keep their bounds with strokes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 06:49:26 +00:00
dotCooCoo 08387a22ec Merge main into feat/script-include-directives 2026-11-10 22:39:32 -08:00
BFlat 8b6c7444be Merge pull request #6524 from dotCooCoo/fix/native-open-budget-no-reread
Native files: a document past a read budget is refused after one read
2026-11-11 13:38:32 +07:00
dotCooCoo 1f1b7a8b7c Scripts: test that an include ending in a carriage return keeps the next line's number 2026-11-10 22:36:45 -08:00
dotCooCoo 548fb9aa61 Docs: the roadmap lists each milestone once
Merges of main kept both sides of conflicting edits to the milestone
table, so M3, M7, M10, M11 and M13 appeared two to four times, each
copy with a different subset of later edits. Keep one row per
milestone. For M3, M10, M11 and M13 the kept row already contains every
statement in the removed copies. For M7 no copy held them all: the kept
row gains the Hyphenation and Justification clause that only the
second copy carried.
2026-11-10 22:35:21 -08:00
BFlat b421c03d03 Merge pull request #6525 from dotCooCoo/feat/scripts-folder
Scripts: File › Scripts lists the Scripts folder, subfolders as submenus
2026-11-11 13:33:56 +07:00
dotCooCoo 4110f8c24e Reshape: a step recorded without focal points plays by the earlier rule
Before the Reshape tool had focal points it sent path.reshape without
focal or radius, and the command stretched an open path from the grabbed
point to its ends whatever the selection, and moved the anchors of a
closed path within half the diagonal of its bounding box with a
falloff. Such a step, in a saved action or a script, now moved a closed
path whole. A step without focal (or with focal null) and without
radius now plays by that earlier rule. The Reshape tool always sends
focal, an empty list included, so its drags keep the focal-point rule.
2026-11-10 22:30:19 -08:00
dotCooCoo 76517afebc Character Styles: the Fill and Stroke Tint fields have distinct names
The two Tint fields in the Character Color section were both named
"Tint", so a screen reader gave no way to tell the Fill field from the
Stroke one. They are now named "Fill Tint" and "Stroke Tint"; the
visible caption stays "Tint". The names have rows in every catalog, and
a test checks both names in Character Style Options and New Character
Style.
2026-11-10 22:28:01 -08:00
dotCooCoo 5a8a57d5f6 Type: upright glyphs on a vertical path keep vertical point type's cells, and the caret spans the column
On a vertical path, an upright glyph is now placed in its column as
vertical point type places it, then the column is centered on the path.

- Its cell starts at its place on the path; it started 0.12 em earlier
  with fonts whose cell top is less than a full cell above the baseline.
- A baseline shift moves it across the column instead of along the path.
- A horizontal scale widens it evenly about the column's center.
- A combining mark stays on its upright letter.
- The caret and the selection highlight span the column, half its em on
  each side of the path, instead of the font's ascent and descent.

With Skew, 3D Ribbon and Stair Step on a path that runs to the left,
letters are a quarter turn counterclockwise from upright glyphs: Skew and
3D Ribbon mirror both kinds there, and Stair Step keeps letters level. The
test, the progress doc and the params text of Tate-chu-yoko Settings now
state these conditions and the block's directions on a path.
2026-11-10 22:27:53 -08:00
dotCooCoo fdbf85d4c8 Stores: saving a preset, profile or plug-in reads at most one byte past it from the file it replaces
Before writing a PDF preset, ICC profile, plug-in, Color Settings,
disabled list or grants file, the store compared the new bytes with the
file already there by reading the whole file into memory, so a large file
left in the folder was read in full. The comparison now reads at most one
byte more than the new content.
2026-11-10 22:24:39 -08:00
BFlat 9f44e37274 Merge pull request #6522 from dotCooCoo/fix/thumbnail-render-options
Render: node renders and thumbnails follow the supersample and precise options
2026-11-11 13:21:40 +07:00
BFlat 663f3434d7 Merge pull request #6523 from dotCooCoo/fix/render-document-composite-fonts
Render: type in a document's own composite font draws in its definition
2026-11-11 13:17:10 +07:00
dotCooCoo f4496d61aa Paths: Add Anchor Point keeps the same anchors and segments selected
path.insertAnchor (the Add Anchor Point tool, the Pen's Auto Add, the
Smart Pen's Alt-click on a segment and Alt-click with the Scissors)
added the anchor without changing the selection, so the direct-selected
anchors and selected segments after it on the subpath kept their old
numbers and the selection shifted onto the next points along. It now
renumbers them with renumber_after_insert, the helper path.reshape
uses. A selected segment that the new anchor splits stays selected as
its two halves, and the new anchor is direct-selected with them. Undo
restores the path and the selection in one step.

Docs: params text, docs/mcp.md, docs/target-app-parity.md.
2026-11-10 22:17:08 -08:00
dotCooCoo fd9c7a2073 Merge main into feat/script-include-directives 2026-11-10 22:13:57 -08:00
BFlat 99cbdf9b73 Merge pull request #6520 from dotCooCoo/fix/break-link-selects-only-selectable-art
Symbols: Break Link selects no art inside a hidden or locked group
2026-11-11 13:05:00 +07:00
dotCooCoo 693031c509 Scripts: #include and the other preprocessor lines run, and $.evalFile runs a file
Before a script runs, `script.run` reads its preprocessor lines (`#` or
`//@` at the start of a line, outside strings and comments):

- `#include` and `//@include` put another file's text in place of the
  line, looked for beside the including file, then in each
  `#includepath` folder, then in each `JSINCLUDE` folder. A later
  `#includepath` replaces the list.
- `#script` names the run unless `name` is given; `#target` takes any
  value; `#strict off` is taken. `#strict on`, `#targetengine` and
  `#engine` are refused as unsupported, and any other `#name` as
  unknown.

`$.evalFile(path, timeout?)` runs a file in the same global environment
and returns its last value, `$.fileName` is the file being run and
`$.includePath` the include folders.

A script run from a file reads these files only in its folder and the
folders below it. Paths with a `..` name, links or junctions that lead
out, device names, streams and network paths are refused; a script
given as text reads none. A run reads at most 64 files 16 levels deep,
32 MiB of source in all and 1,024 paths looked up. An error in an
included or evaluated file is reported at that file's line and column,
and the report's new `file` field names it.

Docs: docs/mcp.md (script.run, Script Console), docs/target-app-parity.md.
2026-11-10 21:59:22 -08:00
BFlat 0695db3ec0 Merge pull request #6519 from dotCooCoo/feat/reshape-focal-points
Reshape: a click sets a focal point and a drag moves every focal point
2026-11-11 12:53:37 +07:00
dotCooCoo 5452b516f6 Render: type in a document's own composite font draws in its definition
Raster renders, ink renders, thumbnails and node renders now lend the
document's composite fonts to the font database while they draw, as the
PDF, SVG and EPS writers already do. A document that is not in front, a
document read from a file (library thumbnails, save previews) and a
placed document's art drew such type in the fallback font or in another
definition of that name.
2026-11-10 21:39:36 -08:00
dotCooCoo 75fc513a6f Native files: a document past a read budget is refused after one read
When the pass that reads the document and the saved PDF preference
together failed with a data error, open read the whole document a second
time without the preference. A document past a read budget, or with any
other data error, was then read up to the budget again before it was
refused. Open now reads it again only when the first pass stopped at a
pdfCompatible that is not a boolean, which it tells by reading the
preference alone over the bytes up to the first pass's error position.
2026-11-10 21:37:49 -08:00
dotCooCoo f8307b19cd Type: on a vertical path, letters lie a quarter turn clockwise from upright glyphs, in a column centered on the path
Follows #5557. Letters and digits lying on their side in vertical type on
a path kept their top toward the path's end, opposite the upright glyphs.
They are now set as horizontal type on the path sets them: baseline along
the path, top to the path's left, a quarter turn clockwise from upright
glyphs (CSS Writing Modes 3, Unicode UAX #50).

- The column is centered on the path: upright glyphs, letters on their
  side and tate-chu-yoko blocks have their em box centers on the path
  line instead of a column one em wide to the path's right.
- Upright glyphs are turned in the path effect's glyph space, so with
  Skew on a curve their top runs back along the tangent and their x axis
  stays up the page, as letters keep theirs.
- Tate-chu-yoko blocks on a path stand upright, stay whole on a curve and
  move by Tate-chu-yoko Settings toward the path's start and left.
- A tate-chu-yoko block of mixed sizes sets every glyph in its first
  character's em, on a path and off it.

Existing vertical type on a path redraws with these placements.
2026-11-10 21:36:30 -08:00
dotCooCoo eaaf1155a8 Render: node renders and thumbnails follow the supersample and precise options
render_node_with and render_node_thumbnail_with ignored RenderOptions::supersample
and RenderOptions::precise, so the Asset Export tiles, which ask for both, were drawn
with the canvas's shape-by-shape edges and the fast render mode instead of the export's
look. A node render now supersamples Art Optimized edges as a page render does, and
picks the quality render mode when precise is set, for the art's offscreen groups too.
2026-11-10 21:35:47 -08:00
BFlat b34c652a60 Merge pull request #6514 from ruchirguitar/fix/5820-general-units-for-unitless-files
#5820: files that record no units open in Preferences › Units › General
2026-11-11 12:35:44 +07:00
BFlat 10f6f4ffb2 Merge pull request #6518 from dotCooCoo/fix/char-style-basic-names
Character Styles: the style dialogs' fields have accessible names
2026-11-11 12:31:01 +07:00
BFlat ac33652fe3 Merge pull request #6516 from dotCooCoo/fix/menu-scroll-wrap
Menus: a scrolling list keeps each label on one line
2026-11-11 12:26:41 +07:00
dotCooCoo ef6d14dc22 Dimension tool: both ends of a dimension follow the art it measures
A linear dimension clicked from an anchor to a point that is not an
anchor (a point on a segment, or a point a Smart Guide gave) followed
the art at the anchor end only, so scaling the art turned it into a
long slanted dimension.

- A point on a segment is stored by its curve parameter on that
  segment, and stays on it when the segment's anchors or handles are
  edited.
- Any other point is stored against anchors (and, for a path whose
  anchors lie on one line, handles) of the path under it, or of the
  path at the other end, and moves, scales, turns and reflects with
  that path. Beside a path whose anchors and handles all lie on one
  line, such as a straight line, it keeps its distance along and
  across the path: a reflection moves it as a half turn does, and a
  scale that is not uniform moves it as a uniform scale does.
- When linked art is reflected, a linear dimension's line goes to the
  reflected side, except for art whose anchors and handles lie on one
  line.
- Deleting the art, changing its anchor count or whether it is closed,
  turning an angle's arm into a curve, or making a measured circle or
  arc no longer circular leaves the dimension where it was, no longer
  linked, instead of removing it. Undo links it again.

Docs: docs/dimensions.md, docs/target-app-parity.md.
2026-11-10 21:25:59 -08:00
dotCooCoo d069e0e4be Symbols: Break Link selects no art inside a hidden or locked group
Break Link to Symbol on a selected group selected the art of every
instance it expanded that was itself shown and unlocked, including art in
a hidden or locked group inside the selection. The art now goes into the
selection only when it and every group and layer holding it are shown and
unlocked, the check Select All uses (select::is_selectable).
2026-11-10 21:08:57 -08:00
dotCooCoo 561dcb20d3 Docs: the Scripts folder lines say which path each command checks and which platforms read it on File 2026-11-10 21:08:32 -08:00
dotCooCoo 39996d3d2c Merge main into feat/scripts-folder
# Conflicts:
#	crates/engine/src/cmd/scripts.rs
#	crates/engine/src/tests.rs
#	docs/gaps.md
#	docs/mcp.md
#	docs/target-app-parity.md
2026-11-10 21:08:10 -08:00
BFlat 22ec820569 Merge pull request #6513 from dotCooCoo/fix/break-link-keeps-hidden-locked
Symbols: Break Link keeps a hidden or locked instance's art hidden or locked
2026-11-11 12:00:47 +07:00
dotCooCoo c676051641 Character Styles: the style dialogs' fields have accessible names
The text fields and menus of the Basic Character Formats, Advanced
Character Formats, Character Color and OpenType Features sections, and
the Style Name field of Character Style Options, are now named by the
label beside them, so screen readers announce them. This covers both
Character Style Options and New Character Style, which share the
sections. The New Character Style UI test runs with the accessibility
check on again, and a new test opens every section of both dialogs and
checks that no input is unnamed.
2026-11-10 20:53:24 -08:00
BFlat acc6acfdb2 Merge pull request #6266 from Silvertree2010/fix/h13526-graph-csv-round-trip-drops-a-bla
Keep blank value row in single-column graph CSV round trip
2026-11-11 11:52:07 +07:00
BFlat 3e780a8026 Merge pull request #6512 from dotCooCoo/fix/native-open-pdf-preference-one-pass
Native files: open reads the PDF preference in the same pass as the document
2026-11-11 11:51:57 +07:00
ruchirguitar 52918add2d #5820: keep ruler units the EPS program header gives when the editing data has none 2026-11-11 10:12:00 +05:30
BFlat bc814012d9 Merge pull request #6511 from dotCooCoo/feat/artboard-color-labels
Artboards: an artboard's guide label colors its own guides
2026-11-11 11:27:16 +07:00
ruchirguitar f5daa27a2f #5820: files that record no units open in Preferences › Units › General
A PDF, an EPS or .ai without ruler units, a raster image, a metafile, an
Affinity file or an importer plug-in's document opened (and reverted) in
points whatever the General unit was. They now open in the General unit,
as the reference app opens files that record no unit. Native, SVG and DXF
files and a .ai or EPS with %AI5_RulerUnits keep their own units. Only the
displayed units change, not the art.
2026-11-11 09:56:19 +05:30
dotCooCoo 549391a50d Menus: a scrolling list keeps each label on one line
A popup measures its list on the first frame, when the scroll area does
not yet show its bar. When the bar then appeared, its column took its
width from the items, and the widest label wrapped onto two lines:
Distort & Transform in the Add New Effect menu, and Black and White Logo
in the Image Trace presets, in short windows.

menu_scroll now lays the items out at least as wide as on the popup's
first frame, so the bar's column widens the popup instead. That width
is kept until the popup closes and is never wider than the window has
room for. The items are laid out in the same child Ui on every frame,
so their ids do not change when the width does.
2026-11-10 20:23:42 -08:00
dotCooCoo bd39674469 Reshape: a click sets a focal point and a drag moves every focal point
A click with the Reshape tool on an anchor of a selected path makes it
the focal point, and a click on a segment adds an anchor there that
becomes the focal point. Shift-click adds an anchor or a point on a
segment to the focal points, or removes an anchor that is one already.
Each focal point shows a filled anchor square in a larger hollow one.
A drag from a focal point moves all of them; a drag from another point
moves that point alone, and Shift only keeps the drag's angle.

path.reshape takes the other focal points as focal: [[subpath,
anchor]...]. Anchors that are not direct-selected stay in place, and so
do the ends of an open path unless they are focal points. A selected
anchor between two focal points moves by the whole drag, and one
between a focal point and an anchor that stays takes u² (3 - 2u) of
the drag, as before. A closed subpath with every anchor selected moves
whole: a Reshape drag on a fully selected closed path, and path.reshape
without radius on a closed path selected whole or not selected, move
the whole path instead of a local area. With radius, only the grabbed
point's subpath changes, with the falloff as before.

- An anchor added on a segment of a partly selected path is selected,
  and the selected anchors and segments after it keep their points.
- A focal pair that names no anchor is refused ("`focal` names [0, 7],
  which is not an anchor of the path"), and so is focal with radius.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-10 20:18:23 -08:00
NetterSilverandClaude Haiku 5.5 aaf27e1ec6 Keep blank value row in single-column graph CSV round trip
Found while testing crates/engine/src/cmd/graph/data.rs:51 (parse_csv); written by crates/doc/src/graph.rs:497 (GraphSpec::to_csv)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-11 04:16:30 +00:00
dotCooCoo 2faadd28f4 Symbols: Break Link keeps a hidden or locked instance's art hidden or locked
Break Link to Symbol on a selected group, and Delete Symbol with its
instances expanded, turned a hidden or locked instance into visible,
unlocked art. The art now keeps the instance's hidden and locked state,
as Object > Expand does, and Break Link leaves hidden or locked art out of
the selection.
2026-11-10 20:09:28 -08:00
BFlat 726d2b6e13 Merge pull request #6508 from jmverges/fix/3179-warps-of-type-as-mesh
.ai import: warps of type open as mesh envelopes on their saved grid
2026-11-11 10:48:16 +07:00