Commit Graph
111 Commits
Author SHA1 Message Date
BFlat e8aa3ae34c Merge pull request #7249 from dotCooCoo/fix/cleanup-selection-one-pass
Artwork Cleanup: update the selected objects in one pass after each fix
2026-11-14 03:22:08 +07:00
dotCooCoo 05500f7ddb Artwork Cleanup: update the selected objects in one pass after each fix
With the selection as its scope, a fix that removes or unwraps objects
(Needless Groups, Stray Points, Empty Text and the others) kept the list
of selected objects current by searching it and splicing it once for each
object it changed. Removing many selected objects above a long run of
others took time that grew with the square of their number.

The list is now rebuilt in one walk after each pass: each changed object
gives way to what replaces it, in its place, and the others keep their
order. The objects found, the counts, the document and the undo step are
the same as before.

Empty Artboards deleted each empty artboard with its own Vec::remove and
walked every ruler guide again for each one. It now drops the empty
artboards in one walk and deletes their guides in one more. The same
artboards and guides are deleted as before.

Tests cover the order after unwrapping nested and empty groups, Fix All
reaching an unwrapped member on a later round, the rebuild itself, the
number of objects looked at for 150 and 300 removals, and the number of
walks over the artboards and guides when 40 empty artboards are deleted.
2026-11-13 11:20:05 -08:00
dotCooCoo 5d31439e46 Merge main into fix/graph-series-paint-other-commands 2026-11-13 09:57:15 -08:00
BFlat f520e6f8c5 Merge pull request #7184 from dotCooCoo/fix/cleanup-one-pass
Artwork Cleanup: remove quadratic work from three path repairs
2026-11-14 00:48:45 +07:00
dotCooCoo 3e53884b7e Artwork Cleanup: remove quadratic work from three path repairs
Three repairs in crates/pathops/src/addons/cleanup.rs grew with the square
of the input. Each now gives the same results as before, bit for bit.

- Collinear anchors: removing an anchor called Vec::remove, so a straight
  run of n anchors took O(n^2) moves. The repair now tests each anchor once
  against the nearest kept neighbors, with the same test order, neighbors
  and stop rule, and moves the kept anchors into place once.
- Nearly Coincident Anchors (near_point_groups): every pair of anchors in
  touching grid cells was compared, so a cluster of A anchors cost O(A^2)
  checks. Groups now grow one anchor at a time and look only at anchors no
  group has taken, by exact position, skipping quarter-cell squares that
  lie out of reach.
- Rejoin Path Pieces (rejoin): every pair of ends within the gap was listed
  and sorted, O(P^2 log P) for P pieces meeting at one place. Each end now
  finds its first partner in the same order (turn, distance, then end
  order), searching by direction among the ends still free, and two ends
  that are each other's first partner meet.

Tests compare each repair with a copy of the old algorithm on generated
and focused inputs, count the work on dense cases (20,000-anchor runs,
4,000-anchor clusters, 2,000 pieces meeting at one point), and check Health
Check, Show and Fix on a 5,001-anchor path.
2026-11-13 07:58:36 -08:00
dotCooCoo 5741c7bba0 Color: assigned profiles follow the document in front
The profiles Edit > Assign Profile gives a document stayed the active
color settings after another document came to the front, so a new,
opened or switched-to document drew and converted its colors through the
previous document's profile, and closing the last document left it in
use.

The session now puts the front document's profiles in use (the working
spaces where it has none, or no document is open) after a new or opened
document, a tab switch, a close, File > Revert, every command including
each batch step and Undo or Redo of Assign Profile, a failed batch or
plug-in call, a script's rollback and slice boundaries, a canceled
preview, undo group or undo scope, and for each document Export All Open
and the update of placed documents work in. The active settings are
rebuilt, and the documents redrawn, only when they change.
2026-11-13 07:44:19 -08:00
dotCooCoo cf4d27c38e Graphs: stroke, gradient and recolor commands update a series' stored paint
A stroke weight set with stroke.set or stroke.weightUp/weightDown, a
gradient made, placed or edited with paint.editGradient,
paint.setGradientGeom or the freeform gradient edits, and colors changed
by paint.invert, paint.complement, the Edit Colors recolor and Blend
commands, recolor.apply, addon.color.filter,
addon.color.applyNearestSwatch or the ink limit of
addon.color.printFixes changed a series mark but not the paint the graph
stores, so the mark went back to the old paint when the graph was drawn
again.

appearance::edit_items now stores what its edit changes on the topmost
visible fill and stroke of series marks, as the Appearance commands do,
and the recolor pass does the same for the series marks it reaches,
including those inside a series group or a graph it is given. When one
command changes several marks of a series, the frontmost one sets the
stored paint. A gradient is stored with its placement.

These commands do not store the colors they give a graph's axes and
labels. docs/mcp.md, the params text and the Graphs line in
docs/target-app-parity.md say what is stored.
2026-11-13 05:08:19 -08:00
dotCooCoo 6a14e086de Tests: the legacy .ai Color Mask test reads the notes on the options
Saving with transparentImages "omit" now reports its note in the notes on
the options rather than in the warnings, so the test compares every note
the export gives.
2026-11-12 18:34:42 -08:00
dotCooCoo df155042d4 Merge main into feat/image-color-mask 2026-11-12 17:40:13 -08:00
BFlat a6f89f8c85 Merge pull request #6976 from dotCooCoo/fix/followup-6847
Cutting Tools: weeding lines stop at an outline that lies on a line
2026-11-13 08:29:58 +07:00
dotCooCoo 3031fcf96d Cutting Tools: the weed params text keeps the spacing range in one key
The comma in "more than 0, at most 100000" split the `spacing` entry in
the params text of `addon.cutting.weed`, so the params check read
"at most 100000 (...)" as a key and every_description_parses failed.
The range now reads "more than 0 and at most 100000".
2026-11-12 16:01:28 -08:00
dotCooCoo 52867e7096 Fonts: Find Font, Replace Missing Fonts and font lists include type in opacity masks and patterns
Find Font and Replace Missing Fonts looked only at the type on the layers
and in symbols, and the font list behind the export warning, Package and
the Missing Fonts dialog skipped opacity masks and pattern swatches.

- text.fonts lists the type in opacity masks (on objects and layers,
  disabled masks and masks inside other art included) and in pattern
  swatches, a swatch that nothing paints with included. A pattern's type
  counts once however many objects it paints. With selectionOnly, the
  masks of the selected objects and the symbols and patterns they show.
- select.font also selects the objects whose mask holds the font and the
  objects painted with a pattern whose art uses it (visible fills and
  strokes wider than 0). A layer's mask and an unused swatch select
  nothing.
- text.replaceFont changes that type in one undo step. Type in the mask
  of a hidden or locked object, and the type of a pattern that only
  hidden or locked selected objects paint with, keeps its font and is
  counted in skipped.
- addon.cleanup.replaceFonts replaces missing fonts in masks and
  patterns, hidden or locked type included.
- text.missingFonts, File > Package and the export warning read masks
  and patterns too.
- document.info's fonts for the whole document (the Fonts and Font
  Details categories and the text report) include the same type. With
  selectionOnly the list stays the selected type's fonts.

While a mask or pattern is edited, its type is taken from the editing
layer only.
2026-11-12 15:29:22 -08:00
dotCooCoo 76d61be566 Image Tools: Remove Background checks the pixels it clears for a process colorize color
Remove Background refused a grayscale image colorized with a process
color by looking at the pixels the image shows. With a color mask whose
masked pixels are not gray, as an opened file can hold, the check let
the image through, and the gray pixels it cleared took an alpha channel
under the process color. The check now reads the image's own pixels,
which are the ones cleared.

docs/mcp.md and the Color Mask line in docs/target-app-parity.md now say
that a mask that hides no pixels leaves a grayscale image free to take a
process color.
2026-11-12 14:14:24 -08:00
dotCooCoo 7998954a95 Cutting Tools: weeding lines stop at an outline that lies on a line
A weeding line at v0 + k*step can round just past the edge of an outline
segment that lies on it: across 0.1 to 0.5 the one line sits at
0.30000000000000004, and (0.30000000000000004 - 0.1) / 0.2 is
1.0000000000000002. The candidate range for that segment then came out
empty, so the line was not stopped there and ran over the art's edge.
The candidate range is now widened by a small tolerance before rounding;
`near` still leaves out lines the segment does not meet.

docs/mcp.md and the params text of `addon.cutting.weed` now state the
`spacing` range (more than 0, at most 100000 pt), the 1000-line limit
each way, and that a request giving both `count` and `spacing` is
refused.
2026-11-12 13:46:37 -08:00
dotCooCoo 312d4a3914 Merge main into feat/image-color-mask 2026-11-12 13:30:24 -08:00
dotCooCoo dc79bbbe73 Image Tools: Color Mask refuses a process color on each gray image it masks
Color Mask checked the whole document for a grayscale image colorized
with a process color only when the document passed that check before
the run. With another such image already in the document, the check
was skipped, and a process-colorized gray image could take masked
pixels with transparency.

Each image whose mask changes is now checked on the pixels the new mask
shows, made from the image's own pixels, so an image elsewhere in the
document no longer affects the result. A mask that hides nothing keeps
the image's own pixels and is still set. When new pixels replace a
masked gray image's own pixels under a process color, the mask made for
them hides nothing, and Apply Color Mask refuses them. The check shares
its colorize predicate with paint's check_colorized.
2026-11-12 12:51:25 -08:00
BFlat 06ee4cac00 Merge pull request #6952 from dotCooCoo/fix/remove-background-colorized-gray
Remove Background: a gray image colorized with a process color is refused
2026-11-13 03:28:44 +07:00
dotCooCoo 451c308ed4 Remove Background: a gray image colorized with a process color is refused
A process color can't colorize a grayscale image that has an alpha channel,
and paint.setFill refuses that combination. Remove Background gave such an
image an alpha channel and kept its process colorize color. It now refuses
the run, changing nothing, when an image it is given is gray and colorized
with a process color. It checks this before any image is decoded. Another
image in the document that already has that combination does not affect a
run on other images. Black, white and spot colors still colorize the result.

The rule check_colorized applies to each image is now one function,
paint::gray_colorized_with_process, which both checks call.

Docs: docs/mcp.md (Remove Background), docs/target-app-parity.md.
2026-11-12 10:41:22 -08:00
dotCooCoo 00e07698b1 Image Tools: a live color adjustment recolors an image whose masked pixels are missing
When the document does not hold a color mask's masked pixels, the image is
drawn from its own pixels. A live color adjustment now recolors those pixels
and drops the mask on the recolored copy, instead of pointing the image at
the missing masked pixels, which drew nothing and left Expand Appearance with
an image whose pixels were not in the document.
2026-11-12 09:59:11 -08:00
dotCooCoo 60fd410906 Merge main into fix/type-size-range-error 2026-11-12 09:30:29 -08:00
dotCooCoo 8d27e53115 Merge main into feat/image-color-mask 2026-11-12 08:56:33 -08:00
dotCooCoo 63a36fec51 Image Tools: geometry effects keep a color mask
An image with a geometry effect (Transform, for example) is drawn from a
copy of the image, and that copy now keeps the image's color mask. The
canvas and outputs show the masked pixels, and Expand Appearance keeps
the mask on the image it makes.

Test: a_transform_effect_keeps_the_mask.
2026-11-12 07:26:48 -08:00
dotCooCoo fd81eae9b5 Type: text.create and the type style commands refuse a size outside 0.1 to 1296 pt
text.create clamped a size above 1296 pt to 1296 without an error, so a
request for 2835 pt type returned 1296 pt type. text.createInPath,
text.setStyle and text.setRangeStyle clamped the same way. Each now
refuses a size outside 0.1 to 1296 pt with "`size` must be from 0.1 to
1296" and changes nothing. Both ends of the range are still taken.

Follows #6643.
2026-11-12 07:20:37 -08:00
dotCooCoo 2911958414 Image Tools: live color adjustments and envelope warps keep a color mask
- A live color adjustment recolors a masked image's masked pixels, on the
  canvas and in outputs that apply the adjustment, so the colors the mask
  hides stay hidden. Before, the adjustment recolored the image's own
  pixels and the hidden colors showed again.
- An envelope warp gives each piece of a masked image the image's color
  mask, so the warped image shows its masked pixels.

Tests: a_live_color_adjustment_keeps_the_hidden_colors_hidden and
an_envelope_warp_draws_the_masked_pixels.
2026-11-12 07:09:30 -08:00
dotCooCoo f1f9ecfc0f Cutting Tools: Weed Box and Lines leaves art in a hidden group unmeasured
Selected art inside a hidden group or layer is skipped before its outlines are read, so it no longer counts toward the outline point limit.
2026-11-12 06:29:39 -08:00
dotCooCoo 72fb8fe81d Image Tools: masked images count as see-through in legacy .ai and pattern tiles
- The legacy .ai and the check for see-through images in pattern tiles
  read a color-masked image's masked pixels, as the flattener does. A
  legacy .ai flattens a masked opaque image with the art under it, or
  leaves it out with `transparentImages: "omit"`, and a pattern tile that
  holds one is expanded before PDF/X-1a, PDF/X-3 and legacy .ai output
  flatten it.
- Printed separations check whether a colorize paint shows on the masked
  pixels, as the canvas does, rather than on the image's own pixels.
- A saved mask that leaves out `contiguous`, `tolerance` or `softness`
  reads them as the command's defaults: true, 10 and 10.
- Remove Background is unchanged on this branch. Its refusal of a
  grayscale image colorized with a process color is left for a separate
  pull request.

Tests: legacy_ai_flattens_a_masked_image_as_a_see_through_one,
a_pattern_tile_with_a_masked_image_counts_as_see_through,
pdf_x1a_and_x3_flatten_the_hidden_pixels (PDF/X-3 added),
separations_colorize_masked_pixels_whose_own_pixels_are_a_preview,
a_record_without_settings_reads_the_defaults, and the dialog's query on a
linked image at its preview.
2026-11-12 06:27:59 -08:00
dotCooCoo 634cfd053d Cutting Tools: Weed Box and Lines refuses a path past the point limit before copying it
A path or compound path with more anchors than the outline points left to measure is refused before its outlines are copied and followed.
2026-11-12 06:13:46 -08:00
dotCooCoo dc86048bb6 Merge main into feat/weed-box-and-lines 2026-11-12 05:59:30 -08:00
dotCooCoo 0779da299b Image Tools: Color Mask hides chosen colors of an image while its pixels stay
Object › Plug-ins › Image Tools gains Color Mask… (`addon.image.colorMask`),
Remove Color Mask and Apply Color Mask. Color Mask hides colors of the
selected images without changing their pixels. It matches colors as Remove
Background does: the edge color, the corner color or picked colors, with
Contiguous, Match, Tolerance and Softness. The mask is kept with the image
object and saved with the document: its settings, and a PNG of the image's
pixels with the hidden colors made clear, at the source's depth with its
color profile and resolution. It is a VectorCraft addition.

- The canvas (clip groups and white-shape opacity masks included),
  printing and separations, PDF (soft masks of CMYK images included), SVG,
  EPS, the raster formats, the legacy .ai and .ai editing data, EMF/WMF,
  DXF and the flattener draw the masked pixels. A linked image stays
  linked, and an output that would refer to its file writes the masked
  pixels instead.
- Copy and paste, placing a document and placed documents carry the masked
  pixels with the image, under the names they are given there.
- The dialog opens on the selected image's mask settings, with a Preview.
  Without settings, the command returns them and changes nothing.
- Setting, removing and applying a mask are each one undo step, and no
  step is added when nothing changes. Apply makes the masked pixels the
  image's own and embeds a linked image. A mask that hides nothing is only
  taken off, and the image keeps its pixels and its link.
- When an image's own pixels are replaced (Update Link, Relink, Crop
  Image, a recolor, a linked file read again on open), its mask is made
  again for the new pixels, in every art tree and in opacity-mask art.
  Crop Image cuts the image's own pixels. When the new pixels can't be
  masked, the mask keeps its settings and hides nothing.
- Objects in `ids` that are not images, CMYK images, linked images that
  show their preview, images past the decode allowance, masks that would
  hide every pixel, and grayscale images colorized with a process color
  are refused. The Eyedropper, Object Mosaic, Create Gradient Mesh, Crop
  Image's trim and Image Trace read the image's own pixels.
- An image is selected by a click anywhere in its frame, as before.

Remove Background now also refuses a grayscale image colorized with a
process color. Its result has an alpha channel, and a process color is
refused on a grayscale image with transparency.

Docs: docs/mcp.md (Image Tools add-on › Color Mask),
docs/target-app-parity.md.
2026-11-12 05:17:01 -08:00
BFlat 4306a1d1fb Merge pull request #6808 from dotCooCoo/feat/stencil-bridges
Cutting Tools: Stencil Bridges keeps the islands of a stencil attached
2026-11-12 18:19:57 +07:00
dotCooCoo 71fcd584b0 Cutting Tools: limits count hidden clip art, and joined art is not refused
- Weed Box and Lines counts the outline points a nested clip group hides when
  it tests pieces for being inside a region, and counts the work of every clip
  group in the selection together, so a selection cannot run far past the
  limit.
- Stencil Bridges refuses art when its measuring budget runs out only while an
  island is still unjoined, and a refusal for size or detail says so.
2026-11-12 02:35:35 -08:00
dotCooCoo 2c6bd2826b Merge main into feat/dynamic-text-release-path 2026-11-11 23:31:01 -08:00
dotCooCoo ec36ccd076 Cutting Tools: Weed Box and Lines adds a weed box and weeding lines around art
A Cutting Tools add-on command (Object › Plug-ins › Cutting Tools › Weed Box
and Lines…, `addon.cutting.weed`) for vinyl cutting: around the selected art
it adds a weed box, a rectangle at a margin outside the art's bounds, and
weeding lines across the box, horizontal, vertical or both, by count or by
spacing. Each line runs from one side of the box to the other and is left out
over the art and within a gap of its outlines, so it stops at the art and the
waste lifts off in pieces. The lines and the box are straight paths stroked
in a chosen color swatch ([Registration] by default) with no fill, in one
group named Weeding on top of the current layer, selected, as one undo step.
While a clip group, or a group inside one, is edited in isolation, the
group goes on top of the container that holds the outermost clip group
around it.

The art is measured by the outlines a cutter cuts: closed paths by their fill
rule (the hole of an even-odd compound path gets lines too), open paths as
lines, type by its glyph outlines, images by their frames, placed files by
the art they show (by their boxes when the file can't be read), symbol
instances by their art, and blends and other live objects by the art they
draw. A clip group, and an object selected inside one, is measured by what
shows inside the region its clipping paths clip to, and a clipping path
selected on its own as its clip group. Art in a hidden group or layer is
left out. The command refuses an empty selection, art with no outlines, bad
params, and art or lines too complex to measure, with a message.

The dialog has Preview; a Spacing above 0 is used instead of the Count.

Docs: docs/mcp.md (Cutting Tools add-on) and docs/target-app-parity.md.
2026-11-11 22:59:52 -08:00
dotCooCoo 2a494dec50 Cutting Tools: Stencil Bridges keeps the islands of a stencil attached
Object › Plug-ins › Cutting Tools › Stencil Bridges… (`addon.cutting.bridges`)
cuts strips of a set width out of the selected art so that a stencil cut
from it holds together: every island (the inside of an O, A or 8, a hole in
a shape) stays joined to the sheet, directly or through another island.
Bridges take the shortest crossings that fit first, then spread around each
island up to the count asked for, at least two widths apart. They run
vertically, horizontally or along the shortest crossing among 12
directions 15° apart.

- The art is measured by the area its outlines enclose, whatever their
  paint, with hidden objects left out; type by its glyph outlines, without
  converting the type. The result is one compound path with the strips cut
  out, painted as the topmost selected shape with outlines, in the place of
  the topmost selected object with outlines. Selected objects with no
  outlines in the art stay where they are.
- Keep Original (on by default) moves the selected objects that make up the
  art to a new hidden layer, Stencil Original; off replaces them.
- Art with no islands, or none a bridge of the width fits, is left as it is
  with a message and no undo step. Islands the cut result still encloses
  are counted in `unbridged`, with a message. Otherwise the run is one undo
  step.
- Curves are followed within a twentieth of the width (0.002 to 0.25 pt).
  Art that reaches more than 10000000 pt from the origin or has more than
  200000 anchors is refused before it is combined. Art is also refused when
  its combined area has more than 4000 outlines, when its outlines need
  more than 200000 straight segments, or when placing the outlines or
  joining every island takes more work than a fixed budget allows; when
  the budget runs out while extra bridges are added, the bridges found so
  far are kept.

Tests in vectorcraft-pathops, vectorcraft-engine and vectorcraft-ui-egui,
command_sweep cases, catalog rows in all 27 languages, docs/mcp.md, the
evidence list in docs/target-app-parity.md and the ROADMAP progress log.
2026-11-11 22:17:43 -08:00
BFlat fb3f051922 Merge pull request #6792 from dotCooCoo/perf/remove-background-distance
Remove Background: distance mode finds the nearest color before converting
2026-11-12 13:17:28 +07:00
dotCooCoo 00b53a3222 Merge main into feat/dynamic-text-release-path 2026-11-11 22:03:30 -08:00
BFlat a8ac772c53 Merge pull request #6753 from dotCooCoo/feat/pixel-align-new-objects
Transform: Align New Objects to Pixel Grid makes new paths pixel-aligned
2026-11-12 12:41:07 +07:00
dotCooCoo 0ef33f6e41 Remove Background: distance mode finds the nearest color before converting
In distance mode, each pixel took a square root for every background color.
The nearest color is now found by squared distance, and only that distance is
converted to a percentage. The levels do not change.
2026-11-11 21:24:45 -08:00
dotCooCoo f65f3029a6 Image Tools: Remove Background clears an image's background in its pixels
A new built-in add-on, Image Tools (Object › Plug-ins › Image Tools),
adds Remove Background… (`addon.image.removeBackground`). It makes the
background of the selected images transparent by lowering the alpha of
their own pixels, in one undo step, with no service or model. The
background is the most common color along the image's edges, the
average of the image's corners, or colors the user picks. Contiguous
(on by default) clears it only where it reaches in from an edge; off,
it is cleared wherever it is. Tolerance and Softness (0 to 100, 10 by
default) set how near a color must be to be cleared and the band over
which pixels fade out. Match measures that nearness as the RGB
distance or as the largest difference on one channel. It is a
VectorCraft addition.

- The image stays an image: an embedded PNG with alpha, the source's
  ICC profile and resolution, and 16 bits or gray when the source is.
  A linked image is embedded and keeps its Placement Options.
- When the edges hold at least as many clear pixels as pixels of their
  most common color, edge mode clears nothing, so a second run leaves
  the subject alone. Corner mode leaves clear corners out of the
  average and clears nothing when all four are clear.
- With Match set to Each Channel, a tolerance of t / 255 × 100 clears
  the colors within t 8-bit steps on every channel.
- A CMYK image, a linked image that shows its preview, an image that
  would need more than the decode allowance (checked from its header)
  and a result with no pixel left are refused, and the document stays
  as it was. When no pixel changes, no undo step is added. The result
  reports `cleared`, the pixels made fully clear.
- Picked colors are hex colors, with or without `#`, or black, white,
  red, green or blue.
- The dialog opens with Preview off; with Preview on, the canvas shows
  the result, and Cancel puts the image back. While the dialog
  previews, the session keeps the images' decoded pixels (at most
  128 MiB, 32 MiB in the web app) so each preview step does not decode
  them again, and releases them when the dialog closes with OK or
  Cancel. A run that is not a preview step keeps nothing.

Docs: docs/mcp.md (Image Tools add-on), docs/target-app-parity.md.
2026-11-11 19:47:28 -08:00
dotCooCoo 7e071feb4d Merge main into feat/pixel-align-new-objects 2026-11-11 18:57:23 -08:00
dotCooCoo 558568d531 Merge main into feat/dynamic-text-release-path 2026-11-11 18:48:20 -08:00
BFlat 8631f5f1ab Merge pull request #6690 from dotCooCoo/feat/psd-open-layers
PSD import: File › Open converts a PSD file's layers to objects
2026-11-12 09:13:54 +07:00
dotCooCoo 93ccc6fbfa Transform: Align New Objects to Pixel Grid makes new paths pixel-aligned
Document Setup gains alignNewObjectsToPixelGrid. When it is on, every
path or compound path drawn in the document (shape tools, Pen,
Curvature, Pencil, Paintbrush, Blob Brush, grids, flares and add-on
shapes) gets the pixel-aligned property and snaps in the same undo
step. Text, paste, duplicate, Place and import are not affected.

- The Transform panel menu has an Align New Objects to Pixel Grid
  item for the active document.
- New Document's Advanced Options has the checkbox; the Mobile and Web
  presets turn it on, other presets and older saved presets leave it
  off, and file.new, Save Preset and Recent keep it.
- The setting is saved with the document only when it is on.

https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/pixel-preview-mode-for-web-graphics.html

Docs: docs/mcp.md, docs/target-app-parity.md, docs/ui-parity.md.
2026-11-11 17:41:21 -08:00
dotCooCoo e6add18663 Fix #6634: Pen closing drag no longer gives the first anchor symmetric handles
Closing a path by dragging on its first anchor made that anchor smooth
with symmetric handles, so the first segment bent along with the closing
one. The drag now sets the first anchor's incoming handle to the mirror
of the pointer. Its outgoing handle stays where it is on a corner, so
the first segment keeps its shape, and on a smooth anchor it turns to
stay in line at its own length. Alt makes the anchor a corner and leaves
the outgoing handle where it was when Alt went down. A click on the
first anchor closes the path with the incoming handle retracted and the
anchor a corner, so the closing segment comes in straight.

The Smart Pen's closing drag follows the same rule.

path.close's `in` now places the handle as path.setHandle does, and a
new `out` param places the outgoing handle and makes the anchor a
corner.
2026-11-11 15:33:09 -08:00
dotCooCoo 0923d862a1 PSD import: File › Open converts a PSD file's layers to objects
Opening a .psd or .psb used to give one merged image. document.open now
reads the layer records and builds the document from them. The PSD
import options page
(https://helpx.adobe.com/illustrator/desktop/add-and-import-files/import-from-other-apps/photoshop-import-options.html)
says the option that converts layers to objects keeps as much of the
layer structure as it can, merges the layers of a clipping mask into one
layer and discards hidden layers that require merging, and that Import
Hidden Layers brings hidden layers in. document.open does the same, with
hiddenLayers: true for the hidden layers; layers: false keeps the merged
image.

VectorCraft's own rules:

- Each layer becomes a layer holding its pixels as an image, with its
  name, visibility, opacity and blend mode. A group becomes a layer of
  sublayers; a Pass Through group is not isolated.
- Clipped layers show where the layer below has pixels. That layer's
  fill opacity fades only its own pixels. Layers clipped to an
  adjustment layer, or to a fill that stores no pixels and isn't drawn,
  show over the whole canvas.
- A layer mask becomes the layer's opacity mask, its default color and
  invert flag applied; a disabled mask is kept, switched off.
- Fill opacity multiplies the layer's opacity.
- Layers and groups in Dissolve, Linear Burn, Linear Dodge, Vivid Light,
  Linear Light, Pin Light, Hard Mix, Subtract, Divide, Darker Color and
  Lighter Color are merged with the layers below, whether or not they
  hold transparent pixels; Color Dodge, Color Burn and Difference keep
  their mode. A merged Dissolve layer's pixels are opaque or
  transparent, in a pattern of each layer's own.
- A solid color fill layer that stores no pixels and has no vector mask
  comes in as its color (RGB, CMYK, Grayscale, Lab or HSB).
- A layer name stored only as a Pascal string, without its Unicode
  name, is read as Mac Roman.
- Adjustment layers, fill layers that aren't drawn, layer effects that
  are switched on, knockouts and vector masks are not applied; the
  warnings count them.
- A merge whose canvases need more memory than allowed leaves the layer
  alone, in the Normal mode or unclipped, with a warning.

This changes what opening a layered PSD does. Batch Trace Folder passes
layers: false, so a PSD is still traced as its merged image. A file
whose layers can't be read, or whose layers and merges need more memory
than allowed, opens as the merged image with a warning.

Lengths, counts, nesting, decoded pixels and the canvases merges make
are bounded. Zipped 32-bit data with prediction is now read, in layers
and in the merged image. import_fuzz gains a case that mutates the PSD
and PSB samples and opens them with their layers. The PSD reader's new
error messages have rows in every catalog.

Docs: docs/mcp.md, docs/target-app-parity.md, docs/file-format-parity.md,
README.
2026-11-11 13:59:32 -08:00
dotCooCoo b426822a9c Type: Release Type on a Path keeps the size Dynamic Text drew the type at
Release Type on a Path copied the stored runs into point type with the
Dynamic Text flag still set, so the text dropped back to its stored size
and the file saved the flag on point type. The point type now gets the
drawn sizes and the flag is turned off.

The legacy .ai writer writes Dynamic Text type at its drawn sizes; it
now also warns that the setting itself is not written, as the editing
data writer does, whether the type is written as text or as outlines.

docs/target-app-parity.md lists reshaping or scaling the path among
VectorCraft's own rules, and a task bar comment marks leaving the item
out for threaded type as VectorCraft's own rule.
2026-11-11 13:06:51 -08:00
BFlat 3dda59ce95 Merge pull request #6640 from dotCooCoo/fix/ids-null-takes-selection
Commands: ids null acts on the selection instead of being refused
2026-11-12 01:56:30 +07:00
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 1643ab52a9 Commands: ids null acts on the selection instead of being refused
The 27 commands that act on `ids` or else the selection (Apply as
Filter, Print Ink Fixes, the Arrange, Cleanup and Path Tools plug-in
commands, Smooth, Text Wrap, variable.bind and variable.unbind among them)
refused `ids: null` with "ids must be an array of non-negative integer
object ids". They now read null as `ids` left out, as the other commands
that take `ids` do. Remove Breaks also reads null as left out when it
decides whether to act on the characters the Type tool selected.
2026-11-11 10:10:46 -08:00