Commit Graph
4872 Commits
Author SHA1 Message Date
FredApps 448ec5e468 Merge pull request #2660 from dotCooCoo/fix/cmyk-view-conversion
CMYK view: convert the blended inks to screen colours on the render threads
2026-11-12 17:59:36 +01:00
FredApps 4d86f3e34a Merge pull request #2355 from dotCooCoo/fix/mcp-dirbuilder-windows
Fix MCP temporary directory build on Windows
2026-11-12 17:58:36 +01:00
FredApps b7321d31b8 Merge pull request #2659 from dotCooCoo/feat/justification-auto-leading-single-word
Justification: the dialog sets Auto Leading and Single Word Justification
2026-11-12 17:58:12 +01:00
FredApps 6e50ee3974 Merge pull request #2650 from dotCooCoo/feat/paragraph-value-checks
Text: paragraph spacing and justification values are checked
2026-11-12 17:57:35 +01:00
FredApps 2522b78ef3 Merge pull request #2656 from dotCooCoo/fix/preflight-off-interface-thread
Preflight: check the document on a background worker, not on every edit
2026-11-12 17:56:38 +01:00
Dylan M. Taylor e2b5dbaa8a Merge pull request #2648 from dotCooCoo/fix/issue-1999
Compose: vertical Center, Bottom and Justify measure to the last baseline
2026-11-12 11:29:27 -05:00
jayzed80 5c484618ca Save: a TIFF, BMP or PSD too big for opening to inflate is stored as is, so the document reopens (#2283) (#2701)
save deflated every asset that isn't PNG, JPEG, GIF or WebP, with no size
cap, while opening refuses a deflated asset over 1 GiB or deflated entries
over 4 GiB together. An asset past either cap is now stored as is, which
opening reads at any size. Smaller assets are deflated as before, and the
zip bomb guard on load is unchanged.
2026-11-12 15:53:23 +00:00
Adithya Shankaran 92043b4c48 Automation roots: refuse COM¹ to LPT³ and a device name before a colon (#2383)
* Automation roots: refuse COM¹ to LPT³ and a device name before a colon

is_device_name missed COM¹, COM², COM³ and LPT¹, LPT², LPT³, which Windows reserves as it does COM1.
It also cut the name only at a period, so COM1: and NUL:x were not seen as device names.

* Credit my name in the About window

* Automation roots: document the device-name tests

CodeRabbit's docstring check counts the touched tests. same_component stays without a doc comment, because #2205 deletes that function and a doc line above it conflicts.

* Automation roots: record the device-name refusal

The MCP roots description and the roadmap now name COM¹ to LPT³ and a device name before a colon.
2026-11-12 15:09:39 +00:00
autocraft-bot[bot] a17fb5d3d8 Merge pull request #2341 from Hamza0101/fix/datamerge-fields-in-tables
Data Merge: a field in a table cell goes into the cell and is filled (#2315)
2026-11-12 12:00:52 +00:00
autocraft-bot[bot] 424d08d935 Merge main into fix/datamerge-fields-in-tables 2026-11-12 11:38:19 +00:00
Dylan M. Taylor 027bbae9cb Engine: index style, tag, swatch and run lookups; bound polygon sides, Change All and spelling candidates
* fix(engine): index lookups that were quadratic in a document's styles, tags, swatches and runs

* address review: first swatch per name in book sync; bound spelling input before collecting

* address review: keep the last source style per name in book sync; bound GREP replacement bytes while generating them

* address review: write GREP replacements into a byte-bounded buffer; gate keep_last test off wasm

* merge main into fix/sec-engine-linear-lookups

* address review: make the suggestion length-cap test deterministic
2026-11-12 06:28:15 -05:00
Dylan M. Taylorandautocraft-bot[bot] ff0463e299 Exports: leave out text the page doesn't show (inherited conditions, deletions, hidden layers)
* fix(export): leave out text hidden by inherited conditions or deletion in every exporter

* address review: skip hidden frames in page text and hidden article items; first visible paragraph as nav label; read table anchor's own format

* address review: skip nonprinting frames and non-printable layers in fixed-layout page text

* Apply review fixes

- crates/epub/src/html.rs
- crates/engine/src/cmd/export/formats.rs

* Apply review fixes

- crates/epub/src/html.rs
- crates/engine/src/cmd/export/formats.rs

* address review: fixed-layout page text skips frames in inactive object states

* address review: place a threaded story at its first shown frame; skip it only when every frame is hidden

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-12 06:28:07 -05:00
Dylan M. Taylorandautocraft-bot[bot] b7174dc92d Engine: bounded DTD validation, compound-path hole orientation
* dtd: bounded matching steps, element depth and problem count

* address review: stop DTD matching when a step charge fails; refuse hole orientation past its budget

* Apply review fixes

- crates/engine/src/dtd.rs

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-12 06:27:59 -05:00
Dylan M. Taylorandaiongg 568f25fa9f Fonts: cap decoded names, bound outline flattening, cache fallback coverage
* fonts: cap decoded names, outline flatten tolerance by size, coverage cache for system fallback

* Apply review fixes

- crates/fonts/src/fontdb/system.rs
- crates/fonts/src/fontdb/names.rs

* Apply review fixes

- crates/fonts/src/fontdb/system.rs

* address review: cap flattened edges in has_serifs

* address review: check alias blankness before capping

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-12 06:27:53 -05:00
Dylan M. Taylor 665fe2a8e4 Format: a failed entry read counts against the archive budget
* format: bytes a failed entry read inflated count against the archive budget

* address review: mutate the payload bytes explicitly in the checksum test

* address review: charge a failed read to the budget it belongs to (stored vs deflated)
2026-11-12 06:27:47 -05:00
Dylan M. Taylor 26d5c8941c IDML: story export and object-style overlay in linear time, embedded image budget
* idml: story runs and marker offsets found once, object-style overlay by position, embedded image budget

* address review: saturating embedded-bytes counter

* address review: IDML export past the embed limit succeeds and warns for each image written as a link

* address review: an unlinked image is always embedded, only linked ones fall back to their link
2026-11-12 06:27:41 -05:00
Dylan M. Taylor a41fc046f3 Data merge: a record range stops expanding once the limit is met
* Data merge: a record range stops expanding once the limit or the record count is met
2026-11-12 06:27:35 -05:00
Dylan M. Taylor eb0ea78d9a Images: a WebP with an ICC chunk longer than the file is read without its profile
* Images: a WebP whose ICC chunk declares more than the file holds is read without it
2026-11-12 06:27:29 -05:00
Dylan M. Taylorandautocraft-bot[bot] 23465223bc xtask: refuse an oversized corpus archive before extracting it
* xtask: refuse a corpus archive that expands past the cap before extracting it

* address review: a within-cap answer needs tar to exit successfully

* Apply review fixes

- xtask/src/main.rs

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-12 06:27:24 -05:00
Dylan M. Taylor f87c24a1cd PPTX export: bound the retained glyph-to-character maps
* PPTX export: keep only the last four faces' glyph-to-character maps
2026-11-12 06:27:18 -05:00
dotCooCoo c9cc76e6ad CMYK view: the conversion returns the number of bands it converted
With more render threads than bands of 32 rows fit evenly, the rows split
into fewer bands than requested, and the returned count was the requested
one. It is now the number of bands converted.
2026-11-11 22:45:44 -08:00
dotCooCoo eda934fff0 Compose: vertical justification keeps moved lines inside a shaped frame
Center, Bottom and Justify moved the lines of a shaped frame without
testing them against the outline, so in a frame that narrows towards the
bottom a line set in a wide band ended up crossing the outline. Each moved
line's slot is now tested against the outline over its new band, as when
the line was fitted, and the text goes only as far down as every slot
fits. In a frame that narrows and widens again, the search scans the
rooms from the most down (every point, at most 512 steps) before halving,
so the text can still reach a lower part past a narrow waist.
2026-11-11 21:54:27 -08:00
dotCooCoo bdabdc8155 Preflight: show a pending first check as checking, and rebuild document indexes on grid changes
- The status bar and the Preflight panel show a gray light and "Checking" until the active
  document's first check ends, instead of a green "No errors".
- The cross-reference and running-header indexes are keyed on the baseline grid and the font
  scope as well, so a change to either builds them again, in a cache and in a cache over it.
- The test helper that waits for the preflight worker fails when the worker ends without a result.
2026-11-11 21:51:37 -08:00
autocraft-bot[bot] 2e1d17e1fa Apply review fixes
- crates/ui-egui/src/preflight_worker.rs
2026-11-12 05:32:14 +00:00
.CooCoo 6fff5328eb Tests: type.align refusal cases name the check that refuses each (#2662)
Follows #2645. Its test said a misspelled key used to apply Align Left.
Only empty params and a bare string did; the parameter check already
refused a misspelled key, and the value parser refused an unknown
value. Each case now asserts the refusal message it gets.
2026-11-12 04:52:41 +00:00
dotCooCoo c69db89862 Justification: Auto Leading stores the shown percent, and the current choice is no edit
The Auto Leading field shows whole percents, and it now stores the
whole percent it shows, so a typed 500.4% (shown as 500%) is accepted
as 500% instead of being refused. Picking the Single Word
Justification the paragraphs already have is no longer an edit, so OK
adds no undo step for it.
2026-11-11 20:06:28 -08:00
dotCooCoo 27963d6d05 Justification: the dialog sets Auto Leading and Single Word Justification
Type > Justification and Paragraph Style Options > Justification now show
Auto Leading (0% to 500% of the type size) and Single Word Justification
(Align Left, Align Center, Align Right, Full Justify). Both fields show the
selected paragraphs' values, or blank where they differ, and OK writes
autoLeading and singleWordJustify only when they were edited. An Auto
Leading outside 0% to 500% keeps the dialog open with the reason.
2026-11-11 19:45:30 -08:00
dotCooCoo 9c4c3730ab CMYK view: convert the blended inks to screen colours on the render threads
In the CMYK blend space view (Proof Colors off) every render converted
each pixel of the ink passes' area from the blended inks to a screen colour
on the calling thread, through a 16-entry lookup per pixel. With render
threads it now converts bands of rows on that many threads at once, at
least 32 rows a band. The colours are the same; the Wasm build and
single-threaded renders convert on one thread as before.
2026-11-11 19:42:30 -08:00
dotCooCoo ee69d5ac39 Preflight: the worker keeps its compositions out of the interface thread's cache
The worker checks the document state it was given, which is often one
edit behind the interface. It composed that older state into the shared
composition cache, replacing the interface thread's composition of the
current state, so the next frame composed the edited story again (about
14 ms per edit for a 10-page story).

Cache::over makes a cache that uses another cache's compositions of the
same state and keeps whatever it composes to itself. The worker checks
with one over the interface thread's cache, keeps it for the next check
of the same document, and drops it after a minute without jobs.

With no active document, the job waiting for a busy worker is dropped,
so it no longer keeps a closed document in memory until another
document opens.
2026-11-11 19:42:03 -08:00
dotCooCoo 099b89f53d Preflight: check the document on a background worker, not on every edit
The status bar's error count ran the whole-document preflight check on
the interface thread for every new state of the document, so every drag
step and every typed character waited for it. The Preflight panel ran
the same check on every frame. The check composes every story and asks
the file system about every linked graphic, so its cost grows with the
document: on a 300-page document with 900 placed images it took 137 ms
on a fast machine, and moving or resizing a frame and typing became
unusable on large documents.

The check now runs on a worker thread that takes the newest state of
the document; the issues last found stay shown until it answers. An
unchanged document is checked again every few seconds for linked files
changed outside the app, a save under a new path or a font reload is
checked again, and a check blocked on another document's linked file
is handed off to a fresh worker after 200 ms. Tests and the web build
check on the interface thread, once per state of the document.

preflight::check_document takes the document, the composition cache and
the save path, so the worker needs no session.
2026-11-11 18:53:44 -08:00
dotCooCoo 7809f5e9da Text: frame columns, gutter, switches and indents are checked too
object.textFrameOptions refuses a gutter outside 0 to 15552 pt, a column
count outside 1 to 40 (it was clamped) and an on/off option that is not
true or false (it was skipped). The Control bar's Columns field stops at
40, as the other column fields do. The params text gives the ranges and
lists flexibleWidth.

type.para and paragraph style create and edit refuse left and right
indents outside 0 to 15552 pt and first and last line indents outside
-15552 to 15552 pt. A style made from the selection is checked with the
values it takes from the selection.

style.paragraph.apply and style.paragraph.redefine check that Minimum,
Desired and Maximum stay in order in each justification row they change,
over the overrides paragraphs keep, and refuse the change otherwise.
2026-11-11 18:42:32 -08:00
dotCooCoo 9041fd3153 Compose: Bottom, Center and Justify ignore corner radius and descent room
Bottom and Justify now put the last baseline on the bottom inset in a
frame with a corner radius as in a rectangular one, so a radius no longer
moves the text when the bottom inset is above 0. Center puts the last
baseline halfway between where Top sets it and the bottom inset even when
the frame is too short for the descenders under it, so Cap Height text in
a tight frame is centered. The last line's descenders hang below its
baseline, into the bottom inset and past the frame's edge when the inset
is smaller than the descent. An earlier line whose descenders reach below
the last baseline (tight leading) is not moved past the text area. Above
footnotes and in vertical frames the descenders still stay inside the
text area.
2026-11-11 18:02:16 -08:00
dotCooCoo e90517be45 Text: paragraph spacing and justification values are checked
type.para, style.paragraph.create and style.paragraph.edit accepted any
number for paragraph spacing and justification. They now refuse Space
Before, Space After and same-style spacing outside 0 to 15552 pt, word
spacing outside 0% to 1000%, letter spacing outside -100% to 500%, glyph
scaling outside 50% to 200%, Auto Leading outside 0% to 500%, and a
Single Word Justification other than left, center, right or
fullyJustified. Each justification row needs Minimum <= Desired <=
Maximum over the values the paragraph or style resolves to after the
change, including the styles based on an edited style and the
paragraphs, table cells and notes that use them.

object.textFrameOptions refuses an inset outside 0 to 15552 pt or a list
that is not four sides, and a verticalJustification, firstBaseline,
autoSize or columnsKind that is not one of its names. These were applied
or skipped without an error before. IDML import reads these values as
before.
2026-11-11 17:51:19 -08:00
dotCooCoo 86867e8e42 Compose: vertical Center, Bottom and Justify measure to the last baseline
Vertical justification measured the free space down to the bottom of the
last line's descenders, so Center set text too high (most visibly with a
Cap Height first baseline) and Bottom and Justify left the descender depth
empty. The last baseline is now the bottom of the text: Bottom and Justify
put it on the bottom inset, and Center leaves as much room below it as
above the first line. The descenders may reach into the bottom inset but
not past the frame's edge; above footnotes, in vertical frames and in
shaped frames they stay inside the text area. Tables keep their bottom.

A shaped frame no longer tests the part of a line above its text area
against the outline, so a small corner radius leaves a Cap Height first
line where a rectangular frame puts it.

Fixes #1999
2026-11-11 17:31:56 -08:00
.CooCoo b284052acc Type: type.align without a value is an error (#2645)
type.align with no `align` key applied Align Left, so a call that
misspelled the key, or passed a bare string, changed the paragraphs to
left alignment instead of failing. The command now returns an error,
leaves the text unchanged and records no undo step. A named value still
applies, and `align: null` still removes the override.
2026-11-12 01:30:21 +00:00
Dylan M. Taylor 27d8eabb10 Render: clamp the blur size before the filter planner squares it (#2640)
* Render: a blur size is clamped to 1,000,000 pt before the filter planner squares it

* address review: bound effect extents and sigma before spread, padding and reach arithmetic
2026-11-12 00:33:50 +00:00
FredApps 4bdc036769 CI: nightly release dry run (#2633)
release.yml also runs nightly on main with craft-common-actions' dry-run: every release build
except macOS, with nothing signed, pushed or drafted. Breakage that only the release build hits
(riscv64, Flatpak, FreeBSD, packaging) then shows up the next morning instead of on release
day, as it did on 11 Nov 2026.
2026-11-11 23:03:58 +01:00
Dylan M. Taylorandaiongg d6a09639bf Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237)
* Repagination, swatch import and style folders: linear page numbers, resumed duplicate suffixes, bounded folder depth

* fix Section initializer after merging main

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:21:23 -05:00
Dylan M. Taylorandaiongg dc9eea2695 Small bounds: outline simplification, table row insertion, note ids, xtask stats (#2232)
* fix: iterative outline simplification, bulk row insertion, linear note ids, no symlink walking in xtask stats

* Apply review fixes

- crates/doc/src/tests.rs
- crates/geom/src/trace.rs

* Apply review fixes

- crates/geom/src/trace.rs

* address review: cover a maximal note id in tests, format trace test

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:20:58 -05:00
eba00a0dec Opening documents: index lookups in Document::check and the format-1 style upgrade (#2218)
* fix(doc): index items, threads and styles when opening a document

* Apply review fixes

- crates/doc/src/tests.rs

* address review: borrow style names in pin_para_default

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-11 16:20:34 -05:00
Dylan M. Taylorandaiongg 15bea9fa7a Tagged Text, RTF, EPUB classes and PDF layers: lookups by set or map instead of list searches (#2212)
* fix: index style, font, class and layer name lookups in exporters and importers

* Apply review fixes

- crates/epub/src/css.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:20:09 -05:00
Dylan M. Taylorandaiongg 5a3507510e File reads: refuse devices and pipes, cap whole-file reads (#2227)
* fix(engine): whole-file reads take regular files only, up to the format limit

* Apply review fixes

- crates/engine/src/io.rs

* Apply review fixes

- crates/engine/src/io.rs

* Fix failing CI check

- crates/engine/src/io.rs

* address review: refuse to save an encoded document longer than the open limit

* address review: open files for reading without blocking (FIFOs, stream-backed pseudo-files)

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:19:45 -05:00
Dylan M. Taylorandaiongg 8d59590449 Package: copy each font as it was loaded, check read roots, number duplicate names in one pass (#2208)
* fix(engine): package fonts from their loaded bytes under the read roots

* address review: a font's own file is neither overwritten nor packaged when it changed since loading

* Apply review fixes

- crates/engine/src/cmd/package.rs

* address review: compare packaged font file in fixed-size chunks

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:19:20 -05:00
Dylan M. Taylorandaiongg cfd99ba9b5 Automation roots: compare paths exactly; recovery reads only regular entry files (#2205)
* fix(engine): exact root containment and regular-file recovery entries

* Apply review fixes

- crates/engine/src/recovery.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:18:55 -05:00
Dylan M. Taylorandaiongg 34f24a4d2a Gradients: expand midpoint stops in linear time (#2214)
* fix(color): sample gradients by binary search when expanding midpoints

* Apply review fixes

- crates/color/src/gradient.rs

* Apply review fixes

- crates/color/src/gradient.rs

* Fix failing CI check

- crates/color/src/gradient.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:18:31 -05:00
Dylan M. Taylor eba5b9f845 datamerge: all further pages in one insertion, page lookups by start index (#2279) 2026-11-11 16:18:07 -05:00
Dylan M. Taylorandautocraft-bot[bot] c684db5428 Tools: selection bounds in one walk, bounded smart spacing and parent snapping (#2260)
* tools: selection bounds in one walk, caps on smart-spacing boxes and parent occurrences

* Apply review fixes

- crates/tools/src/lib.rs

* address review: iterative selection walk; stop collecting spacing boxes at the cap

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-11 16:17:42 -05:00
Dylan M. Taylorandautocraft-bot[bot] 79d7a912f1 Strokes: cap the points a wavy or hashed stroke places along a path (#2188)
* Strokes: cap the points a wavy or hashed stroke places along a path

* address review: zero-length quadratic contributes no length in stroke samples

* Fix failing CI check

- crates/geom/src/stroke_style.rs

* Fix failing CI check

- crates/geom/src/stroke_style.rs

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-11 16:17:18 -05:00
Dylan M. Taylorandautocraft-bot[bot] 589f5ff8a3 Engine: Erase and Smooth search each distinct drag sample once (#2272)
* engine: Erase/Smooth look at each distinct drag sample once, thinned past 4096

* Apply review fixes

- crates/engine/src/cmd/anchors.rs

* address review: decide whether a drag touched the path on every distinct sample, then thin

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
2026-11-11 16:16:54 -05:00
Dylan M. Taylorandaiongg bcbc3ed424 Story: appending text no longer scans every run and the whole prefix (#2245)
* doc: appending to a story extends the last run, no scans

* Apply review fixes

- crates/doc/src/story.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
2026-11-11 16:16:29 -05:00