Commit Graph
4058 Commits
Author SHA1 Message Date
Combiler01 5cf09552ab Merge Conflicts #4889 2026-10-27 11:04:20 +05:30
KenM76andClaude Opus 5.5 a7b07bfc56 fix(render): a stroke whose outline comes back with NaN is drawn, not dropped (#4907)
kurbo 0.13.1's stroker can give a cubic that is nearly a line (all control points within a
rounding error of its chord) a NaN join, and vello_common's `flatten::fill` drops any path
containing NaN, so the whole outline vanished. An Illustrator outline ending in
`73.763 -0.536 l 73.764 -0.536 73.764 -0.536 73.764 -0.536 c` did (#4907). kurbo tracks the
bug class in linebender/kurbo#617 and #519; #610 is unreleased.

Vendored vello_common patch (2): when the expanded stroke is not finite, `flatten::stroke`
strokes the path again with every quadratic or cubic whose control points lie within the
tolerance of its chord replaced by a line, one element out per element in. A finite outline
is unchanged, and a path with non-finite input is still dropped. `stroke` and
`StripGenerator::generate_stroked_path` take a `Clone` path; vello_cpu's callers pass
`&BezPath` and a copied slice iterator.

Tests: `flatten::tests::a_tiny_degenerate_cubic_does_not_drop_the_stroke` and the render
crate's `stroke_degenerate_cubic` pixel test fail with the fallback disabled;
`a_finite_outline_is_stroked_as_before` and `a_path_with_nan_is_still_dropped` are guards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-27 00:34:47 -04:00
KenM76andClaude Opus 5.5 3c6612a3f9 fix(forms-ui): measure auto-size text at no more than the screen-font bound
An auto-size single-line field's size follows its height, up to about 12,500 pt for a
14,400 pt field. The editor measured the line's width by laying it out at that size,
before `field_screen_font` clamps to `MAX_SCREEN_FONT`, and egui rasterizes every glyph it
lays out: one such measurement took 1.2 s in a debug build, on every frame. The width is
now measured at no more than `MAX_SCREEN_FONT` and scaled, which is exact up to the bound
and linear above it.

`tools::forms_ui::tests::a_line_is_never_laid_out_above_the_screen_font_bound` fails with
the bound removed (laid out at 12,522 pt).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-27 00:34:14 -04:00
Combiler01 2650cbc906 Merge branch 'upstream/main' into main with layout adaptation 2026-10-27 09:55:01 +05:30
KenM76andClaude Opus 5.5 dffe6dd703 fix(edit, a11y): Q inside a text object restores the text matrices, as the renderer does
Inside a text object q/Q save and restore Tm and Tlm too (ISO 32000-2
§9.4.1, as corrected by the PDF Association's erratum,
pdf-association/pdf-issues #368). The renderer's saved state already
holds both. The text-editing interpreter and the heading detector kept
them across Q: text after Q was listed (and, once edited, moved) where
the q ... Q block left the pen, and a word continued after Q was split
("Chap ter One"). Both saved stacks now hold the two matrices.

Tests: pdfcraft-edit and pdfcraft-a11y
tests::q_inside_a_text_object_restores_the_text_matrices. Reverting
the edit fix puts the first case at y = 600, not 700; restoring only Tm
puts the T* case at 586, not 686; reverting the a11y fix reads
"Chap ter One". Each fails its test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-26 23:24:24 -04:00
Cursor Agentandjonathanwxh-cell 14efab25da Merge upstream/main into prep/4596-merge-main
Keep the print module split and reapply the /Contents space join in
imposition::decoded_contents, matching the renderer and the organize pruner.

Co-authored-by: jonathanwxh-cell <jonathanwxh-cell@users.noreply.github.com>
2026-10-27 03:18:57 +00:00
Combiler01 85a4d35733 Review Fixes 2026-10-27 08:46:08 +05:30
KenM76andClaude Opus 5.5 cef9908343 Merge origin/main into fix/auto-size-follows-field-height
main deleted crates/engine/src/reexports.rs and moved its re-exports
into crates/engine/src/lib.rs; the comb_auto_text_size re-export this
branch added now sits in lib.rs. forms_ui.rs moved to
crates/ui-egui/src/tools/; the branch's hunks carried over unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-26 23:11:08 -04:00
songzhihui ba339b7141 M2: resolve CJK viewer PR conflicts after module splits 2026-10-27 11:01:49 +08:00
alehel 993d3f9227 Merge remote-tracking branch 'refs/remotes/origin/main' into fix/background-hidden-by-page-backdrop
# Conflicts:
#	crates/automation/src/lib.rs
#	crates/edit/src/lib.rs
#	crates/engine/src/reexports.rs
#	crates/engine/src/session.rs
#	crates/ui-egui/src/lib.rs
2026-10-27 02:49:24 +01:00
Cursor Agentandjonathanwxh-cell c580b55055 Merge upstream main into prep/4013-merge-main-2
Two content conflicts, both from main splitting the files this branch edits.

crates/cos/src/document.rs: main moved Document into document/*.rs.
Keep that split. A missing /ID is still pdfcraft_crypt::file_id of the
encryption seed (document/open.rs); generated_id is gone. The regression
lives in document/tests.rs.

crates/engine/src/edit.rs: main moved EditCtx and run_edit into
edit/run.rs. Keep that split. Protect still draws its seed and default
owner password from getrandom on EditCtx and fails closed
(EditError::Protection) when the CSPRNG errors or returns all zeros.

Co-authored-by: jonathanwxh-cell <jonathanwxh-cell@users.noreply.github.com>
2026-10-27 01:48:59 +00:00
HiteshandClaude Opus 5.5 64fba7d177 feat(edit): Esc in an open paragraph selects its box, so Delete removes it
In Edit text & images a click inside a paragraph opens it for typing, and selecting the whole
box meant aiming for its thin frame: a press a few pixels inside put the caret in the text
instead (#2203). Esc in the inline editor now leaves the text and selects the paragraph's box,
as Acrobat does, so Esc then Delete removes it, the arrow keys nudge it and its frame drags it.
Esc still discards an unapplied draft.

The editor asks `ObjectSelection` to select the paragraph, and the next `prepare`, which has the
document's inventory, selects it after its own Escape check, so the Esc that closed the editor
cannot clear the new selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 07:17:41 +05:30
aiongg 1dd2737b47 Merge pull request #4889 from aiongg/layout
refactor: shared module layout (craft-contrib#20)
2026-10-26 21:31:30 -04:00
Cursor Agentandjonathanwxh-cell b5b42a3318 Merge upstream main into prep/4013-merge-main
The only content conflict was crates/engine/src/lib.rs: main moved
EditCtx and run_edit into edit.rs, while this branch taught Protect
to draw keys and salts from getrandom and fail closed. Keep main's
module split and apply that CSPRNG behaviour on EditCtx in edit.rs.
The regression test imports EditCtx and run_edit from the edit module.

Co-authored-by: jonathanwxh-cell <jonathanwxh-cell@users.noreply.github.com>
2026-10-27 01:16:56 +00:00
songzhihui 43d2491f5e M2: preserve CJK viewer fallback across engine split 2026-10-27 09:00:39 +08:00
aiongg f022ef0671 style: cargo fmt on moved files 2026-10-27 00:34:32 +00:00
aiongg 323172e860 test(automation): end the file access scan at the test module, not at a cfg(test) use 2026-10-27 00:34:32 +00:00
aiongg d449f2ce63 docs: name the ui-egui files by their new directories 2026-10-27 00:34:32 +00:00
aiongg 064632e0e8 test(ui-egui): name the page modules by their new directories 2026-10-27 00:34:32 +00:00
aiongg 3dbea4e7a0 docs(parity): point evidence at the ui-egui files' new directories 2026-10-27 00:34:32 +00:00
aiongg cb94c8f047 refactor(ui-egui): move open_worker_tests.rs to platform/open_worker/tests.rs 2026-10-27 00:34:32 +00:00
aiongg 636656a9ea refactor(ui-egui): move tab_context.rs into menus/ 2026-10-27 00:34:32 +00:00
aiongg cd0fc37c8d refactor(ui-egui): move folders_ui.rs into home/ 2026-10-27 00:34:32 +00:00
aiongg 7b3d688754 test(ui-egui): rerun the fontconfig tests by their platform:: path 2026-10-27 00:34:32 +00:00
aiongg 80c4572cfa refactor(ui-egui): move system_fonts.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg ed09547ecf refactor(ui-egui): move window_state.rs into persist/ 2026-10-27 00:34:32 +00:00
aiongg d25378c336 refactor(ui-egui): move units.rs into persist/ 2026-10-27 00:34:32 +00:00
aiongg dc25a6e341 refactor(ui-egui): move recovery.rs into persist/ 2026-10-27 00:34:32 +00:00
aiongg 615232d0e5 refactor(ui-egui): move last_view.rs into persist/ 2026-10-27 00:34:32 +00:00
aiongg 5527f931c9 refactor(ui-egui): move last_session.rs into persist/ 2026-10-27 00:34:32 +00:00
aiongg 687f6f6187 refactor(ui-egui): move window_controls.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg 90a1880aee refactor(ui-egui): move updates.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg dc97e74e57 refactor(ui-egui): move ui_scale.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg 2b4f7694dc refactor(ui-egui): move portable.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg b37c3a934c refactor(ui-egui): move pickers.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg 16b49776de refactor(ui-egui): move open_worker.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg d3cfadd9e2 refactor(ui-egui): move motion.rs into platform/ 2026-10-27 00:34:32 +00:00
aiongg 6638646314 refactor(ui-egui): move macos_association.rs into platform/ 2026-10-27 00:34:23 +00:00
KenM76andClaude Opus 5.5 ad33ab626e fix(render): a non-isolated knockout group blends its elements with the page under it
A non-isolated knockout group starts from the backdrop under it (ISO 32000-2
§11.4.7, §11.4.8), but was drawn into a layer of its own starting transparent,
so a blend mode inside it had nothing to blend with: white with /BM /Difference
over magenta stayed white (#4886).

Entered plainly (full opacity, no soft mask, Normal, not itself a knockout
element), the group is now drawn once per blend mode its elements use. Each pass
is a knockout layer composited onto the backdrop in that mode; elements of other
modes clear what is under their shape instead of painting. The Normal pass finds
the other modes, so a group without blend modes takes one pass as before.

hayro-interpret patch 67 (Device::begin_knockout_pass / end_knockout_pass,
draw_knockout_passes), hayro patch 26 (the renderer side). Test:
pdfcraft-render it::knockout_backdrop, three cases failing with the fix
reverted, plus an isolated-group control.

Fixes #4886

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-26 20:18:32 -04:00
KenM76andClaude Opus 5.5 0457aa88f9 fix(redact): Q inside a text object restores the text matrices; revert the render change
Review on #4831 pointed out the PDF Association's erratum to ISO 32000-2
(pdf-association/pdf-issues #368): inside a text object, q/Q also save and
restore Tm and Tlm (§9.4.1, referenced from §8.4.2). Acrobat 26.2 agrees on
a synthetic PDF 2.0 page. The renderer on main already did this, so the
previous commit's hayro-interpret patch (67) was wrong: it is reverted here,
with its vendor/README row and the render tests.

The real disagreement was in the redactor's own interpreter, which kept Tm
and Tlm across Q. Find took its boxes from the renderer's text, the redactor
measured the glyphs elsewhere, and redact_apply refused on residue. Its
state stack now holds (Gs, Tm, Tlm) and Q restores all three.

Test: it::redact_text_after_q, end to end on %PDF-2.0 fixtures, three cases
(font change inside q/Q; q 100 0 Td Q; the same followed by T*). With the
redactor change reverted, each case fails on its own at redact_apply. With
only Tm restored, the T* case fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-26 19:51:58 -04:00
skylar taylor-barrick 9a9813bf7d Merge pull request #4880 from storytold/fix/nextest-0.9.150
ci: require nextest 0.9.150
2026-10-26 17:39:25 -06:00
KenM76andClaude Opus 5.5 0e559fca41 fix(ui-egui): the field editor sizes auto-size text as the page does
Review on #4862 found two mismatches between the on-page field editor and
the field's appearance:

- Comb fields: the editor sized them as single-line text (20.87 pt for a
  500 x 30 comb) while the appearance uses 4-12 pt from the cell height.
  The comb test is now `Field::is_comb` and the comb size
  `appearance::comb_auto_text_size`, both shared by the appearance and
  `forms_ui::field_text_size`. The editor's test was looser (it ignored
  Multiline and Password); it now matches the page's.
- Tall fields: `field_text_size` capped at 300 pt and the three call sites
  clamped the screen font to 64. Both are gone; `field_screen_font` scales
  by zoom and bounds the result at MAX_SCREEN_FONT (256 screen points) so a
  glyph stays well inside the font atlas.

A non-finite comb height now gives 4 pt, as single-line auto-size does.

Test: it::forms::the_field_editor_sizes_auto_size_text_as_the_page_does.
With the comb change reverted the comb assertion fails (20.87 vs 12); with
the 300/64 caps restored the 100 pt assertion fails.

Also fixes it::forms::dragging_over_another_fields_text_focuses_it_and_selects_from_the_press,
which the previous commit broke: the name field now auto-sizes to 13.9 pt
instead of 12, so the press point 30 px in fell on "A|da"; it is now 38 px
in, inside "Ad|a" as the test intends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
2026-10-26 19:27:44 -04:00
aiongg d15c5a2e21 refactor(ui-egui): move file_watch.rs into platform/ 2026-10-26 22:46:12 +00:00
aiongg 3e7cc6e5cb refactor(ui-egui): move drag_pointer.rs into platform/ 2026-10-26 22:46:12 +00:00
aiongg 73cd1b16db refactor(ui-egui): move icons.rs into widgets/ 2026-10-26 22:46:12 +00:00
aiongg 228a91c19a refactor(ui-egui): move icon_data.rs into widgets/ 2026-10-26 22:46:12 +00:00
aiongg 963b25f59b refactor(ui-egui): move side_panels.rs into panels/ 2026-10-26 22:46:12 +00:00
aiongg 9c27b333f5 refactor(ui-egui): move search_ui.rs into panels/ 2026-10-26 22:46:12 +00:00
aiongg dc6b6a5c4e refactor(ui-egui): move page_selection_ui.rs into panels/ 2026-10-26 22:46:12 +00:00
aiongg 946767d22d refactor(ui-egui): move organize_panel.rs into panels/ 2026-10-26 22:46:12 +00:00