Commit Graph
4586 Commits
Author SHA1 Message Date
JonRC 400a49666a Pending filters read the file they were made over
A filter over `currentfile` waits until it is first read, and it took
its data from whichever file was running by then. One made over the
program's own file and first read inside a file run with `cvx exec`
read that file instead, and one made over a file being run, first read
in a file that one runs, read the inner file. The pending stream now
records the file it was made over (a chained filter inherits it), and
`materialize` decodes from that file.
2026-11-03 15:57:03 +07:00
JonRC 6fc82a141f Fix #5321: currentfile in a file being run is that file
A file run with `cvx exec` was read whole and run as a separate
program, while `currentfile` stayed the outer EPS. The PLRM has
`currentfile` return the topmost file being run, positioned after the
last token read. Ghostscript's eps2write runs each page's content and
each Type 3 glyph from a SubFileDecode filter, and its `ID` reads the
inline image's samples through `currentfile`, so they were read from
the outer file and then ran as program.

A file being run is now read object by object from its own data, and
while it runs it is `currentfile`. A filter made over it waits to
read, as one over the program's own file does, so it starts where the
program is when the filter is first read.
2026-11-03 15:57:03 +07:00
JonRC d627a776de Cite the PostScript Language Reference by its public URL 2026-11-03 15:57:00 +07:00
JonRC 8fb394ca16 Fix #5318: known answers false for keys no dictionary holds
`known` raised a typecheck for any key that can't be a key here (an
array, a dictionary, a real with a fraction). The PLRM allows any
object but null as a key, and since `put` refuses such keys, no
dictionary holds one: `known` now answers false, and null still raises
the typecheck. Ghostscript's eps2write prolog looks each inline-image
value up in a dictionary of abbreviations, and an image with two
filters has an array there.
2026-11-03 15:57:00 +07:00
JonRC eca414044b Cite the PostScript Language Reference by its public URL 2026-11-03 15:56:58 +07:00
JonRC 097b013ea7 Fix #5316: StandardEncoding and ISOLatin1Encoding are Encoding resources
The standard encodings were names in systemdict only, and the Encoding
category was empty, so `/StandardEncoding /Encoding findresource`
failed with undefinedresource. The PLRM (3rd ed.) has both as
instances of the Encoding category, the same arrays as the names.
Ghostscript's eps2write prolog takes StandardEncoding that way for a
font whose encoding is a Differences dictionary with no BaseEncoding,
so files with its Type 3 text stopped there.
2026-11-03 15:56:58 +07:00
Dylan M. Taylor 2fec613353 Place: the place cursor reads its files within the roots it was loaded in
An agent confined to automation roots could load the place cursor, with
file.place.queue or tool.setOption, and the files were placed later, by
a click of the person at the keyboard, outside any roots. tool.setOption
checked a queued path but not files given inline, whose linked files (an
SVG's referenced images) were then read with the keyboard user's
unrestricted access.

The session now keeps the automation roots in force when the cursor's
queue is loaded, and both the engine's own placement and the desktop
app's background placement read the queued file within them. A queue
loaded outside any roots places as before.
2026-11-03 15:56:55 +07:00
Dylan M. Taylor a4aa1960cf Threaded text: a frame listed twice flows the story once
Reflow copied each listed frame's text into its thread's story, so a
document that listed one frame several times in a thread, or in several
threads, repeated that text in the story and wrote the grown story back
for the next thread to copy again, growing the text with every
repetition while the document opened. Reflow now keeps each frame at its
first place in the thread list only.
2026-11-03 15:56:53 +07:00
Dylan M. Taylor d9e3df23b1 Brushes: leave out an opacity mask whose root symbol draws a brushed stroke
The filter that keeps brush pieces from drawing a brush again walked a
mask's art but never looked at the mask's root itself. A symbol instance
at the root of a mask, whose symbol draws a stroke with the brush, then
survived and re-entered the brush while the mask was rendered, without
end. The mask goes now, as such an instance goes among the children.
2026-11-03 15:56:50 +07:00
Maxwell Wang 4a0a3701b0 Fix Simplified Chinese translation of Luminosity 2026-11-03 15:56:48 +07:00
Brandon Thomas 065a646799 Merge pull request #5280 from dotCooCoo/feat/symbol-nine-slice-guides-on-canvas
Symbols: 9-slice guides are shown and dragged on the canvas while editing a symbol
2026-11-03 00:19:44 -05:00
Brandon Thomas 2ef386c924 Merge pull request #5249 from dotCooCoo/feat/recolor-wheel-display
Recolor Artwork: the Edit tab shows the colors on a smooth wheel, a segmented wheel or as color bars
2026-11-03 00:19:40 -05:00
Brandon Thomas d232a29591 Merge pull request #5237 from dotCooCoo/feat/global-edit-shift-exclude
Global Edit: a Shift-click on a highlighted match leaves it out of the edit
2026-11-03 00:19:36 -05:00
Brandon Thomas 0b0a9c43c9 Merge pull request #5310 from storytold/fix/sec-affinity-field-index
Affinity import: index the fields of large objects and read four rectangle corners
2026-11-03 00:19:32 -05:00
Brandon Thomas 7f484253d2 Merge pull request #5304 from storytold/fix/sec-export-name-linear
Export for Screens: name patterns and taken names take linear work
2026-11-03 00:19:29 -05:00
Brandon Thomas 69fa98dc94 Merge pull request #5302 from storytold/fix/sec-affinity-master-copy-cost
Affinity import: count path segments and masks in master page copies; range-check vector masks
2026-11-03 00:19:26 -05:00
Brandon Thomas 9c91939701 Merge pull request #5300 from storytold/fix/sec-resource-name-index
Brush and symbol libraries: look definitions up by name
2026-11-03 00:19:22 -05:00
Brandon Thomas 03b256bdb6 Merge pull request #5298 from storytold/fix/sec-gradient-stop-lookup
Gradients: midpoints and freeform points find their stops by binary search
2026-11-03 00:19:18 -05:00
Brandon Thomas 9134297774 Merge pull request #5294 from storytold/fix/sec-depth-limit-linear
Depth limit: merge containers at the cap in one pass over the siblings
2026-11-03 00:19:15 -05:00
Brandon Thomas c1c5fcb625 Merge pull request #5292 from storytold/fix/sec-page-range-linear
Page ranges: overlapping intervals skip indices already picked
2026-11-03 00:19:11 -05:00
Brandon Thomas b72215e71a Merge pull request #5290 from storytold/fix/sec-repeat-copy-budget
Repeat: the instance budget counts opacity-mask art and the nodes each copy holds
2026-11-03 00:19:08 -05:00
Brandon Thomas 70e32e449b Merge pull request #5289 from storytold/fix/sec-dxf-export-budgets
DXF export: bound curve flattening work and expanded symbol art
2026-11-03 00:19:04 -05:00
Brandon Thomas b1faef0081 Merge pull request #5271 from dotCooCoo/fix/projective-scale-invariant-checks
Geometry: a projective map's horizon and invertibility checks do not depend on its scale
2026-11-03 00:19:01 -05:00
Brandon Thomas 6d10ae13a3 Merge pull request #5242 from rahul05ranjan/i18n-sv-complete
i18n(sv): translate the 22 strings the report listed as missing
2026-11-03 00:18:57 -05:00
Brandon Thomas e3a1d0999f Merge pull request #5240 from rahul05ranjan/i18n-ru-complete
i18n(ru): translate the 130 strings the report listed as missing
2026-11-03 00:18:54 -05:00
Brandon Thomas c6131cf798 Merge pull request #5243 from dotCooCoo/fix/svg-round-trip-edge-ellipse
SVG: an exported ellipse imports as the four-anchor ellipse it was written from
2026-11-03 00:18:50 -05:00
Brandon Thomas 57e0e55bba Merge pull request #5244 from dotCooCoo/feat/select-same-text-fill-stroke
Select: Same › Text Fill & Stroke Color selects type whose fill and stroke both match
2026-11-03 00:18:46 -05:00
Brandon Thomas a47ebfc3ce Merge pull request #5245 from dotCooCoo/fix/inline-graphic-manual-kerning
Type: an inline graphic takes its character's manual kerning
2026-11-03 00:18:42 -05:00
Brandon Thomas 0116c2522e Merge pull request #5250 from dotCooCoo/fix/pdf-spot-reserved-names
PDF export: spot inks named All or None print as spot inks
2026-11-03 00:18:39 -05:00
Brandon Thomas a824ea9ea1 Merge pull request #5260 from dotCooCoo/fix/document-info-counts-each-object-once
Document Info: Objects counts each object once
2026-11-03 00:18:35 -05:00
Brandon Thomas cc1d906c4c Merge pull request #5259 from dotCooCoo/fix/tcy-style-offsets-in-range
Type: Tate-chu-yoko offsets in character style definitions stay in range
2026-11-03 00:18:32 -05:00
Brandon Thomas ef37b37213 Merge pull request #5314 from JonRC/fix/eps-gcheck-simple-objects
Fix #5312: EPS files written by Ghostscript's eps2write open
2026-11-03 00:18:24 -05:00
Brandon Thomas 1b503c618b Merge pull request #5279 from Silvertree2010/fix/h5763-svg-export-writes-invalid-xml-wh
Drop invalid XML characters from SVG link URLs and aria-labels
2026-11-03 00:18:21 -05:00
Rahulandrahul05ranjan b191900855 i18n(sv): drop the rows MENU_KEEP_AS_IS forbids (gate fix)
The gate failed kept_menu_names_are_menu_labels_left_in_english: sv is in
KEEPS_MENU_NAMES, so the MENU_KEEP_AS_IS names (VectorCraft, OpenType, the
workspace names, the perspective-grid presets) must stay in English. The
coverage report had listed them as missing; the 20 rows are removed so the
names fall back to English again. The two genuinely-missing strings
(Font Size:, digits Hindi) stay.

Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
2026-11-03 10:18:58 +05:30
Rahulandrahul05ranjan 32d59f7239 i18n(ru): drop the rows MENU_KEEP_AS_IS forbids (gate fix)
The gate failed kept_menu_names_are_menu_labels_left_in_english: ru is in
KEEPS_MENU_NAMES, so the MENU_KEEP_AS_IS names (VectorCraft, OpenType, the
workspace names, the perspective-grid presets) must stay in English. The
coverage report had listed them as missing; the 20 rows are removed so the
names fall back to English again. The 110 genuinely-missing strings stay.

Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
2026-11-03 10:18:51 +05:30
Brandon ThomasandClaude Opus 5.5 14d617f1d4 Format the symbol library test (rustfmt)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 23:44:01 -05:00
Dylan M. Taylor 9086842f4b Format with rustfmt 2026-11-03 04:31:56 +00:00
Dylan M. Taylor fb67e28954 Format with rustfmt 2026-11-03 04:31:54 +00:00
Dylan M. Taylor 68602ac344 Merge pull request #3990 from dotCooCoo/feat/native-save-precision
Native format: document.save can write path coordinates at a fixed precision
2026-11-02 23:29:28 -05:00
JonRC e44f5a1b77 Fix #5312: EPS files written by Ghostscript's eps2write open
`gcheck` and `scheck` answered false for every operand. The PLRM (3rd
ed., `gcheck`) says they are true for a simple object, and false only
for a composite one in local VM. The eps2write prolog copies its
initial graphics state into global VM and leaves a value alone only
when `gcheck` is true. So the integers in the `currenthalftone`
dictionary took the copy path, left the stack one item off, and the
next `put` failed with a typecheck in `cp2g`.

Simple objects now answer true. Composites still answer false, since
every composite here is in local VM.
2026-11-03 01:07:29 -03:00
Dylan M. Taylor ed4a663986 DXF export: charge symbol art as it is placed unclipped, test the segment budget
Count nine-slice symbol art with clips off, as place_symbol_art_unclipped
places it, so art crossing the guides is not over-charged; add a test that
the flattening segment budget stops a path independently of the point
budget; format.
2026-11-02 22:33:39 -05:00
Dylan M. Taylor aaca80c961 Affinity import: bound archive index names and charge failed entry extraction (#5291)
The table chain's records and entry names now have a whole-archive allowance, only the
first name of an id is decoded and kept (no clone into the entry map), and an entry's
size is charged before it is decompressed and stays charged when it fails, with the
failure remembered so a broken entry is not decompressed again.
2026-11-02 21:36:16 -05:00
Dylan M. Taylor f8f9280d75 Repeat test: drop the full-budget expand from the large-source test 2026-11-02 21:31:03 -05:00
Dylan M. Taylor 1f80c018c7 Gradients: compare NaN samples as printed in the stop lookup test 2026-11-02 21:03:30 -05:00
Dylan M. Taylor 572a51894f Affinity import: index the fields of large objects and read four rectangle corners
Object::get scanned every field for each lookup, and a shared object is looked up again
on every visit. Objects with more than 16 fields now keep a sorted tag index (first and
last position), so get and get_last are binary searches with the same first/last-
occurrence results. Rectangle corner types and radii read at most the four entries that
can matter instead of converting the whole arrays.
2026-11-02 20:46:58 -05:00
Dylan M. Taylor f1d4969864 DXF export: bound curve flattening work and expanded symbol art
Flattening a path for DXF capped the points it kept but kept flattening every remaining curve
after the cap, each curve at a fixed tolerance however large it was. Symbol instances placed
inside symbols were cloned and walked once per instance with only the nesting depth bounded, so
a small symbol graph of empty symbols could fan out into billions of visits that write nothing.

- Flatten through vectorcraft_geom::flatten (a bounded number of segments per curve) and stop
  at the first curve past the point or segment budget.
- Charge each symbol instance's art to MAX_SYMBOL_NODES with charge_symbol_art before placing
  it, as the document does elsewhere; once spent, no further instances are expanded.
2026-11-02 20:43:17 -05:00
Dylan M. Taylor 67ef83f155 Gradients: midpoints and freeform points find their stops by binary search
A gradient whose stops are not strictly increasing (repeated offsets, or
a file's unsorted stops) sampled each Classic off-centre midpoint, and
each freeform point when recoloring, by scanning the stops from the
start, so many stops and points cost their product. Such stops now get
an index of the furthest offset reached so far, which never decreases,
and each sample finds the pair of stops sample() would pick by binary
search, giving the same colour for any order of offsets.
2026-11-02 20:39:15 -05:00
Dylan M. Taylor 9a1ac9dad3 Brush and symbol libraries: look definitions up by name
Making a brush or symbol library, and gathering the resources copied
art uses, found each referenced swatch, symbol, pattern, graphic style,
text style and brush by scanning all the definitions of its kind, and
checked library membership and panel order by scanning the lists again,
so a library or document of N definitions cost N squared comparisons.
Each kind is now indexed by name the first time a reference to it is
followed, and the library code looks names up in sets and maps built
once.
2026-11-02 20:38:22 -05:00
Dylan M. Taylor 1d7c8f93ab Export for Screens: name patterns and taken names take linear work
The file name pattern searched the rest of the pattern for a closing
bracket at every opening bracket, so a pattern of many unmatched brackets
took quadratic time to render, in the export and its live preview. A
token's name never holds a bracket, so the search now stops at the next
opening one.

Output naming tried -2, -3 and so on from the start for every file given
a taken name, so one name pattern over many artboards rebuilt and looked
up every number used before for each file. It now goes on from the last
number given for that name, and remembers which file got a name from it.
2026-11-02 20:35:58 -05:00
Dylan M. Taylor 1ad4233846 Page ranges: overlapping intervals skip indices already picked
parse_range walked every index of every interval, so a range that names
the same pages many times ("1-,1-,1-,...") cost the number of parts
times the page count. Picked indices now link to the next unpicked one,
so each page is visited about once whatever the overlap.
2026-11-02 20:33:30 -05:00