Commit Graph
2879 Commits
Author SHA1 Message Date
Andee CollardandClaude Opus 5.5 aeccc9c5d3 PDF: validate an actual layer rewrite for explicit all-on choices
skylartaylor's review: a PDF can list readable layers yet fail the visibility
rewrite. On a synthetic 33-section xref history, object.layerOptions with
useDefaults:false and an empty hidden list was accepted (only hidden names
triggered #1670's rewrite check), the canvas could not draw the choice and
PDF export then failed.

Every explicit choice now runs one actual pdf_hide_layers rewrite per
distinct source before any item is edited or undo is recorded; this subsumes
the separate layerless check. Resetting to file defaults (useDefaults:true
or the legacy empty list) needs no variant and bypasses the check. #1670's
fail-closed canvas handling is kept alongside the explicit-override state: a
stored explicit choice (including all-on) whose source can no longer be
rewritten draws nothing rather than the unmodified source, and export errors.

The new regression test fails before this change (the all-on request is
accepted) and covers both selection orders, atomicity, undo depth, reset
bypass and the stale all-on fail-closed path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:51:48 +01:00
Andee CollardandClaude Opus 5.5 96a4a9060b Format: test one version 4 reader keeping both layer capabilities
skylartaylor review of #1647/#1671: both PRs introduced native format 4 for
different capabilities. Stacked on #1647, version 4 is one capability:
required_version (the single place that picks a version) asks for it when a
document has retained placed-graphic layer options or an explicit all-on PDF
layer choice, so a version 4 reader understands both. That merge was made
while rebasing "PDF: distinguish all-on layer choices from file defaults",
which also replaced its Document::all_items scan (document spreads only)
with Document::has_explicit_all_on_pdf_layers, covering parent spreads,
groups, anchored objects and nested story content; an all-on PDF on a parent
page previously saved as version 2.

This save/reopen test holds both features in one document, checks each
alone still needs 4, that documents with neither keep 3 (EPS) or 2, and that
a parent-spread all-on choice needs 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:51:37 +01:00
andeecollard 57658368af PDF: validate layer overrides and query mixed selections 2026-10-24 13:23:02 +01:00
andeecollard 8d295b101e PDF: distinguish all-on layer choices from file defaults 2026-10-24 13:23:02 +01:00
Andee CollardandClaude Opus 5.5 2633fe8b5d Format: choose the native version in one place; share v4 with #1671
skylartaylor's review: #1647 and #1671 each introduced native format 4 for a
different capability, so a reader that understood only one could accept a
file carrying the other and silently drop its settings. No release has shipped
v4 (main and v0.12.0 still write at most 3), so v4 is defined as one
capability covering both retained placed-graphic layer options and explicit
all-on PDF layer choices; #1671 is stacked on this branch.

Move the version choice into required_version so every new capability is
decided in one place, document the shared v4 contract on VERSION, and test
that plain, EPS-only and layer-option documents keep 2, 3 and 4 respectively.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:22:08 +01:00
andeecollard b7e36bf616 M6: retain layer order when native parents reopen closed subtrees 2026-10-24 13:22:08 +01:00
andeecollard 3d362d0bdf M6: preserve nested graphic layers and retain export diagnostics 2026-10-24 13:22:08 +01:00
andeecollard 7074dc8a85 M6: preserve per-placement graphic layer options 2026-10-24 13:22:08 +01:00
Dylan M. TaylorandClaude Sonnet 5.5 c313c53497 refactor: split complex functions in ruby, warichu, pdf text, render text, epub, pdfx (Sonar S3776) (#1728)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:51:58 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 4c5ea73d98 refactor(tools): fewer parameters and simpler pointer handling (Sonar S107, S3776) (#1725)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:51:35 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 75d5b015d3 refactor(idml): extract helpers to cut cognitive complexity (Sonar S3776) (#1723)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:51:31 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 cb763c2583 refactor: split complex functions in psd, table, parabox, index, trace, pdf export, render (Sonar S3776) (#1724)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:51:26 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 8271f1a26b refactor(engine): split execute_unguarded, load_styles and resize_border (Sonar S3776) (#1726)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:50:14 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 c142678bd5 refactor(ui-egui): extract character style General section (Sonar S3776) (#1720)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:49:00 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 e0c244d2ed refactor(ui-egui): extract style option field helpers (Sonar S3776) (#1719)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:48:56 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 e651c637f4 refactor(ui): extract helpers from conditions, book, credits and page control panels (Sonar S3776) (#1721)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:45:48 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 8299d26400 chore: replace trivial closures with method paths (Sonar S1612) (#1714)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:30:43 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 bfd95b258b chore: drop redundant 'static lifetimes in statics and consts (Sonar S8863) (#1713)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:30:39 -04:00
Dylan M. TaylorandDylan Taylor f90d286721 chore: resolve SonarCloud maintainability issues (#1698)
* chore: resolve SonarCloud maintainability issues

- Replace lambda closures with method references (S1612)
- Replace wildcard imports with explicit imports (S2208)
- Refactor complex functions with extracted helpers (S3776)
- Replace OR pattern with range pattern in math parser (S9047)

* style: apply rustfmt to warichu helper

* fix(compose): revert slice conversion in tests and remove unused var in warichu

* Group warichu row layout scalars to satisfy S107 parameter limit

* style: satisfy rustfmt in warichu.rs

---------

Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
2026-10-24 03:54:24 -04:00
skylar taylor-barrick 5449bc4757 M6: preserve PDF catalogs and safely apply layer choices (#1670)
Preserve existing PDF catalog entries and full object generations. Accept literal null trailer entries while failing closed on encrypted/hybrid/ambiguous or unreadable history. Validate visibility variants atomically before document edits, suppress stale unsupported canvas overrides, and preserve conservative content cropping without overcropping empty optional-content stubs.

Local full CI: all 9 gates passed, 3063 tests passed and 6 skipped, all 16 WASM-safe crates checked. Independent qpdf/preservation/Poppler checks passed for17 supported inputs;6 refusal cases stayed refused. All11 additional Prev controls passed. GitHub CI and CodeRabbit passed on00d5fa5c; CodeRabbit confirmed the Prev finding addressed. Author history preserved; no native format changes.
2026-10-24 00:51:57 -06:00
skylar taylor-barrick 00d5fa5cdd M6: reject unreadable PDF trailer history links (#1670)
Reject a non-null Prev entry that cannot be read as an offset instead of silently treating it as the end of the guarded trailer chain. Keep absent/null end markers and readable numeric offsets unchanged.

Reproduced CodeRabbit discussion_r4366245854 with an independent probe and a failing native regression before the fix. The synthetic regression covers seven unreadable value types plus absent/null and integer/real history controls.

Validation: all 9 cargo xtask ci gates passed (3063 tests passed, 6 skipped; 16 WASM-safe crates). One unrelated GPU test was labelled leaky by nextest in that run and passed cleanly in an isolated rerun. Independent checks: 17 original supported PDF variants still pass qpdf, logical preservation and Poppler pixels; 6 original refusal cases remain refused. All 11 additional Prev controls pass (7 refused, 4 accepted).
2026-10-24 00:40:33 -06:00
skylar taylor-barrick 7427a15863 M6: harden placed PDF layer variants (#1670)
Integrate current main (d8d78851) without rewriting the contributor's commits, retaining craft-libs 9f75d3dc.

Accept literal null trailer entries while rejecting actual or ambiguous encryption/hybrid markers. Structurally inspect bounded xref/trailer history instead of adopting trailer-looking comments. Preflight all selected source variants before editing/undo; preserve reset-to-defaults. Suppress stale unrewritable canvas overrides rather than revealing source content. Keep conservative all-content crop fallback without overcropping layerless/null stubs.

Validation: cargo xtask ci, all 9 gates passed; 3062 tests passed, 6 skipped; all 16 WASM-safe crates checked. 17 supported variants passed independent qpdf, logical preservation and Poppler pixel checks; 6 unsupported/repair-only cases refused. Direct-harness Claude Opus 5 reviewed the exact main-relative delta with no blocking findings.

No native-format changes or unrelated layer features. Synthetic regression fixtures are generated in test code.
2026-10-24 00:18:22 -06:00
aiongg d8d7885172 Anchored objects: Relative to Spine mirrors custom positions on right-hand pages (#1702)
* Anchored objects: Relative to Spine mirrors custom positions on right-hand pages

* Anchored objects: page side from the frame's spread position; footnote cache keyed by page side
2026-10-24 01:34:05 -04:00
aiongg 4823b59492 PDF: shared reader from craft-libs 9f75d3dc (input bounds and crash fixes) (#1701)
* PDF: craft-pdf, krilla and hayro from craft-libs main (input bounds and crash fixes)

* PDF: craft-libs 9f75d3dc, with hayro-cmap from its vendored copy
2026-10-23 23:03:36 -04:00
Dylan M. Taylor 203529ab36 ci: move release workflow write permission to job level (SonarCloud S8233) (#1697) 2026-10-23 22:03:59 -04:00
aiongg 3b71900097 Links: resolve stored paths with craft-docpath's resolve_absolute (#1399)
* Links: use resolve_absolute for stored paths

* Links: check for a missing linked file with is_ok_and

* CI: release only with git dependencies from storytold

The winit patch from skylartaylor/winit at its pinned rev is the one other source allowed.

* Links: Relink to Folder only uses a name that stays a file name in the folder

* CI: the git-sources check reads Cargo.lock as TOML, needs it current and refuses config patches

* CI: the git-sources check parses .cargo/config and .cargo/config.toml for source replacement, patches and paths

* Links: rustfmt

* Links: Relink to Folder only takes a file directly in the chosen folder

* Links: Relink to Folder compares folders as the file system resolves them
2026-10-23 21:19:50 -04:00
Davit MatchakhelidzeandClaude Opus 5.5 80d13911b2 fonts: Georgian UI text from craft-fonts' Noto Sans Georgian (#1270)
* fonts: Georgian UI text from craft-fonts' Noto Sans Georgian

font_definitions registers the Geor face and appends it to every family, like
Arabic (and to the Arabic families after the CJK faces); the wasm filter in
crates/fonts/build.rs keeps the face. The installed-font probe for Geor stays
skipped whenever craft-fonts covers the script. Bump craft-fonts-ref to a71c20e
(storytold/craft-fonts#27).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF

* Release: build the web version with craft-fonts too (web-craft-fonts)

The shared release workflow builds the web release without CRAFT_FONTS_DIR unless web-craft-fonts
is set, so the web version would still have no Georgian face (CodeRabbit on vectorcraft#2934).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF

* test: the Arabic New Document test scrolls to Height like the other fields

With craft-fonts' Noto Sans Arabic (from a71c20e3) the rows above Height are taller, so at
392x271 the field starts partly below the dialog body's clip and the test's unscrolled
visible_label check failed (FreeBSD jobs). It stays reachable: scroll to it as the test
already does for Gutter and the margins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF

* CI: same craft-fonts pin as release (a71c20e3), so the gate checks the Georgian face

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 19:47:45 -04:00
Brandon Thomas 348a8a4dc9 Merge pull request #1235 from KnottyDyes/squad/pdfx-unembedded-fonts
PDF: report visible unembedded fonts in PDF/X-4
2026-10-23 17:30:30 -04:00
Brandon Thomas 058b369b53 Merge storytold/main into squad/pdfx-unembedded-fonts
# Conflicts:
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-23 17:30:20 -04:00
Brandon Thomas 79c4ed5d3a Merge pull request #1308 from Silvertree2010/fix/h553-ase-export-corrupts-the-file-whe
Truncate ASE swatch names that overflow the u16 length field
2026-10-23 17:30:14 -04:00
Brandon Thomas 8ce126407e Merge pull request #1310 from Silvertree2010/fix/h572-docx-import-stores-out-of-range
Drop out-of-range font sizes on DOCX import
2026-10-23 17:30:10 -04:00
Brandon Thomas a77660b9fa Merge pull request #1319 from Silvertree2010/fix/h679-docx-xlsx-xml-parser-silently-dr
Keep CDATA text in the DOCX/XLSX XML parser
2026-10-23 17:30:07 -04:00
Brandon Thomas ce7d993f52 Merge pull request #1442 from HEOJUNFO/fix/grey-tiff-device-gray
Export placed greyscale TIFFs as DeviceGray
2026-10-23 17:30:03 -04:00
Brandon Thomas ae550aa670 Merge pull request #1470 from nikolainyegaard/language-picker-order
Preferences: list the languages alphabetically by their own name
2026-10-23 17:29:59 -04:00
Brandon Thomas 807d9b5723 Merge pull request #1491 from Hamza0101/fix/underline-under-tabs
An underline runs across a tab, as the rest of the line's text (#1466)
2026-10-23 17:29:54 -04:00
Brandon Thomas f682c80d7b Merge pull request #1547 from Silvertree2010/fix/h1246-idml-round-trip-renames-styles-w
Keep a literal ':' in style names through an IDML round trip
2026-10-23 17:29:50 -04:00
Brandon Thomas d45a7baf4c Merge storytold/main into fix/h1246-idml-round-trip-renames-styles-w
# Conflicts:
#	crates/idml/src/tests.rs
2026-10-23 17:29:40 -04:00
Brandon Thomas aaa18ad1c2 Merge pull request #1550 from Silvertree2010/fix/h1233-text-frame-column-count-is-trunc
Clamp text frame column count before narrowing to u32
2026-10-23 17:29:35 -04:00
Brandon Thomas 0d156f32b6 Merge pull request #1560 from Hamza0101/feat/cell-rotation-reported
Rotated cell text is settable and reported, not silently flattened (#1468)
2026-10-23 17:29:32 -04:00
Brandon Thomas 8eb4f5590a Merge storytold/main into feat/cell-rotation-reported
# Conflicts:
#	crates/idml/src/tests.rs
2026-10-23 17:29:22 -04:00
Brandon Thomas b212bdcd8f Merge pull request #1561 from Hamza0101/fix/rtl-first-line-indent
A right-to-left paragraph's first-line indent is at its right edge (#1448)
2026-10-23 17:29:17 -04:00
Brandon Thomas 98f957ed6b Merge storytold/main into fix/rtl-first-line-indent
# Conflicts:
#	crates/compose/src/tests.rs
2026-10-23 17:29:07 -04:00
Brandon Thomas 17d197dbef Merge pull request #1567 from Hamza0101/fix/insert-pages-count
A page count Insert Pages cannot mean is refused
2026-10-23 17:29:02 -04:00
Brandon Thomas 44ddf8e857 Merge pull request #1553 from PiMinusMax/gradient-drag-to-swatches
Gradient panel: drag the gradient onto the Swatches panel to keep it
2026-10-23 17:28:58 -04:00
Brandon Thomas 3e783b2671 Merge pull request #1562 from Hamza0101/fix/duplicate-page-in-export-list
A page named twice in an export list is exported once
2026-10-23 17:28:54 -04:00
Brandon Thomas 515796aa1c Merge pull request #1571 from Hamza0101/fix/unique-anchor-name
A text anchor's name is the document's, so it is not reused
2026-10-23 17:28:50 -04:00
Brandon Thomas fc2e42738c Merge pull request #1397 from Silvertree2010/fix/h951-tagged-text-export-strips-from-s
Keep ':', '<', '>' and '\' in Tagged Text style names
2026-10-23 17:28:47 -04:00
Brandon Thomas 132a0816e1 Merge pull request #1376 from Silvertree2010/fix/h869-table-alternating-fill-counts-ar
Saturate table alternating-fill and index paragraph counts
2026-10-23 17:28:43 -04:00
Brandon Thomas 4144b7414d Merge pull request #1378 from Silvertree2010/fix/1337-bug-unable-to-insert-a-multi-pag
Refuse PDF page ranges in the Place PDF dialog instead of using page 1
2026-10-23 17:28:39 -04:00
Brandon Thomas e3ac9936a6 Merge pull request #1371 from Hamza0101/fix/backend-log-says-what-happened
Graphics: the start-up log says which backend was chosen and how to change it
2026-10-23 17:28:35 -04:00