Commit Graph
10282 Commits
Author SHA1 Message Date
Drew Dibble 59cc303912 Canvas redraw: the stack overflow fix's evidence, and two tests' known differences
- The parity rows say what the fix covers: a 3D effect on a fill or
  stroke that builds nothing overflowed the stack with no effect of the
  object's own too, on the canvas, in Object › Rasterize and in raster
  exports.
- The builds-nothing test says the fill-only difference (a raster
  effect clipped to the path, cutting Roughen's spikes, when drawn
  without the 3D effect) is an older bug, not the design.
- The traced-shape test says why its area is bounded rather than drawn
  again: a partial render in outline view differs from the whole by one
  in alpha on 37 pixels, older than the test and unrelated to the edit.
- A doc comment rewrapped.
2026-11-09 15:13:42 -07:00
Drew Dibble 78b31831c2 Artboards: Fit to Artwork Bounds' kept answer kept by the document, with the plug-ins and fonts it reads
The answer whether Fit to Artwork Bounds has art to fit moves from a
function-local thread_local to DocState, beside any_empty_artboards, and
drops with the document. It is kept for that version of the document
(held weakly, as any_empty_artboards holds its own) and the artboards
asked about, and measured again when the installed plug-ins, whose
effects draw art, or the installed fonts, which set type drawn by its
effects' art, change: their generations are an explicit input of the
measure. A change of the selection or the view keeps it.

The test counts the measures, as the Delete Empty Artboards check's
does: a later frame, select.set and a view change keep the answer; an
edit, other artboards, and each generation measure again. Taking any
part out of the key fails it.
2026-11-09 15:13:41 -07:00
Drew Dibble 758a31890d Artboards: Fit to Artwork Bounds' kept answer follows the document's version and the plug-ins
fit_has_art kept its answer for the document's uid and revision, which
don't follow every change of what it measures: a document's tab coming
to the front replaces it with its composite fonts synced, and a plug-in
installed or removed changes what its effects draw, with no revision
moving either time. The answer is now kept for that document Arc, held
weakly as DocState::any_empty_artboards keeps its own, and the artboards
asked about, until the plug-ins' revision moves. A selection or view
change keeps it.

The test replaces the document with art on an artboard, its revision as
it was, and asks again: kept by revision, the answer was stale.
2026-11-09 14:18:05 -07:00
Drew Dibble bd9f6a04ef Canvas redraw: review follow-ups to the strengthened tests
- A 3D effect that builds nothing: af754bcb2 said the object draws exactly
  as without it under a Drop Shadow or Gaussian Blur. That holds only for
  a stroked object. With only a fill, the raster effect draws from the
  art made for the object, where without the 3D effect it is clipped to
  the path, so Roughen's spikes differ: the earlier wording was right.
  The test keeps the stroked cases exact and restores fill-only cases
  with a Drop Shadow and a Gaussian Blur, which differ in under 4% of
  the pixels and nowhere inside the path. Its reach check compares with
  the object drawn without its raster effect, since Roughen alone
  reaches past the path.
- The Vector Halftone test's bounds are a consistency check, and only
  holding no art tests the branch: its doc no longer says no solid is
  built (the free measure's halftone arm builds one). The overprint
  test's area check is labeled likewise.
- Recoloring a traced shape bounds the area the renderer that drew the
  trace object measures too, inflated by half the stroke and a pixel.
- The let-go test pins the nothing-to-draw branch: no frame, whole or
  part, began since the measure.
- The parity doc's feature row names the stack overflow fix and its
  test; a group test's doc says what its fixture holds.
2026-11-09 14:18:05 -07:00
Drew Dibble 2fcaaedb2d Merge main into type-3d-redraw 2026-11-09 13:20:30 -07:00
Drew Dibble d0b26c0772 Canvas redraw: the let-go test receives the worker's job; the fit cache's key documented
Review follow-ups:
- The test that art measured for an edit not drawn on this thread is let
  go first checks that measuring the edit through the canvas's renderer
  holds art, so a measure that held nothing can't pass it. Its worker is
  a test channel whose job the test receives, in place of a real thread's
  pending job, which a finished frame could clear. Taking out either
  let_go_of_measured fails it.
- fit_has_art's comment says why its one kept answer can't be stale: a
  document's uid is never reused in the process and its revision only
  moves forward.
2026-11-09 13:19:55 -07:00
BFlat 9394a43e58 Merge pull request #6347 from jmverges/fix/6314-pdf-separation-images
PDF import: Separation images keep their ink (#6314)
2026-11-10 03:18:58 +07:00
Drew Dibble af754bcb23 Canvas redraw: the renderer's measure tests check what their names say
Review follow-ups:
- The tests that a group with effects of its own is measured once a pass
  plant its kept bounds after the first artboard and read them back over
  the next two, so a measure made again fails. Its solid is built by the
  free measure, which the renderer's three_d_built doesn't count.
- The budget test checks that every object, past the budget too, is
  measured as the free measure does and draws as a new renderer draws it.
- A 3D effect that builds nothing draws the object exactly as without it,
  with a Drop Shadow or Gaussian Blur too, which reach past the path. The
  doc comment said those differ past the path; they don't.
- The brush widened in view first checks that the wider brush draws
  otherwise.
- Recoloring a traced shape changes no more than the shape, its stroke
  and a pixel's anti-aliasing.
2026-11-09 13:13:17 -07:00
Drew Dibble 049f8c3963 Canvas redraw: tests for edits measured under overprint, with Vector Halftone, and to the instance symbol editing came from
Review follow-up: these three branches of what a renderer measures had no
test. Under Overprint Preview a renderer measures an edit as changed()
does and holds none of the 3D art it made for it; a 3D effect with
Vector Halftone is measured by the free measure, with no solid built and
no art held; and on screen in symbol editing mode, an edit to the
instance it was entered from changes nothing. Each test fails with its
branch taken out.
2026-11-09 13:10:41 -07:00
BFlat 2318ba0457 Merge pull request #6341 from Hassan1305/feat-4936-auto-spell-check
Part of #4936: Auto Spell Check underlines the unknown words of the type
2026-11-10 02:31:29 +07:00
HassanKhan f8ca2c09cb Merge remote-tracking branch 'upstream/main' into feat-4936-auto-spell-check
# Conflicts:
#	docs/gaps.md
#	docs/roadmap.md
#	docs/target-app-parity.md
#	docs/type-parity.md
2026-11-09 23:50:29 +05:00
HassanKhan ff1079b3ce Auto Spell Check: underline the unknown words of the type on the canvas (part of #4936) 2026-11-09 23:41:41 +05:00
jmvergesandClaude Opus 5.5 ca59598cd7 PDF import: Separation images keep their ink (#6314)
An image in a Separation color space opened as an RGB image: its spot ink
was lost (no plate in Separations Preview), and Fill and Recolor Artwork
didn't reach its color.

It now opens as a grayscale image of its tints (white where it lays no
ink, black at 100 %, its Decode array applied; 1 to 16 bits a sample, or
one gray channel from its JPEG, CCITT, JBIG2 or JPEG 2000 decoder),
colorized by its ink at 100 %: the spot swatch, a process plate's CMYK
color, or Registration. Its mask becomes its opacity mask, as a CMYK
image's does. The ink is found by the image's color space among those the
file defines, once per image. The ink None, an ink whose color can't be
told, images inside an alpha soft mask, inline images and DeviceN images
open as before; samples that can't be read open in RGB with a warning, and
the ink gets no swatch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 18:39:46 +00:00
BFlat 9dc4c33529 Merge pull request #6330 from thisisgomaa/fix/pdf-export-mark-text
PDF export: letters with marks are written once in the text layer
2026-11-10 01:29:17 +07:00
BFlat 9cf3a4e5b6 Merge pull request #6334 from JonRC/fix/eps-missing-fonts-of-the-document
EPS import names the missing fonts of the document's type (#6326 follow-up)
2026-11-10 00:49:58 +07:00
Ahmed Gomaa 95a2527585 Merge remote-tracking branch 'upstream/main' into fix/pdf-export-mark-text 2026-11-09 19:47:08 +02:00
BFlat 14d545e875 Merge pull request #6329 from Messhias/feat/g5-symbol-lib-ui-frames
G5: built-in UI Frames symbol library with default 9-slice
2026-11-10 00:29:14 +07:00
Ahmed Gomaa 9ffea06f82 Merge remote-tracking branch 'upstream/main' into fix/pdf-export-mark-text 2026-11-09 19:12:24 +02:00
JonRC d439d734e6 EPS import names the missing fonts of the document's type (#6326 follow-up)
The warning #6326 added listed the families `set_text` met while the
page ran. An Illustrator EPS can be rebuilt from its editing copy,
whose type may be in other fonts than the page's, and `stringwidth` and
`charpath` reach `set_text` without adding any type. The families are
now taken from the text objects of the document the import gives (its
layers and its symbols), once each, in the order the type comes,
whichever path built it.
2026-11-09 14:01:27 -03:00
Drew Dibble baa5bab2ea Docs: the 3D-bounds map's sweeps and bound, and the change in the parity doc's revision history 2026-11-09 09:54:50 -07:00
Drew Dibble bd779077e5 Merge main into type-3d-redraw
# Conflicts:
#	crates/ui-egui/src/canvas/tests.rs
#	docs/target-app-parity.md
2026-11-09 09:49:25 -07:00
Drew Dibble 0f75f8e9da Canvas redraw: each version's trace source read from its own node; the 3D-bounds map's bound documented
Diff took the Image Trace flag of the old version for both sides when it
read each version's first member. Both versions have the same extras
there (same_but_members), so the result was right, but each side now
reads its own node.

The doc of Renderer's three_d_bounds now says what adds an entry, when
entries are swept, and the bound that follows: about twice the live 3D
art plus 1024 entries.
2026-11-09 09:48:50 -07:00
Fabio William Conceição a668f44780 G5: assert default 9-slice on every UI Frames symbol
Keep the library test aligned with SymbolNineSlice::default() for Panel, Button and Bar.
2026-11-09 16:40:13 +00:00
Fabio William Conceição e5ef855903 G5: size UI Frames so default 9-slice keeps round corners
Button and Bar were shorter than 4x their corner radius, so the default guides cut through the curves on a vertical resize.
2026-11-09 16:29:22 +00:00
Fabio William Conceição bd9b1696e0 G5: built-in UI Frames symbol library with default 9-slice
Add Panel, Button and Bar HUD chrome as a second original symbol library so games can drop resizable UI frames without inventing art each time.
2026-11-09 16:29:22 +00:00
BFlat 9086ff3e96 Merge pull request #6325 from Silvertree2010/fix/h15445-graph-csv-parser-does-not-strip
Strip leading byte-order mark in graph CSV parser
2026-11-09 23:16:56 +07:00
Ahmed Gomaa 9b797c06d1 PDF export: letters with marks are written once in the text layer
A mark glyph's vertical translation started a new draw_glyphs batch, so
krilla received the cluster's source range again and mapped its
characters twice. Copying or searching the exported PDF then found
doubled letters for Arabic harakat in any font, and for every dotted
letter in fonts that draw dots as zero-advance mark glyphs (Noto Sans,
Naskh and Kufi Arabic).

Keep compatible glyphs on the same layout line in one batch and carry
their relative vertical placement as per-glyph y_offset; horizontal
placement is unchanged (next_x - x advances). Font, size, linear
transform, line/column, paint run, list marker and hyphen boundaries
still split batches. Krilla keeps owning cluster mappings and
ActualText. No importer change.

Regressions decode the content stream and ToUnicode maps: one batch per
layout line, no duplicated cluster assignment, one ActualText per
multi-glyph cluster, contours within 0.05 pt of outline export; mixed
scripts, vertical columns, path rotations and PDF/X variants covered.
The reader round-trip stays an ignored test until the importer consumes
ActualText (#6165).

Addresses #6309.
2026-11-09 18:13:14 +02:00
BFlat 09aedd417d Merge pull request #6326 from JonRC/fix/eps-missing-fonts-warning
Fix #6320: EPS import warns about fonts that aren't available
2026-11-09 23:12:31 +07:00
BFlat 7875114168 Merge pull request #6308 from Messhias/feat/g5-dynamic-symbol-part-appearance
G5: dynamic symbol parts take opacity, blend and non-solid paint
2026-11-09 22:31:51 +07:00
JonRC ddbc0d545a Fix #6320: EPS import warns about fonts that aren't available
Type set in a family that isn't available keeps its name and shows in
the fallback font, as in PDF import, but EPS import said nothing. It
now notes each such family once, in the order its type comes (at most
64), and ends with PDF import's warning: "fonts that aren't available
show in the fallback font until they are: <families>".

Tests that set type in fonts the test machine may lack (Helvetica,
Ryumin, made-up names) check the program's warnings without that note,
since which fonts are installed depends on the machine.
2026-11-09 12:31:17 -03:00
BFlat 67c7cbda51 Merge pull request #6321 from jmverges/fix/6313-pdf-image-mask-colorized
PDF import: image masks open colorized by the color they are painted in (#6313)
2026-11-09 22:26:37 +07:00
NetterSilverandClaude Haiku 5.5 511bb23999 Strip leading byte-order mark in graph CSV parser
Found while testing crates/engine/src/cmd/graph/data.rs:45-47 (parse_csv)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-09 15:25:52 +00:00
BFlat c66cb516e2 Merge pull request #6317 from dotCooCoo/fix/pdf-cmyk-gradient-image
PDF export: dithered and Perceptual CMYK gradients stay CMYK
2026-11-09 21:46:10 +07:00
jmvergesandClaude Opus 5.5 def928c0dc PDF import: image masks open colorized by the color they are painted in (#6313)
A PDF image mask (`/ImageMask true`) painted in a solid color opened as an
RGB image with the color in its pixels: Fill and Recolor Artwork didn't
reach the color, a spot color lost its ink, and the same mask painted again
in another color took the first one, because the painted image was cached
by the mask alone, and so did an uncolored pattern whose cell draws a mask.

It now opens as a grayscale image of what it paints, colorized by that
color, as the .ai reader opens a 1-bit image mask (#5790). A spot color
keeps its swatch and tint. The page's walk counts paths, not images, so the
ink is found from the color space. Readings of a pattern cell are told
apart by colorized images' colors too. Inside an alpha soft mask, or
painted with a pattern, a mask opens as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:43:13 +00:00
Fabio William Conceição 84e7d55bc8 G5: finish Eyedropper and undo wording for a picked part
copyFrom only writes paints enabled for pickup and apply, and paint, Transparency and the Eyedropper record an undo step only when the override changes.
2026-11-09 14:42:18 +00:00
Fabio William Conceição a4ea6d6fbe Merge remote-tracking branch 'upstream/main' into feat/g5-dynamic-symbol-part-appearance
# Conflicts:
#	docs/gaps.md
#	docs/target-app-parity.md
2026-11-09 14:42:18 +00:00
BFlat b4cb6a69c4 Merge pull request #6306 from thisisgomaa/fix/macos-native-cursor-delivery
macOS: deliver canvas cursors through AppKit pending a winit fix
2026-11-09 21:37:25 +07:00
Fabio William Conceição 0f2dde0282 G5: qualify when a picked part takes the Eyedropper and Transparency
copyFrom still edits the part when reverse, append and defaultsOnly are false, and reverse copies onto source. transparency.set records an undo step only when the override changes.
2026-11-09 14:27:19 +00:00
Fabio William Conceição e88e9077e7 G5: spell out part-paint targets and the pen gaps still open
A picked part takes transparency and the Eyedropper only when those calls omit their other targets. Art, Pattern and Bristle brushes, native Wayland and the web still do not take tilt, bearing or rotation.
2026-11-09 14:07:48 +00:00
Fabio William Conceição 08cc3d6ffa Merge remote-tracking branch 'upstream/main' into feat/g5-dynamic-symbol-part-appearance
# Conflicts:
#	docs/target-app-parity.md
2026-11-09 14:07:11 +00:00
Ahmed Gomaa 7020af6501 Merge remote-tracking branch 'upstream/main' into fix/macos-native-cursor-delivery 2026-11-09 15:59:17 +02:00
dotCooCoo 90bc821f3f PDF: dithered and Perceptual CMYK gradients stay CMYK
A dithered fill or a Perceptual linear or radial gradient whose stops
are all CMYK was written as an RGB image. It is now a CMYK image.
The stops keep their inks, an off-center midpoint is halfway between
its two stops' inks, and a Perceptual curve uses the ink mixes a
DeviceN shading uses. Dither's noise is added per ink and adds no ink
where the gradient has none.

The Output settings convert the inks as they do for any CMYK image.
A gradient with an RGB, gray or Lab stop, a stop linked to a spot
swatch, or a Perceptual curve of more than 4,096 stops is still written
as an RGB image.
2026-11-09 05:55:04 -08:00
BFlat 1eaf678083 Merge pull request #6158 from thisisgomaa/fix/arabic-mark-colour-ownership
Type: colouring Arabic marks preserves joining and glyph ownership
2026-11-09 20:39:32 +07:00
Fabio William Conceição 0216bd58c5 G5: document gradient, pattern, opacity and blend on a picked part
The MCP guide and the Eyedropper spec still said those were refused for a Direct Selection of a dynamic symbol part.
2026-11-09 13:12:49 +00:00
Ahmed Gomaa 5c64c074ca Merge remote-tracking branch 'upstream/main' into fix/macos-native-cursor-delivery 2026-11-09 15:02:19 +02:00
Ahmed Gomaa 7d4f8dce27 Merge remote-tracking branch 'upstream/main' into fix/arabic-mark-colour-ownership 2026-11-09 15:02:18 +02:00
Fabio William Conceição 6def1c6b04 Merge remote-tracking branch 'upstream/main' into feat/g5-dynamic-symbol-part-appearance
# Conflicts:
#	docs/gaps.md
#	docs/target-app-parity.md
2026-11-09 13:00:35 +00:00
BFlat 6dac80e75d Merge pull request #6166 from thisisgomaa/codex/snapping-quick-access
Control bar: add glyph and alignment guide toggles to Snapping
2026-11-09 19:38:52 +07:00
BFlat 49853de906 Merge pull request #6303 from Hassan1305/feat-4936-dictionary-followups
Part of #4936: follow-ups to #6296 (read the dictionary file whole; keep other windows' words when a save fails)
2026-11-09 19:19:41 +07:00
Fabio William Conceição 1ff0fd62fc G5: rustfmt dynamic symbol part paint paths 2026-11-09 12:18:55 +00:00