Commit Graph
4895 Commits
Author SHA1 Message Date
dotCooCoo 1567957482 Smooth tool: an open path's end turns with the smoothing when a drag reaches it
When a Smooth tool drag refits the stretch at the first or last anchor
of an open path, the curve there now leaves or arrives along the
smoothed path within the tool's reach instead of along the first or
last segment, so a jagged end no longer keeps its jag. The end point
stays where it is. An end where the smoothed path turns back by 90
degrees or more keeps its segment's direction, and a stretch that ends
inside the path keeps the direction of the part outside the drag.

- pathops: SimplifyOptions gains free_start and free_end, off by
  default; closed subpaths and simplify_part ignore them, so Simplify
  and Object > Path > Smooth give the same output as before.
- engine: path.smoothRegion sets them for the ends of an open path
  that a run's refit reaches.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-13 11:51:02 -08:00
dotCooCoo b7709a3c1f MCP: SVG export by a confined caller refuses script links outside its read roots
An SVG or SVGZ writes each linked JavaScript file of SVG Interactivity
into a <script xlink:href> element as stored, so a caller with
automation read roots could read a path outside them from the exported
text. With read roots in force, an SVG or SVGZ of a document that links
such a file is now refused with "a linked JavaScript file is outside the
read roots", an error that names no file or folder. No file or folder is
written, and the document keeps the link.

- The check uses the rule document.json already applies to
  svg_scripts: a relative path is taken from the document's folder, a
  file: URL is a file, and another URL is not checked.
- It covers document.serialize, document.export, document.exportSelection,
  document.exportForScreens and assets.export (before the folder is made
  or any row is written), the SVG and SVGZ saves (also a save without a
  path of a document saved as SVG), file.exportAs and the SVG Options
  dialog's Show Code.
- Callers without roots, and the person at the keyboard, export the
  links as stored.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-13 11:46:18 -08:00
dotCooCoo e1a918636e Document Info: values show in the interface language
The panel showed the values Document Info makes in English in every
language. It now shows the Units, the Raster Effects resolution, each
font's file, substitution and embedding permission, each image's size
and linked file, each Repeat object's kind and counts (in the
language's plural forms) and gradients named by their kind in the
interface language. Font, face, file and swatch names stay as they
are, a gradient swatch named like a kind included.

document.info keeps its English rows and adds the values the panel
builds them from: document.unitId, fontDetails, imageObjects and a
kinds list on each gradientObjects entry. Save… and Package's report
stay in English.
2026-11-13 11:42:24 -08:00
dotCooCoo 51e8938374 Blob Brush and Eraser: the drag outline does a bounded amount of work per frame
The outline of the area a Blob Brush or Eraser drag covers was outlined
again for the whole stroke on every frame, so a long stroke slowed the
canvas as it grew.

- The drag is outlined in pieces of up to 32 segments (one segment each
  with Size set to Pressure), and a frame outlines again only the pieces
  it added segments to. A grid of squares lists the segments near each
  square, and each piece's outline drops the parts inside the rest of
  the area, so the pieces show as one edge.
- One frame takes at most 256 new points and a fixed amount of work;
  Tool::overlays_pending makes the canvas draw again until the rest is
  done with the pointer still. Points not outlined yet show as a thin
  line, and the tip shows at the pointer.
- The settled outline is kept in joined paths of 64 pieces, and a frame
  joins again only the paths that changed. The grid's size is capped.
- The Blob Brush's length label and the Size-by-pressure check keep
  running values instead of rescanning the stroke each frame. With Size
  set to Pressure the outline shows only the edge of the whole area.

The release sends the same path.blob and path.eraseRegion parameters.
2026-11-13 11:40:53 -08:00
dotCooCoo ae113557be Merge main into fix/docs-layers-row-menu 2026-11-13 11:40:52 -08:00
BFlat 08b6cfd3e8 Merge pull request #7227 from dotCooCoo/fix/hindi-variable-and-join-terms
i18n: Hindi uses one word for a variable and जोड़ें for joining paths
2026-11-14 02:40:46 +07:00
BFlat a105e14aef Merge pull request #7220 from dotCooCoo/feat/image-indexed-color
Edit Colors: convert embedded images to indexed color
2026-11-14 02:40:36 +07:00
BFlat 5f8e4c1913 Merge pull request #7240 from dotCooCoo/feat/smooth-reach-overlay
Smooth tool: the drag shows the band the tool smooths
2026-11-14 02:40:24 +07:00
BFlat 6e54257294 Merge pull request #7225 from dotCooCoo/fix/modal-blocks-canvas-touch
Touch: canvas taps, presses and view navigation are ignored while a modal dialog is open
2026-11-14 02:40:15 +07:00
BFlat 90a9e00fdd Merge pull request #7205 from dotCooCoo/fix/svg-interactivity-hide-script-paths
SVG Interactivity: replies name JavaScript files outside the read roots by file name
2026-11-14 02:40:06 +07:00
BFlat 3a7295e588 Merge pull request #7201 from dotCooCoo/fix/revert-drops-pending-place-reads
Place: File › Revert drops reads started for the content it discards
2026-11-14 02:39:57 +07:00
BFlat 95b328dcca Merge pull request #7193 from dotCooCoo/fix/trace-blur-rings
Image Trace: blurred edges no longer trace as rings of in-between colors
2026-11-14 02:39:47 +07:00
BFlat 58dd9e8908 Merge pull request #7230 from dotCooCoo/fix/docinfo-hidden-object-paints
Document Info: hidden objects and objects at an opacity of 0 list no brushes or paints
2026-11-14 02:39:39 +07:00
BFlat 34457735e5 Merge pull request #7231 from dotCooCoo/fix/threaded-type-measures-paths-and-aligned-frames
Type: threaded paths and frames aligned off the top measure the paragraphs they need
2026-11-14 02:39:29 +07:00
BFlat 821e2d0bb5 Merge pull request #7224 from dotCooCoo/fix/close-modified-background-tab-keeps-front
Documents: closing a modified background tab keeps the document in front
2026-11-14 02:39:19 +07:00
BFlat 4dc9c5c5d3 Merge pull request #7218 from dotCooCoo/fix/batch-fit-journal-index
Artboards: a batch's Fit to Artwork Bounds step journals the artboard it fits
2026-11-14 02:39:07 +07:00
BFlat aa6d9acc95 Merge pull request #7228 from dotCooCoo/fix/global-edit-docs-type-image-groups
Docs: Global Edit leaves out groups holding type or images
2026-11-14 02:38:55 +07:00
BFlat 38c0f3ed61 Merge pull request #7100 from dotCooCoo/fix/flatpak-clipboard-images
Clipboard: the Flatpak on GNOME copies and pastes pictures and SVG with other apps
2026-11-14 02:38:46 +07:00
BFlat f0c3646e90 Merge pull request #7198 from dotCooCoo/fix/area-type-band-coverage
Type: area type lines stay inside a frame that pinches in within their band
2026-11-14 02:38:38 +07:00
BFlat 1e385ba06e Merge pull request #7210 from dotCooCoo/fix/envelope-empty-type-box
Envelope: type that draws nothing adds no box next to other content
2026-11-14 02:38:27 +07:00
BFlat 858749d596 Merge pull request #7222 from dotCooCoo/fix/parity-doc-preferences-bullet
Docs: keep one Preferences progress bullet with the off default for Highlight Alternate Glyphs
2026-11-14 02:38:19 +07:00
BFlat b004977dba Merge pull request #7202 from dotCooCoo/fix/raster-effects-skipped-transform-budget
Effects: raster effects before a Transform effect past the budget stay with the art
2026-11-14 02:38:10 +07:00
dotCooCoo 5c0f22b345 Graphs: Appearance edits on a label are kept for every label of its kind
A fill or stroke row that the Appearance commands gave a graph label, its
object opacity, and the characters the Eyedropper gave it lasted only
until the graph was drawn again: the graph stored nothing for a label's
rows, and the Eyedropper's character attributes were not stored.

- The graph keeps, for value axis numbers, category labels and legend
  labels, the paint, weight, opacity and blend mode of a label's topmost
  visible fill and stroke row, their order and place relative to the
  Characters row, and the label's object opacity and blend mode
  (labelStyles valuesRows, categoriesRows, legendRows). Every label of
  the kind gets those rows when the graph is drawn again, with a placed
  gradient fitted to each label.
- Every appearance.* command stores them, and so do graphicStyle.apply
  and redefine and the paint, stroke, gradient and transparency edits
  aimed at a row, even when the label already showed them.
  transparency.set without a row and object.setProps store only the
  object opacity and blend mode. With several labels of a kind, the last
  one edited wins.
- appearance.copyFrom onto all of a label's text stores the character
  attributes it applied and, from type, the paragraph attributes; a
  transparency pick stores the object opacity and blend mode, and
  append stores the rows.
- paint.setFill and paint.setStroke store a character fill or stroke
  only when the characters take the paint (the whole label, or all of
  its text highlighted with the Type tool); aimed at a row, they store
  the row.
- Document Color Mode and swatch edits reach the kept rows.

Docs: docs/mcp.md, the commands' params text, docs/target-app-parity.md.
2026-11-13 11:35:27 -08:00
dotCooCoo b429b2937f Docs: one app.open row after the merge of main 2026-11-13 11:34:50 -08:00
dotCooCoo 1d35e00981 Live Paint and Shape Builder: tool.setOption refuses invalid options
tool.setOption for the Live Paint Bucket, the Live Paint Selection tool
and the Shape Builder used to keep the old value when a switch was not
true or false, a color could not be read or a width or gap length was
not a number, and it set the other values sent with it. It also took
the RGB of a color with an alpha part, and the Shape Builder took any
`pickColorFrom` other than `swatches` as `artwork` and any `selection`
other than `straightLine` as `freeform`.

The command now checks every value before it sets any, whether the tool
is chosen or not: a switch must be true or false, a highlight color
must be an RGB color or a layer color's name without an alpha part, a
width or gap length must be a number, `pickColorFrom` and `selection`
must be one of their names, and an option the tool does not have is an
error. The error names the option, and nothing is set or saved. A width
outside 1 to 20 and a gap length outside 0 to 72 are still clamped, and
saved settings with an invalid value still load.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-13 11:34:44 -08:00
dotCooCoo 18b879a5bc Merge main into fix/graph-series-paint-visible-rows 2026-11-13 11:30:16 -08:00
Drew Dibble 09d5522785 Merge remote-tracking branch 'upstream/main' into seam-round-joins
# Conflicts:
#	docs/effects-parity.md
#	docs/gaps.md
#	docs/target-app-parity.md
2026-11-13 12:29:58 -07:00
dotCooCoo 6326b17b0e Blend: spreading keys along a replaced spine measures it once
Giving the keys of a blend whose spine came from Replace Spine anchors of
their own flattened and measured the whole spine again for every key,
then walked its segments one by one. 1,000 keys on a spine of 4,096
segments flattened it 999 times.

The spine is now flattened once into one buffer. A split flattens only
its two halves and measures the segments after it again, in order, only
as far as the next key, so the arc lengths are summed as before and the
keys get the same anchors. A binary search finds each key's segment.

A spine so large that its length overflows no longer gets an anchor
split at a parameter that is not a number: spreading keys along it
returns nothing and leaves it as it was.
2026-11-13 11:21:31 -08:00
dotCooCoo 69deae55cf .ai import: straight paths twisted past 180° keep the drawn look
A path or compound path with straight segments and nothing stroked was
read with its Twist live at any angle. It is now read live up to 180°
either way, a limit VectorCraft sets, and one twisted further keeps the
file's drawn look, as curves and groups already do past 90°.

The .ai writer keeps a graphic-style link only where the reader reads the
style live, so a straight object twisted past 180° is now written without
the link, with the existing style-link warning.

Docs: docs/file-format-parity.md, docs/target-app-parity.md.
2026-11-13 11:21:08 -08:00
dotCooCoo b7dbb4b59c Merge main into fix/graph-series-paint-other-commands 2026-11-13 11:18:16 -08:00
dotCooCoo af91a37669 Merge main into feat/monitor-profile-windows-linux 2026-11-13 11:12:25 -08:00
dotCooCoo 7dc335b49d Merge main into fix/status-linked-files-keeps-notes 2026-11-13 11:11:31 -08:00
BFlat 630ef6f549 Merge pull request #7129 from dotCooCoo/fix/brush-library-names-translated
Brushes: built-in library panels show brush names in the UI language
2026-11-14 01:55:05 +07:00
BFlat e718e975b6 Merge pull request #7104 from dotCooCoo/feat/actions-record-into-selected
Actions: Begin Recording adds steps to the selected action, and a drag moves a step
2026-11-14 01:54:47 +07:00
BFlat 1664f6de66 Merge pull request #7139 from dotCooCoo/feat/ctb-type-tools-font-fill
Contextual Task Bar: the Type tools show font family, style, size and Fill
2026-11-14 01:54:39 +07:00
BFlat ca8e49e9e2 Merge pull request #7158 from dotCooCoo/fix/export-unused-option-warning
Export: warnings name an option the chosen format doesn't read
2026-11-14 01:54:29 +07:00
BFlat 820b82b8d3 Merge pull request #7188 from dotCooCoo/fix/color-gamut-cache-profile
Color: the out-of-gamut warning updates after a profile change
2026-11-14 01:54:13 +07:00
BFlat a8db64db47 Merge pull request #7208 from dotCooCoo/feat/live-paint-selection-cursors
Live Paint Selection: cursor shows a face, an edge or nothing to select
2026-11-14 01:54:04 +07:00
BFlat 5010861362 Merge pull request #7199 from dotCooCoo/fix/close-background-tab-keeps-front
Documents: closing a background tab keeps the document in front
2026-11-14 01:53:56 +07:00
BFlat 9bad58b73e Merge pull request #7215 from dotCooCoo/fix/new-profile-errors-hide-path
New Document profiles: errors name the profile file by its file name outside the read roots
2026-11-14 01:53:47 +07:00
BFlat 1c1bb2f96e Merge pull request #7191 from dotCooCoo/feat/gradient-hue-blend
Gradients: Hue Clockwise and Hue Counterclockwise mix stops around the hue wheel
2026-11-14 01:53:39 +07:00
BFlat 26869d1754 Merge pull request #7197 from dotCooCoo/fix/item-4498
Arrowheads: keep agents to the arrowheads file inside their read roots
2026-11-14 01:53:29 +07:00
BFlat 2370ad1b21 Merge pull request #7200 from dotCooCoo/fix/free-distort-constrain
Free Transform: Constrain keeps a Free Distort corner on its diagonal
2026-11-14 01:53:20 +07:00
BFlat edc4b712dd Merge pull request #7146 from jmverges/fix/7141-page-check-typed-envelopes
.ai and EPS import: envelopes of type stay live where other art differs from the page
2026-11-14 01:53:11 +07:00
BFlat d533018fd5 Merge pull request #7180 from ruchirguitar/feat/6740-type3-named-groups
feat(pdf): preserve Type 3 font text runs as named groups (#6740)
2026-11-14 01:53:02 +07:00
dotCooCoo 2aa7bbd791 Plug-ins: file-key exemptions name only params a command takes
A command now counts as taking a file or folder when its params
description (with the commands its `…` entries name) or its schema takes
a file key as a param. A word in the description's prose or result no
longer counts; a description whose keys are not known keeps the text
scan. The code of the call-time scan of arguments is unchanged, but it
reads the changed exemption tables. The confined run is unchanged.

- NOT_FILES drops seven entries that named no param of their command
  (object.setLiveShape path, path.reverse paths, object.pathfinder.options
  paths, object.maskImage path, imageTrace.make paths,
  svgInteractivity.info files, addon.cleanup.rejoin paths). A top-level
  `path` to object.setLiveShape or object.maskImage, `paths` to
  path.reverse, imageTrace.make or addon.cleanup.rejoin, and `files` to
  svgInteractivity.info are now refused.
- Image Trace's path fidelity setting is exempt only inside `params` and
  `savedPreset` of imageTrace.make and imageTrace.makeAndExpand, so a
  call with it is no longer refused.
- every_command_is_sorted checks that each exemption names a param its
  command takes, and that each nested exemption starts at one.
- effect.expandAsWireframes is reviewed as allowed and
  stroke.arrowheads.list as refused.
2026-11-13 10:50:53 -08:00
dotCooCoo 444f50a4c4 Objects on Path: each path is flattened once per placement or transform
stops and stop flattened the path twice, once for the points and once
for its length, and stop did both before rejecting an index past the
last object. place validated the path with attachable_path first, and
transform measured the old and new paths up to three times each.

A private Measured value now holds the flattened first subpath with its
length and closed flag, and path_length, stops, stop and transform use
it. stop returns None for an out-of-range index without measuring, and
a move of the group measures no path.

attachable_path now uses path_length, so a path whose length overflows
to infinity is no longer offered as one objects can attach to when
placement cannot measure it.
2026-11-13 10:50:24 -08:00
dotCooCoo d1f76ede8a Smooth: a drag along a segment smooths it when its anchors are out of reach
A Smooth drag along the middle of a curved segment smoothed nothing when
neither of the segment's anchors was within the reach, and paths of two
anchors were never smoothed.

- path.smoothRegion searches each curved segment where it can come
  within the reach, halving it down to pieces no longer than half the
  reach, and adds an anchor in the middle of each stretch in reach; the
  existing reach split then cuts the segment where the drag enters and
  leaves the reach. A drag that only grazes a curve finds the place on
  it nearest the drag. The search is bounded per drag and shared
  equally by the segments in reach.
- Paths of two anchors are smoothed, open or closed.
- Alt with the Paintbrush smooths a selected two-anchor curve; a
  two-anchor straight line still gets the closed stroke. Both sides use
  one segment_is_straight test.

Part of #2224
2026-11-13 10:44:19 -08:00
dotCooCoo e25795f73e Path Precision Tools: Trim at Crossings leaves clipping paths and art outside isolation alone
- The clipping path of a clip group or a clipped layer takes no part,
  the members of a compound clipping path included. Before, only a
  plain clipping path was left out.
- In isolation mode only paths inside the isolated object are trimmed;
  paths outside it still count as crossing.
- A rectangle or line that reaches so many paths that comparing their
  boxes would take more than 50,000,000 tests is refused before any
  work starts.
- A tool drag that goes 3 screen pixels or more from the press stays a
  rectangle or line when it ends near the press. Before, it ran as a
  click and could remove a whole path the final rectangle did not
  touch.

Docs: docs/mcp.md.
2026-11-13 10:44:07 -08:00
dotCooCoo 1dff3264f0 Docs: File formats area rows list the legacy .ai kerning, hyphen and language evidence
The current File formats rows of docs/target-app-parity.md now name the legacy .ai manual kerning, discretionary hyphen and hyphenation language reading and writing, with their tests. Score, gaps and hours are unchanged.
2026-11-13 10:42:02 -08:00