Commit Graph
3171 Commits
Author SHA1 Message Date
BFlat f83d916d8a Merge pull request #6631 from Hassan1305/docs-6340-rotation-direction
Commands: every angle and rotation param says which way it turns (#6340)
2026-11-12 01:32:17 +07:00
BFlat 210e9ad7d0 Merge pull request #6632 from dotCooCoo/feat/ruler-guides-as-objects
Guides: ruler guides are document objects on their layers
2026-11-12 01:32:07 +07:00
dotCooCoo 5ac7d97d85 Guides: ruler guides are document objects on their layers
Ruler guides were a list kept beside the layers. Each guide is now an
object of its layer or sublayer, always directly in it and above the
layer's art. These behave as on main:

- Guides draw on screen only. Exports (SVG, PDF, PNG, PSD), Fit All,
  Select All, the art bounds, clicks and marquees, and a layer's
  Pathfinder and Transform effects leave them out. The Layers panel
  lists them as guide rows of their layer, the highest guide.list
  index first.
- Deleting a layer deletes its guides, and merging layers keeps their
  guides in the merged layer.
- The guide commands number guides as guide.list does, in the order
  they were made.

New: each guide takes an id from the document's object ids. An object
command given a guide's id fails with an error, and node.move cannot
put a guide into a group or out of its layers. A guide made while an
opacity mask, a symbol or a pattern is edited moves to the top
visible, unlocked layer when editing ends.

File format: native files still save the guides in the document's
guides list, in every file version, so older builds read them. Each
entry may now also carry the guide's id, name, locked and hidden
flags; older builds ignore those fields. Opening a file puts each
saved guide on its layer (on the top visible, unlocked layer when the
file names none or a layer it does not have), and each saved guide
counts against the object limit for opening a file. A ruler guide node
that a file holds below a layer's art moves up to the layer's guides,
and one anywhere else (in a group or another object, beside the
layers, or in a symbol) is removed. Ruler guides read from an .ai file
become guide objects on the layer they were on, numbered in the order
the file lists them.
2026-11-11 09:52:28 -08:00
BFlat ad70adf96e Merge pull request #6624 from Messhias/feat/g5-symbol-lib-skill-icons
G5: built-in Skill Icons symbol library
2026-11-12 00:50:41 +07:00
BFlat 25433ede65 Merge pull request #6619 from jmverges/fix/6610-aligned-lines-trailing-tracking
Type: aligned lines leave the tracking after their last character out
2026-11-12 00:39:30 +07:00
BFlat 61acb79de3 Merge pull request #6620 from storytold/fix/sec-links-shared-reads
Links: groups of one file share one decoded image per operation
2026-11-12 00:21:59 +07:00
Fabio William Conceição f07c2f7e9c G5: built-in Skill Icons symbol library
Five symbol libraries; MCP docs list Skill Icons with the other generated symbol libraries.
2026-11-11 17:08:39 +00:00
BFlat 29207e507d Merge pull request #6611 from dotCooCoo/fix/plugins-folder-cleared-forgets-folder
Plug-ins: setting the plug-ins folder again after clearing it installs its plug-ins
2026-11-11 23:46:01 +07:00
Dylan M. Taylor ec9169591a Links: groups of one file share one decoded image per operation 2026-11-11 16:42:19 +00:00
HassanKhan b3860bf7d0 Commands: every angle and rotation param says which way it turns (#6340)
The params docs now state the direction (and the zero) of each angle or
rotation a command takes; behaviour is unchanged. Shape creation, text.create,
the grids, add-on shapes, saved views, Liquify, Puppet Warp pins, Mirror and
Radial Repeat and Vector Halftone turn clockwise; text character rotation,
gradients, the eraser tip and print screen angles turn counter-clockwise.

view.saved.new's rotation note changes its schema, so the API level goes to 3.

A test walks every command's params doc and fails when a param named like an
angle or rotation doesn't say clockwise or counter-clockwise.
2026-11-11 21:40:27 +05:00
jmverges 352b488b12 Merge remote-tracking branch 'upstream/main' into fix/aligned-lines-trailing-tracking
# Conflicts:
#	docs/file-format-parity.md
2026-11-11 16:38:59 +00:00
BFlat caaf261e9f Merge pull request #6605 from dotCooCoo/fix/gradient-stop-symbol-part
Gradients: picking a part of a symbol instance leaves no gradient stop selected
2026-11-11 23:25:06 +07:00
jmvergesandClaude Opus 5.5 9f80b4daae Type: aligned lines leave the tracking after their last character out (#6610)
A centred or right-aligned line of tracked type was measured with the
tracking after its last character, so it sat half that tracking
(centred) or the whole tracking (right-aligned) left of where the page
of users' .ai files draws it. That page aligns a line as wide as its
characters without that tracking.

Shaping now records the tracking each glyph's advance holds
(SGlyph::tracking), and a line that isn't justified leaves its last
character's out of the width it is aligned by. The last character is
the last one the line draws before a paragraph's end, a forced line
break or the spaces a wrap leaves; spaces or a tab typed before a
paragraph's end or a forced line break keep the letter's tracking, as
the page does. Forced line breaks and wraps aren't in the files: they
follow the rule so that turning a wrap into a paragraph or a forced line
break keeps the line in place. Hyphenated lines, lines whose last
character hangs, vertical and right-to-left lines and type on a path
keep it. The tracking stays in the glyph's advance, so the caret,
selections, line breaking and Fit Headline are unchanged.
LineInfo::trailing gives the amount. Right-aligned area type sets the
text after its last tab the same way.

What aligns by line widths follows. Convert To Area Type makes its
frame end where the lines are aligned, with room for the tracking, so
tracked type converted either way stays in place. Affinity import lines
up differently aligned paragraphs of artistic text by the aligned
widths. SVG import moves a centred or right-aligned letter-spaced line
back by its share of the last letter spacing, so it stays where a reader
draws it and SVG export, which anchors lines at the end of their
advances, reads back unchanged.

Centred and right-aligned tracked type lays out differently than before
in every document.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 16:07:40 +00:00
dotCooCoo 8eb3788eba Plug-ins: setting the plug-ins folder again after clearing it installs its plug-ins
Clearing Preferences > Plug-ins & Scratch Disks > Additional Plug-ins Folder
left the folder recorded as the one last loaded. Setting the same folder
again then matched that record, and nothing in it was installed, so a
plug-in removed in the meantime stayed removed. Clearing the preference now
forgets the folder when it is the one last loaded.
2026-11-11 08:07:27 -08:00
dotCooCoo b44cbdb048 Gradients: picking a part of a symbol instance leaves no gradient stop selected
A stop selected on a whole dynamic symbol instance's gradient stayed
selected after Direct Selection picked an object of that instance's art,
because the instance stayed the first selected object. The Gradient panel
kept the stop highlighted and the Gradient tool took Delete and the arrow
keys for it, while every gradient edit is refused for a picked object.

The stop's owner now records whether a part is picked, so the stop is not
selected while one is, and is selected again when the whole instance is.
2026-11-11 07:39:47 -08:00
dotCooCoo ac8e39fa2e Effects: a pasted SVG filter also takes a free punctuation character when no letter or digit is free
A filter's id can be any character, so when every letter and digit is in
use a pasted filter at the size limit with a one-letter name now tries the
other printable ASCII characters (`!` to `~`) before the paste is refused.
2026-11-11 07:26:02 -08:00
dotCooCoo f60da17d39 Effects: a pasted SVG filter also takes a free capital letter when no lowercase name is free
Filter names are case-sensitive, but a pasted filter at the size limit with a
one-letter name only tried the letters a to z and the digits 0 to 9 as a new
name. A paste was refused while every capital letter was still free. It now
also tries A to Z.
2026-11-11 07:26:02 -08:00
BFlat 9fc43f2a35 Merge pull request #6598 from dotCooCoo/fix/pasted-svg-filter-brush-names
Effects: a pasted SVG filter avoids brush effect names and is refused with no free name
2026-11-11 22:10:15 +07:00
dotCooCoo e0e361a834 Effects: a pasted SVG filter avoids brush effect names and is refused with no free name
Follows #6592. Paste now also skips the names that effects in the
document's brush art use when it picks a free name for a pasted SVG
filter. When no free name keeps the filter within the 64 KB limit (a
one-letter name at the limit with every free letter and digit taken),
the paste is refused instead of keeping the name of the document's
filter. Clipboard::import_into and import_text_styles return a Result,
and their callers pass the error on before the document changes.
2026-11-11 06:08:58 -08:00
dotCooCoo 48e342f03b Merge main into feat/script-dollar-object 2026-11-11 05:55:39 -08:00
BFlat 2d90cda199 Merge pull request #5493 from storytold/fix/sec-effects-paint-dash-budget
Effects: bound 3D paint copies, dash restarts and trap candidate pairs
2026-11-11 20:36:20 +07:00
BFlat 8353e8fdd3 Merge pull request #6562 from dotCooCoo/fix/script-console-report-text
Script Console: report lines match script.console, counts of one are singular, every run ends
2026-11-11 20:36:11 +07:00
BFlat c064ded1d1 Merge pull request #6592 from dotCooCoo/fix/pasted-svg-filter-free-name
Effects: a pasted SVG filter is not renamed to a name the document's effects use
2026-11-11 20:28:20 +07:00
BFlat 3f8b10afdf Merge pull request #6588 from dotCooCoo/fix/rasterize-side-rounding
Rasterize: art that rounds to 32,768 pixels a side is no longer refused
2026-11-11 20:13:57 +07:00
BFlat f242b0752f Merge pull request #6590 from dotCooCoo/fix/text-style-leading-strict
Type: text.setStyle refuses a leading with trailing text
2026-11-11 20:08:46 +07:00
dotCooCoo f77fe0423f Merge main into fix/script-console-report-text 2026-11-11 04:58:29 -08:00
Dylan M. Taylor a8f5549fd5 Merge branch 'main' into fix/sec-effects-paint-dash-budget 2026-11-11 12:55:22 +00:00
dotCooCoo ccf153dccc Merge main into feat/script-dollar-object 2026-11-11 04:52:37 -08:00
dotCooCoo c746841839 Scripts: $.error keeps the last error thrown, and $.sleep throws in callbacks on the web
An exception that a finally block passes on, or one that leaves a
built-in's callback, no longer becomes $.error again over an error thrown
after it; throwing a caught error again still makes it the last one.

$.sleep with more than 0 inside a getter, a conversion or a built-in's
callback now throws whether or not the platform has a clock, so the web
build throws there as the other builds do.
2026-11-11 04:48:13 -08:00
dotCooCoo 08efd91360 Effects: a pasted SVG filter is not renamed to a name the document's effects use
Paste renamed a pasted SVG filter to a name no filter of the document
held, but an effect could still use that name, for example after its
filter was deleted. Defining a filter of that name later changed both
effects. Paste now also skips the names the document's effects use,
read only when a pasted filter needs a new name.

A new name with a tab, line feed or carriage return was written into
the filter's id as is, which XML reads as a space, so the id no longer
matched the effect's name. svg_filter::with_id now writes those
characters as character references, and paste takes a name only when
the filter's id reads back as that name.
2026-11-11 04:44:54 -08:00
BFlat a2e34903e9 Merge pull request #6577 from dotCooCoo/fix/script-rethrown-error-place
Scripts: an error $.evalFile could not run, caught and thrown again, is reported where it was thrown again
2026-11-11 19:44:23 +07:00
dotCooCoo 07664847bd Type: text.setStyle refuses a leading with trailing text
`leading: "12abc"` set 12 pt leading and returned success, while `size`
and `tracking` in the same command refused trailing text. `leading` now
reads its value with `length_given`, so a string must be a whole number
or a length with a unit. The error message is unchanged.
2026-11-11 04:24:11 -08:00
dotCooCoo af22ac8f50 Scripts: $.stack names a declared function after its declaring function returns
The compiler now keeps a function declaration's name with its code, so
$.stack no longer shows [anonymous] for a declared function that is
called after the function that declared it has returned. The member test
expects "Web" for $.os in the wasm build, as the engine gives there.
2026-11-11 04:23:32 -08:00
BFlat 8ea341d57f Merge pull request #6579 from dotCooCoo/fix/legacy-ai-flatten-side-limit
Legacy .ai export: a long transparent image is flattened whole
2026-11-11 19:15:04 +07:00
BFlat e8a570cb0e Merge pull request #6578 from dotCooCoo/fix/print-bitmap-side-limit
Print: Print as Bitmap prints all of a page longer than 32,768 pixels
2026-11-11 19:05:50 +07:00
dotCooCoo 80b452ad6c Rasterize: art that is exactly 32,768 pixels a side at the resolution is accepted
The side limit compared the region's height in points times the scale
with 32,768. Far from the origin the snapped region can come back a
fraction of a pixel over, so art that the renderer draws at exactly
32,768 pixels was refused (a rectangle at y = 100,000 rasterized at
400 ppi). The check now uses the renderer's own rounded pixel width and
height.
2026-11-11 04:00:39 -08:00
BFlat a5a42e45ac Merge pull request #6576 from dotCooCoo/fix/pasted-svg-filter-size-limit
Effects: a pasted SVG filter at the size limit still draws under its new name
2026-11-11 19:00:06 +07:00
dotCooCoo c8475771b9 Merge main into fix/script-rethrown-error-place 2026-11-11 03:59:08 -08:00
dotCooCoo d50ea29772 Merge main into feat/script-dollar-object 2026-11-11 03:58:05 -08:00
dotCooCoo 2b88f31a7d Merge main into fix/script-console-report-text 2026-11-11 03:56:06 -08:00
BFlat 4fc8517215 Merge pull request #6574 from dotCooCoo/fix/graph-labels-empty-middle-line
Graphs: centered labels with an empty middle line stay centered
2026-11-11 18:51:23 +07:00
BFlat c443a25016 Merge pull request #6569 from dotCooCoo/feat/script-strict-on
Scripts: #strict on runs the script with strict write checks instead of refusing it
2026-11-11 18:45:03 +07:00
BFlat 0398c85b14 Merge pull request #6575 from dotCooCoo/fix/opened-thread-composite-fonts
Type: an opened file flows its threads in its own composite fonts
2026-11-11 18:40:32 +07:00
BFlat 4483fcfaa7 Merge pull request #6572 from dotCooCoo/fix/command-sweep-path-params
Tests: the command sweep sends file and folder params only into its temp folder
2026-11-11 18:35:45 +07:00
BFlat 7e9633e3cb Merge pull request #6573 from dotCooCoo/fix/rasterize-side-limit
Rasterize: art longer than 32,768 pixels at the resolution is refused, not cut off
2026-11-11 18:35:36 +07:00
dotCooCoo baf8056c5f Merge main into fix/script-console-report-text 2026-11-11 03:28:54 -08:00
BFlat 212bc9f837 Merge pull request #5457 from Taha-Mahmoodi/fix/ruler-double-click-guide
Fix #5239: double-clicking a ruler adds a guide there
2026-11-11 18:24:56 +07:00
BFlat 31971bc090 Merge pull request #6555 from dotCooCoo/feat/plugin-effect-open-budget
Plug-ins: live effects of a document's first view share a 2,000 ms budget
2026-11-11 18:22:28 +07:00
dotCooCoo ea0dd5fda5 Legacy .ai export: a long transparent image is flattened whole
Saving a legacy .ai of version 7 flattens each transparent image at its own
resolution, limited only by total pixels. The renderer draws at most 32,768
pixels a side, so an image that came out longer than that at its resolution
was cut off and placed as if whole: the part past that length showed the art
under it without the image. The resolution is now lowered until the longest
side fits.
2026-11-11 03:22:06 -08:00
dotCooCoo 68f3095cfd Print: Print as Bitmap prints all of a page longer than 32,768 pixels
Print as Bitmap limited each page's image to 65,535 pixels a side, but the
renderer draws at most 32,768. A 9000 x 100 pt artboard at a 300 ppi raster
effects resolution printed as an image that stopped at 7,864 pt and was
placed as if whole. The resolution is now lowered until the longest side
fits.
2026-11-11 03:21:57 -08:00