Commit Graph
8850 Commits
Author SHA1 Message Date
BFlat 51aea90f07 Merge pull request #5972 from dotCooCoo/fix/selection-overlay-per-frame
Canvas: selection outlines and anchors are reused between frames
2026-11-07 09:10:03 +08:00
BFlat afdc490d3a Merge pull request #5971 from slafebre/fix/5964-gradient-dash-corner
Part of #5964: stroke gradients cover an arrowhead to the end of its reach
2026-11-07 09:09:47 +08:00
BFlat 073923ee30 Merge pull request #5969 from dotCooCoo/fix/eyedropper-keeps-story-selection
Type: switching to the Eyedropper keeps a whole-story selection
2026-11-07 09:09:33 +08:00
BFlat 085bbf5495 Merge pull request #5968 from slafebre/fix/5714-smooth-width-profiles
Fix #5714: widths run smoothly between width points
2026-11-07 09:09:19 +08:00
BFlat ee4f711fbe Merge pull request #5967 from dotCooCoo/fix/ai-brushed-paths
.ai import: paths with an Art brush open with the brush on their stroke
2026-11-07 09:09:01 +08:00
BFlat 7adc7fa40c Merge pull request #5966 from dotCooCoo/fix/ai-envelope-stroked-box
.ai import: envelopes map from their stroked box when the file saves its size
2026-11-07 09:08:45 +08:00
BFlat 9950bde2e7 Merge pull request #5963 from dotCooCoo/fix/pdf-export-cost
PDF export: members of a plain group or layer are measured once to leave out off-page art, and the link walk measures only what it reads
2026-11-07 09:08:28 +08:00
BFlat e940a55cb6 Merge pull request #5959 from dotCooCoo/fix/ai-symbol-section-strings
.ai import: ASCII85 data in a section does not hide the section's end
2026-11-07 09:08:13 +08:00
BFlat aeb697c8ea Merge pull request #5958 from FractalEncrypt/fix/shape-tool-centre-and-rotate
Shape tools: move the selection from its centre point and turn it outside a corner
2026-11-07 09:07:57 +08:00
BFlat b59e31203e Merge pull request #5957 from FractalEncrypt/fix/transform-fields-tab-order
Transform fields: Tab moves from one field to the next, one press each
2026-11-07 09:07:42 +08:00
BFlat 5a07696a8e Merge pull request #4732 from SofiaAFigueredo/feat/4684-unify-home-screen-ui
UI: centre the Home screen and use the accent for the Discord button (#4684)
2026-11-07 09:07:26 +08:00
BFlat 4244b96afc Merge pull request #5955 from dotCooCoo/fix/open-text-layout
Type: layout keeps each font face's shaping plans
2026-11-07 09:07:10 +08:00
BFlat 8df48df103 Merge pull request #5953 from mockydevs/fix/legacy-ai-smooth-image-clip-5264
Legacy .ai export: a flattened transparent image's clip follows its edge smoothly
2026-11-07 09:06:50 +08:00
BFlat 4db8bbc97c Merge pull request #5952 from dotCooCoo/feat/ai-pathfinder-effect-commands
.ai import: the other Effect › Pathfinder operations open as live effects on a group
2026-11-07 09:06:14 +08:00
BFlat 3bceade119 Merge pull request #5951 from dotCooCoo/fix/ai-active-artboard
.ai save: the editing copy names the active artboard
2026-11-07 09:05:42 +08:00
BFlat 76eca8e98e Merge pull request #5950 from mockydevs/feat/progress-indicator-5930
Opening a slow file shows a progress window with Cancel and Continue in Background
2026-11-07 09:05:27 +08:00
BFlat b497793902 Merge pull request #5948 from Hamza0101/feat/bulgarian-text-language
Languages: Bulgarian, with its quote marks and the fonts' Bulgarian forms (#5945)
2026-11-07 09:05:15 +08:00
BFlat 98c6e8ab5d Merge pull request #5947 from mockydevs/fix/grid-snap-anchors
Direct Selection: with Snap to Grid, a dragged straight segment lands its anchors on the grid
2026-11-07 09:04:57 +08:00
BFlat 0ebce55584 Merge pull request #5942 from mockydevs/feat/paste-spreadsheet-table
Paste: cells copied from a spreadsheet paste as a table of type over gridlines
2026-11-07 09:04:38 +08:00
BFlat d79c3574af Merge pull request #5940 from dotCooCoo/fix/paint-without-bounds
Appearance and Eyedropper: reading an object's paint does not measure its bounds
2026-11-07 09:04:16 +08:00
BFlat af4f590b6b Merge pull request #5939 from mockydevs/feat/alt-numpad-codes-5108
Type: Alt + numeric-keypad codes (Alt+0176 → °) type their character on Windows; type.insert takes a code
2026-11-07 09:03:59 +08:00
BFlat 84fc4b74ac Merge pull request #5938 from mockydevs/feat/3d-effects-on-groups
3D effects: Extrude & Bevel, Inflate and Rotate apply to groups, turned about one shared axis
2026-11-07 09:03:47 +08:00
BFlat e688fbea0e Merge pull request #5937 from mockydevs/feat/glyph-bounds-corners-5112
Snap to Glyph: each glyph's bounding-box corners are snap points, and the box turns with rotated type
2026-11-07 09:03:27 +08:00
BFlat bc57bdaee3 Merge pull request #5932 from Hamza0101/fix/paste-into-new-type-keeps-formatting
Type: pin that a Type-range paste into new point type keeps its formatting (#5929)
2026-11-07 09:03:09 +08:00
BFlat 8029748283 Merge pull request #5931 from mockydevs/fix/perspective-plane-offsets
Perspective grid: a grid dragged off its preset reports no preset name
2026-11-07 09:02:47 +08:00
BFlat c14ec164a2 Merge pull request #5928 from adikshan11/fix/library-untitled-format-copies
Don't copy a library on every save when its format keeps no title
2026-11-07 09:02:27 +08:00
BFlat d074756192 Merge pull request #5927 from mockydevs/fix/transform-effect-copies-5920
Effects: a Transform effect's copies of a filled and stroked path stack one above another
2026-11-07 09:02:10 +08:00
BFlat 0f0ded95b4 Merge pull request #5924 from jayzed80/fix/text-huge-gutter-stall
fix(text): a gutter too huge to step past no longer stalls area type layout
2026-11-07 09:01:34 +08:00
BFlat 145a10c2db Merge pull request #5922 from Hamza0101/fix/find-whole-word-across-runs
Find Whole Word: a change of style inside a word is not a word boundary (#5901)
2026-11-07 09:01:14 +08:00
BFlat 9ef87c19e5 Merge pull request #5921 from Hamza0101/fix/find-replace-respects-group-lock
Find and Replace: type inside a locked or hidden group is left alone (#5900)
2026-11-07 09:00:51 +08:00
BFlat 4166d31a54 Merge pull request #5918 from mockydevs/feat/drop-shadow-colour-picker
Drop Shadow: a swatch beside Color opens the Color Picker (#5364)
2026-11-07 09:00:28 +08:00
BFlat c0a40216ce Merge pull request #5917 from mockydevs/fix/boolean-area-check
Path booleans: check the windings against the operands' areas and resolve the operands when they don't add up (#5478)
2026-11-07 08:59:49 +08:00
dotCooCoo 7e22d3816a Tests: the pan test also pans with the Selection tool
a_pan_moves_the_marks_without_building_them covered Direct Selection
only. It now runs with both tools.

The module comment and MAX_PAN's comment now say what is kept as
triangles and as document points, and when a pan builds the marks again.
A test label now says points rather than px.

The timings in docs/target-app-parity.md are measured again with 10 fill
colors on the 2,000 circles. The pixel sentence there also names the
rounding errors of kept vertices.
2026-11-07 05:15:15 +07:00
dotCooCoo ae69e5d1e1 Docs: selection marks timings measured on the final build
The progress line gives the release-build timings from the head that places marks by document point.
2026-11-07 05:15:14 +07:00
dotCooCoo 6c1f426dd0 Canvas: selection marks are placed by the same sum as the rest of the canvas
Kept squares and handles hold document points, and each frame maps them from the view's center as Xf::to_screen does. A pan's distance comes from the difference of the two view centers.
2026-11-07 05:15:14 +07:00
dotCooCoo dcc1b2158c Tests: canvas frame helper reads the selection's marks as shapes
A frame that repeats a view now draws the marks as one mesh. frame_output drops the kept marks first, so the tests that read outlines and anchors from the frame's shapes keep working.
2026-11-07 05:15:14 +07:00
dotCooCoo 480bed78c2 Docs: selection marks timings measured on the final build
The progress line gives the release-build timings of the head that tests each subpath and handle against the view, and says which corner can differ after a pan.
2026-11-07 05:15:13 +07:00
dotCooCoo 94741cdae1 Canvas: selection subpaths and handles out of view add no triangles to a frame
Each subpath and each direction handle is now tested against the view on its own, and gets its triangles the first time it is in view. A group or compound path with one subpath in view, or a long path zoomed in with a few of its handles in view, draws only those.
2026-11-07 05:15:13 +07:00
Sven Lafebre a83a0054ea Part of #5964: stroke gradients cover an arrowhead to the end of its reach
With ribs only at the path's corners (an Along gradient), the ribs that reach
across an arrowhead stopped at the last corner inside its reach, so the slice
narrowed from the head's tip towards the next corner and left the corners of
a Triangle head's base outside every slice. Where each arrowhead's reach ends
now gets a rib of its own.
2026-11-07 05:15:12 +07:00
dotCooCoo 18015f3631 Type: a selected story stays selected when its text leaves the edited frame
When a frame threaded in before the edited frame takes all of the story's
text, the edited frame is left with no text while the story stays
selected. The other frames' text is now highlighted, Delete and Backspace
replace the story, an Alt+arrow step changes the tracking of every frame,
and Copy and Cut take the story. A story whose frames hold no text has
nothing to copy, and Delete in it records no undo step.
2026-11-07 05:15:12 +07:00
dotCooCoo 4a5ff880ff Canvas: selection outlines and anchors are reused between frames
The canvas flattened every selected object's outline and tessellated its
anchors and handles again in each frame. It now keeps them per object as
one mesh, valid for the object's node, layer color and selected anchors.
An idle frame draws the mesh again. A pan moves kept outlines and handles
and places the anchor squares again.

A frame with a new zoom, rotation or display scale draws plain shapes and
keeps nothing, and the next frame at that view builds the marks. Entries
of objects that leave the selection or the document are dropped.
2026-11-07 05:15:12 +07:00
dotCooCoo 22bb2ac8a6 Type: a selected story's highlight and typing follow its current thread
With a whole story selected, the highlight and typing read the frames saved
at Select All, while a pick, a fill and the other story-wide edits read the
document's thread. A frame added by text.thread.add took a pick without being
highlighted, and typing left its text in place.

Both now read the thread through Document::story_of. A frame threaded in
during the selection is highlighted and takes the edit, and a frame that
leaves the thread is not highlighted and keeps its text.
2026-11-07 05:15:11 +07:00
dotCooCoo c969b7857d Type: an Eyedropper pick on a selected story styles every frame
appearance.copyFrom and a fill or stroke change on a story selected by
Select All no longer skip locked frames, hidden frames and frames on a
locked artboard. They apply to every frame of the story, as the Character
panel's story edits do. appearance.copyFrom still leaves out a frame that
is its source.
2026-11-07 05:15:11 +07:00
Sven Lafebre 1b62f86b8c Fix #5714: doc comments on the width profile tests 2026-11-07 05:15:10 +07:00
dotCooCoo f534b0061a Type: switching to the Eyedropper keeps a whole-story selection
With a threaded story selected by Select All, switching to the Eyedropper kept
only the edited frame's selection, so a pick styled one frame. The selection now
carries the story's frames, a pick or Shift-click applies to the text of every
frame as one undo step, and switching back to a Type tool restores the story
selection. A selection inside one frame and unthreaded type behave as before.

A pick and a fill or stroke change on a selected story leave locked and hidden
frames and frames on a locked artboard as they are. appearance.copyFrom leaves
out a frame that is its source.

Typing over a selected story no longer removes the text of a frame whose thread
was removed after Select All.
2026-11-07 05:15:10 +07:00
Sven Lafebre d208f5da64 Contributors: Sven Lafebre's name 2026-11-07 05:15:10 +07:00
dotCooCoo 0c570dee87 .ai import: paths with an Art brush open with the brush on their stroke
A path with an Art brush comes in as the path, with the brush on its
stroke at its weight, instead of as its drawn look, when the brush
stretches art of solid-filled paths along the path, unflipped, at 100% in
Tints. The art runs on the side of the path the file draws it.

The drawn look stays for other colorizations and widths; Proportional,
between-guides and flipped brushes; type; a path with settings of its own,
a variable width, effects, a swatch stroke or an entry that isn't read;
and art with strokes, gradients, patterns, masks or effects, or no length.

A brushed stroke, Calligraphic ones too, takes the brush the Brushes panel
keeps under its name, and an image with a brush keeps its drawn look.

In every document, Tints and Tints and Shades take art in black ink alone
by its ink amount, and a process or gray stroke color's tints and shades
stay in that color's model.

Place and Expand bring the brushes the art uses, renaming on conflict.

Part of #637.
2026-11-07 05:15:09 +07:00
Sven Lafebre 9da56717a0 Fix #5714: widths run smoothly between width points
The width between two width points was a straight line, so a variable-width
stroke turned a corner at every width point.

- Each side of a width profile now follows a monotone cubic (Fritsch-Carlson)
  through its points: no kink at a point, flat at a point wider or narrower
  than both neighbours, never past either point of a span. Points on one line
  stay on it and two-point tapers are unchanged; stacked points still step.
- widest() counts each span's wider left and wider right, since the two sides
  needn't peak together.
- The outliner samples straight runs between width points closely enough to
  follow the curve to the drawing tolerance (at most 64 samples per span and
  4,096 per piece); straight spans get none.
- Tests that expected straight-line widths now expect the curve. The stroke
  gradient coverage test uses Teardrop instead of Wave until #5964 is fixed.
2026-11-07 05:15:09 +07:00
dotCooCoo ab3ac3d429 .ai import: envelopes map from their stroked box when the file saves its size
When Distort Appearance is on and the size a `.ai` saves for an
envelope's contents (`AIDeformArtWidthKey`, `AIDeformArtHeightKey`)
matches the contents' bounds with strokes, the reader now maps the
contents from that stroked box. It used to map them from the geometric
bounds, half a stroke inside that box, so an envelope of stroked art
could differ from its drawn art and keep the drawn art with a note.

Envelope Options hold the box's margins as `boundsMargin`, shares of the
geometric bounds at the top, bottom, left and right. Native files write
them only when they are not zero, and `object.envelope.info` reports
them then. Leaving Edit Contents measures them again when the strokes
reach differently than when Edit Contents began, and the node holds
what they measured then until it leaves. New envelopes have no
margins, so their results do not change. Contents with no width or no
height, such as one straight line, get no margins.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-07 05:15:08 +07:00
dotCooCoo b50a6bcad4 PDF export: the link walk measures only linked objects and clipping groups
The walk that writes link annotations measured every object at every
level, on every export that can have links, and read the box only for
an object with a URL that opens and for a clipping group. It now
measures only those, so a document with no URLs or clipping groups is
not measured a second time. The link annotations are unchanged.

The output is byte for byte the same on a document of linked objects in
plain and clipping groups on and off the page, with default settings,
with uncompressed text and with PDF layers.
2026-11-07 05:15:08 +07:00