Commit Graph
4017 Commits
Author SHA1 Message Date
NetterSilverandClaude Haiku 5.5 2289b5755d Ignore a negative trailer /Size in incremental saves (#5566)
Found while testing crates/cos/src/writer.rs:248

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-01 15:04:36 -05:00
NetterSilverandClaude Haiku 5.5 fdaa502f27 Reject signed and empty arcs in try_oid (#5581)
Found while testing crates/sign/src/der.rs:467-472 (try_oid)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-01 15:04:32 -05:00
FredApps 2cd50b8d39 Merge pull request #5491 from Piohrun/fix/jbig2-retained-bitmaps
fix(render): a JBIG2 page's segments are bounded in what they hold and refer to (hayro-jbig2 patches 5 to 9, hayro-syntax 29)
2026-11-01 21:04:29 +01:00
Grzegorz MartensandClaude Opus 5.5 b57ddb0a22 Merge upstream/main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-01 20:10:05 +01:00
aiongg 41652972ac Merge pull request #5539 from Piohrun/fix/indexed-lookup-by-reference
M2: a reference in a colour space or array isn't lost: Indexed tables, Pattern spaces, /Decode, /W and functions
2026-11-01 13:59:05 -05:00
Brandon ThomasandClaude Opus 5.5 7d78f3e144 Release 0.17.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.17.0
2026-11-01 13:58:27 -05:00
VoiceLessQ 424ca0e972 M14: Preferences sets how many recent files to keep (#5572) (#5675)
The list was fixed at 12. Preferences ▸ Documents and view now takes a
number from 0 to 50, with 12 as the default. At 0 Home has no Recent
section and File ▸ Open Recent is disabled.

The list is cut when Preferences closes, so the number can pass through
0 on its way to another. Until then Home and saved settings already
leave out what is past it. A settings file can't ask for more than 50.

The control channel and launch options take it as recent-files. The two
new strings go in every catalog as English copies.
2026-11-01 13:52:47 -05:00
aiongg 4238670dd5 Merge remote-tracking branch 'o/main' into fix-5539
# Conflicts:
#	crates/create/src/tests.rs
2026-11-01 18:48:28 +00:00
aiongg 6818995a3c Merge pull request #5673 from Piohrun/fix/jbig2-region-location
fix(render): JBIG2 arithmetic near the end of an i32 doesn't panic (hayro-jbig2 patch 12)
2026-11-01 13:45:39 -05:00
FredApps 67e86f2b27 Merge pull request #5620 from Piohrun/fix/mask-resample-allocation
fix(create,optimize): a mask of other proportions doesn't take the process down
2026-11-01 19:44:58 +01:00
FredApps b3023b4b28 Merge pull request #5624 from Piohrun/feat/xfa-rotate
M12: an XFA draw placed by position turns about its anchor
2026-11-01 19:43:57 +01:00
FredApps 61140ed807 Merge pull request #2155 from Combiler01/main
feat: Acrobat UI parity for image editing, text formatting, and UI stabilization and Bug Fixes
2026-11-01 18:50:01 +01:00
Grzegorz MartensandClaude Opus 5.5 10107d943a M2: JBIG2 arithmetic near the end of an i32 doesn't overflow
A region's location, a refinement's offset, a symbol's corner, a Huffman
range line and a decoded integer of 2^31 could each overflow: a panic
wherever overflow is checked. The last four wrap, as a release build did.
Bitmap::combine saturates, which comes to the same: a side is at most
65,535, so a location that overflows is past the end of any page. What is
drawn doesn't change. Patch (12), after the numbers #5491 and #5569 take.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-01 18:32:33 +01:00
Dylan M. Taylor 7ca642980a docs: sync Craft App Suite list with ArtCraft Launcher 2026-11-01 12:29:59 -05:00
FredAppsandCodex GPT-6.1 a9de3db628 docs: record image editing review fixes and movement semantics
Validated with 3231 passing scoped tests (10 skipped), clippy, wasm checks, repository gates, and 42 CLI smoke steps including saved-document verification.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:59:35 +01:00
FredAppsandCodex GPT-6.1 6816d14e02 Fix context image placement and canvas selection ownership
Convert context-paste user coordinates into AddImage display coordinates and
identify the inserted image through its new owning stream and XObject. Keep
legacy added-image metadata aligned with the active image controller, route
Delete to the visible selection, and clear hidden image selections when leaving
the controller while preserving text selections and drafts.

Separate selection-dependent Copy from whole-page Snapshot and document Export
permissions. Add synthetic UI regressions covering transformed page placement,
identity collisions, shared image references, saved deletion results, tool
transitions, and permission controls.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:54:15 +01:00
FredAppsandCodex GPT-6.1 75e012de9a fix(edit): compose inside-scope group translations in order
Fold a leading transform inside the image scope as cm followed by the local transform; an enclosing transform uses the opposite multiplication order. This preserves the complete requested image and crop displacement under an outer scale. The exact crop-arrange-group-move fixture previously moved only five points for a ten-point request; saved geometry and rasters now match an independent direct Transform control across both axes and signed offsets. Full scoped Linux native, wasm and repository gates pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:41:13 +01:00
FredAppsandCodex GPT-6.1 e677c009b3 fix(edit): restore inherited text state when arranging Forms
Track the text-state operators with saved drawing state, restoring inherited spacing, scaling, leading, rendering mode, rise and known font before relocated Form artwork. Emit restoration inside BT/ET, and leave a font selected by a replayed ExtGState authoritative over an older direct Tf. The exact inherited 12 Tc fixture failed its saved-PDF raster comparison before this fix; zero-spacing and destination-state controls now preserve rendering. Scoped Linux native, wasm, clippy and formatting checks pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:41:13 +01:00
FredAppsandCodex GPT-6.1 8669aa48aa fix(edit): preserve graphics state chronology and mask identity
Replay repeated ExtGState names in last-application order. Compare each complete soft-mask value and its establishment matrix instead of only its group reference, and retain cached shared definitions across saved states. Saved-PDF raster regressions cover Alpha versus Luminosity over the same group, repeated aliases at different matrices, and ordinary sequence/single-mask controls. Definition checks also cover backdrop and transfer parameters. Actual baseline and reverted-comparator tests fail; scoped Linux native, wasm, clippy and formatting checks pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:41:12 +01:00
FredAppsandCodex GPT-6.1 fdb6a6f33e fix(ui): rotate cropped image previews around the committed pivot
Project the visible user-space bounds centre for the drag preview, matching the RotateBy engine operation. The full image centre differs for cropped artwork and caused the preview to jump on release.

The regression compares actual painted preview corners with saved/reopened image corners and verifies a requested 90-degree turn on cropped and uncropped controls, including page rotation. Linux scoped clippy, 106 tests, wasm, formatting, layering and assets pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:34:13 +01:00
FredAppsandCodex GPT-6.1 c0a5a5cbf8 fix(ui): resize image frames relative to the captured press
Invert the actual affine basis instead of projecting onto assumed orthogonal axes. Capture the displayed crop frame for handles and apply its relative transform to the full artwork, preserving author clips on rotated pages. Exact out-and-back gestures preserve bytes and undo state, including off-centre presses.

Synthetic headless regressions verify sheared and rotated images, crop-frame anchors, press-offset independence and saved/reopened placement. Degenerate and nonfinite bases are refused; the inverse guard has a negative-control test.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:34:13 +01:00
FredAppsandCodex GPT-6.1 393bd30701 fix(ui): leave source text untouched when script conversion is a no-op
Only request a script conversion from the panel; the caller decides whether conversion changed the text. Do not create a paragraph rewrite merely because the button was clicked. A hidden QQQ fixture checks both script buttons preserve document bytes, undo history and saved rendering, while supported conversions remain covered. Actual reverted-fix raster failure and scoped Linux native, wasm, clippy and repository checks passed.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:19:21 +01:00
Grzegorz MartensandClaude Opus 5.5 89fed9a9e6 M2: the chain tests want std, like the module's other thread tests
They use std::thread and std::sync::mpsc, so they take the same gate, and
so does the helper only they use. The crate's test build doesn't compile
without std on main either, for reasons of its own; these add nothing to
that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-01 17:17:59 +01:00
FredAppsandCodex GPT-6.1 2ab9c6992c docs(edit): record latest PR 2155 review fixes
Record delivered clipboard events, the mixed-size display correction, and explicit mixed-script normalization with Undo. Combined scoped Linux validation passed: 2785 tests, clippy, doctest checks, wasm, formatting, layers, assets, parity, and a 26-step CLI smoke test.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 16:38:24 +01:00
FredAppsandCodex GPT-6.1 27e34098d3 fix(ui): size the font field for the localized mixed label
Measure Mixed with the active body font and include the input margins and caret allowance. Keep that minimum stable while typing so the full label is visible without shifting the row on each keystroke.

A themed panel regression fails against the old 40-pixel input, verifies the text fits inside the field margins and keeps the alignment control inside a 272-pixel pane. Linux scoped clippy, format tests, wasm, formatting, layering and assets pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 16:34:38 +01:00
FredAppsandCodex GPT-6.1 a3840e1eda fix(ui): paste delivered images instead of guessing from key releases
The pinned integration consumes native clipboard shortcut keys and delivers PasteImage pixels. Handle those payloads in order, keep text cache invalidation, and use the delivered image even if the OS clipboard changes before processing. Preserve alpha and validate dimensions and byte counts before allocation.

Remove release timestamps so Windows clipboard history cannot reuse a completed paste gesture. Keep explicit shortcut fallback for control-channel and browser internal-image paste, with modal, focus and permission guards unchanged. Tests cover both release orderings, history after prior paste, mixed batches and duplicate prevention.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 16:30:06 +01:00
FredAppsandCodex GPT-6.1 b7d04009a2 fix(ui): refresh font-size text when selection becomes mixed
Include the mixed-size flag in the font-size draft cache key. Selecting a mixed block can preserve the previous representative number, so a value-only key left the field showing 24 instead of Mixed. Unchanged formatting still preserves partially typed input across frames.

The headless regression covers uniform-to-mixed and mixed-to-uniform transitions with the same number, draft preservation and a single committed edit. Linux scoped clippy, tests, wasm, formatting, layering and assets pass; reverting the cache fix reproduces the stale display.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 16:18:26 +01:00
FredAppsandCodex GPT-6.1 e7762568cc docs(text): define mixed-script normalization and undo policy
Document the existing policy: mixed plain and target-script text normalizes to that script, then to plain text, rather than reconstructing the original mixture. Undo restores exact prior text. Cover both scripts in engine and headless tool tests, including document-byte restoration, redo and save/reopen, and record the evidence in parity. The new tests pass against unchanged conversion logic; this is policy documentation and coverage, not a product behavior fix. Scoped Linux native, wasm, clippy, formatting, layers, assets and parity validation passed.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 16:12:39 +01:00
Grzegorz MartensandClaude Opus 5.5 4303d49eea M2: a reference to a reference is what it names
`IndirectObject<f32>` read an object holding `6 0 R` as the number 6, so `/Decode [11 0 R 0]`, with
11 naming 6 and 6 holding 1, read as 6, and `/W` gave glyphs such widths. As anything but a number,
such an object was lost.

`XRef::get_with` is how every reference is read, to an object stored on its own or in an object
stream, so it now follows such objects in a loop, up to 32 references as `Document::resolve` does in
#5548. A loop takes no stack however long the chain, and a cycle runs out of references and reads as
a missing object, as a reference to nothing does: the image with such a `/Decode` isn't drawn, as
with `/Decode [99 0 R 0]`.

An object stream isn't reached that way: it has to be a stream stored as that object, and following
a reference to one stored inside another let a 1 KB file run out of stack. `XRef::objects` leaves
such objects out, or a page came out once more for each one holding a reference to it, and a comment
inside a reference counts as white space, as it does everywhere else.

Reading an object stream's index now counts against the 64 nested loads, and reads its dictionary
alone. That is older than this branch, which only made it slightly worse: a chain of object streams,
each with a member of the next for its `/N`, `/First` or `/Length`, recursed with no limit, holding a
copy of the chain at each, and aborted on 750 KB with an 8 MiB stack, or 250 KB with 2 MiB, in a test
build. Parsing the stream read `/Length` as well as `/N`, two ways to the next stream's index, and a
failed index isn't remembered, so the work doubled at each stream: 20 streams in a ring took 20 s on
`main`. ISO 32000-2 7.5.7 keeps an object stream's `/Length` out of object streams, so no legal file
has a `/Length` chain. Nothing forbids `/N` or `/First` by reference, though no writer I know of makes
such a chain. Past the limit it reads as missing unless a stream within 64 of it has been read.

`/W` and `/W2` with their list by reference are tested too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-01 15:28:31 +01:00
FredAppsandCodex GPT-6.1 73655948c6 fix(automation): flip images along displayed page axes
Map horizontal and vertical tool actions to PDF user-space axes after accounting for page rotation. The tool description states the displayed-coordinate semantics. A four-quadrant raster and transformed-corner regression covers both actions at 0, 90, 180 and 270 degrees, with undo between actions; it fails on the wrong axes before this fix. Scoped automation clippy, all 354 tests, wasm, formatting, layers and assets pass on GGEO-AI02.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 15:05:32 +01:00
FredAppsandCodex GPT-6.1 0b0d39c661 docs(edit): record PR 2155 review follow-ups
Record image crop and stream ownership, visible orientation, clipboard and formatting fixes, Home controls, and reloadable font discovery as PR candidates. Estimates remain unchanged.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 15:01:00 +01:00
FredAppsandCodex GPT-6.1 0595d4d397 fix(ui): preserve author clips and route crop controls before page content
Offer Remove Crop only for editor-owned clips, reset draft cropping to the author-visible bounds, and remove only an owned crop when confirming the full image. Active crop mode owns presses on its page so underlying text and marquee selection cannot steal crop controls. Label the painted controls for accessibility and automation.

The author-clip regression opens the real menu, resets a draft crop and confirms it while preserving the authored clip. It failed before ownership checks and again before the router fix.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:58:21 +01:00
FredAppsandCodex GPT-6.1 d423dd03ec fix(ui): keep image grips and flips aligned with the visible page
Use matrix resizing whenever image axes are turned or reflected on screen, including document and view rotation. Share the visible grip geometry for cursor claims and hit routing, and use only the drawn rotate knob. Map flip labels to the visible axis and defer Cut selection clearing to its result.

Regressions cover all page/view rotation combinations and 64 outward drags across every grip, asserting fixed anchors and pointer tracking for upright and rotated images.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:58:21 +01:00
FredAppsandCodex GPT-6.1 0046177f47 fix(engine): validate image transforms and promote arbitrary added-image transforms
Reject finite but singular or overflowing determinants at the engine boundary. Promote added images for arbitrary transforms, as RotateBy already does, while preserving editable quarter turns and reflections. Regressions verify transformed placement, promotion, undo and refusal without mutation.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:58:20 +01:00
FredAppsandCodex GPT-6.1 aa68d0c27f fix(home): show pinned tools once and expose unpin controls
Omit pinned tools from Recommended and keep unpin buttons in the accessibility tree without requiring pointer hover.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:51:28 +01:00
FredAppsandCodex GPT-6.1 faf85f5af9 fix(text): apply explicit sizes and preserve script characters
An explicit size commit normalizes mixed-size selections even when the value matches the displayed size. Caret-only script commands format the whole draft. Mathematical minus uses reversible Unicode forms and ASCII hyphen-minus remains unchanged. Correct the applied-selection comment and document the character policy in parity and the tool.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:51:27 +01:00
FredAppsandCodex GPT-6.1 a310d5a41a fix(ui): respect clipboard authority and retain refused cut selections
Do not reuse stale native images for unsupported clipboard contents, while preserving web internal image paste. Observe text paste before focus gating and keep image-less key releases silent. Tie release fallback to V gestures. Check modification permission before copying and clear selection only after successful deletion.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:51:27 +01:00
FredAppsandCodex GPT-6.1 36a6a572b8 fix(engine): match added images by their owning stream
An original image and an added item may share an XObject without sharing editable metadata. Require the selected drawing stream to own the added item instead of falling back to any matching resource. The regression actually moved the added sibling before the fix; scoped native and wasm gates now pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:47:46 +01:00
FredAppsandCodex GPT-6.1 9a1334e04d fix(edit): preserve image scopes and content ownership
Move editor crop scopes with grouped images while retaining fixed author clips and folding repeated transforms. Arrange keeps relocated original artwork in its own stream beside an added item, so later edits or deletion cannot discard it; unusual shared owned streams are refused. Refuse nested marked-content extraction when its tags cannot be preserved. Synthetic regressions and the headless group-move, undo/redo, save/reopen, arrange, delete and render lifecycle fail before these fixes and pass afterward.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:47:46 +01:00
FredAppsandCodex GPT-6.1 3a0ea63c33 fix(edit): share saved drawing operands across graphics scopes
Keep dash, color and extended printing operand payloads shared across q snapshots. Copy-on-write color updates preserve saved values without multiplying large operand arrays by nesting depth. A pointer-sharing regression failed before the change; scoped native tests, clippy and wasm check pass on GGEO-AI02.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:47:46 +01:00
FredAppsandCodex GPT-6.1 43ad4bf418 feat(edit): expose image crop ownership to frontends
Report active PdfCraft crop markers through PageImage::has_editor_crop and page_images.has_editor_crop so frontends can distinguish removable editor crops from author clipping paths.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:47:46 +01:00
FredAppsandCodex GPT-6.1 6e4d9a6838 fix(fonts): rescan installed fonts and preserve accepted results
Resolve explicitly configured font roots while skipping descendant links; retain all accepted fonts within the existing bounded scan. Allow an explicit Reload without duplicate workers or an app restart. Three actual reverted-fix regressions fail; scoped engine/UI clippy, 2400 tests, wasm, formatting, layers and assets pass on AI02.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:34:36 +01:00
Grzegorz MartensandClaude Opus 5.5 41bf288a23 M12: a turned draw past the edge of the page stays where it turned to
Nothing tested one that stands off the page: it isn't moved back or cut, as an upright one isn't.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-01 13:46:01 +01:00
FredAppsandCodex GPT-6.1 321f976f93 fix(ui): preserve crop scale at large screen offsets
Reconstruct moved edges from the fixed opposite anchor in f64 and round each coordinate once. This avoids cancellation introduced by adding a nearly full-width UV displacement to the old screen edge. The deterministic Linux CI case fails against the previous implementation and passes with the fix.

Check scale on both axes in screen space against a derived f32 coordinate-rounding bound, using the stored rectangle dimensions. Verify fixed edges for every handle and reject a deliberately stretched result. Both CI regression seeds and 10000 randomized cases pass; scoped UI clippy/tests, wasm, formatting, layering and assets are green on AI02.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 13:33:53 +01:00
FredAppsandCodex GPT-6.1 1184bd02cb docs(edit): record safe crop and arrange semantics
Describe editor-owned crop removal, preserve authored clipping paths, and link the scope/state regressions in parity evidence. Record the maintainer changes without changing readiness estimates.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 13:00:26 +01:00
FredAppsandCodex GPT-6.1 d4810fd00f refactor(ui): finish shared image selection and clipboard state cleanup
Use the common image-selection constructor across owners, remove obsolete crop and copied-coordinate fields, keep only a shortcut timestamp, and make the internal UI modules private. Combined GGEO-AI02 validation: 4198 tests passed, scoped clippy, doctests, fmt, layers, assets, parity and wasm; 25-step CLI save/reopen smoke and real-shell screenshot checked.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 13:00:26 +01:00
FredAppsandCodex GPT-6.1 bea79e1884 fix(i18n): translate clipboard and Home tool messages
Fill five notification/search entries in all catalogs and the missing Home tool labels in ckb, lo, nb and th. Correct Albanian crop labels and Italian/Kazakh unpin meanings. Catalog additions are AI-assisted and not separately native-reviewed.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:54:52 +01:00
FredAppsandCodex GPT-6.1 21a48ac735 fix(ui): finish font discovery when its worker panics
Contain discovery panics and publish the empty result so the font menu leaves its pending state. A synthetic panic regression fails when containment is removed.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:54:52 +01:00
FredAppsandCodex GPT-6.1 2c6a0fed48 fix(ui): honor current clipboard text and elapsed paste timing
Menu paste refuses cached images when system text supersedes them. Keyboard and menu paste share the text check; image validation reuses Create. Expire shortcut context by elapsed time even when frames are sparse. Regression tests fail with the old checks restored.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:54:52 +01:00
FredAppsandCodex GPT-6.1 f62c1cfafe refactor(text): share source font names and selection defaults
Reuse the existing subset-tag parser through the engine facade and share the fallback formatting state.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:54:52 +01:00