* M4: Document Properties has a Custom tab for custom properties
Document Properties has a new Custom tab between Fonts and Advanced. It
lists the document's custom properties, and Name and Value fields with
Add, Update and Delete edit the list. Clicking a listed property fills
the fields with it. OK writes the changes through SetInfo in the
existing "Change document properties" step, so one undo reverts them
with the other tabs' changes.
Add is off for an empty value, a name already listed, a name that
check_custom_key refuses (its message is the button's tooltip), and a
name the file already uses for an entry the list leaves out (not text,
only padding, or past the 256 listed). A property already in the file
under a refused name or a name that is not UTF-8 is listed, and Add,
Update and Delete stay off for it, so OK cannot fail on it or write a
different key.
Clearing an /Info entry now removes it when /Info is a dictionary
written directly in the trailer. set_info_entry returned without a
change there, so a delete in the Custom tab, a cleared Description field
and a doc_set_info clear left the entry in the file. It now writes a
copy without the entry as a new indirect /Info.
The engine re-exports check_custom_key and adds Document::has_info
(organize::has_info). set_option("dialog", "custom") opens the tab.
* Contributors: add dotCooCoo (Robert Lee)
* M4: Add in the Custom tab stops at the 256 properties the tab lists
Document Properties > Custom lists at most 256 properties, so a property
added past that was saved but left out of the list when the dialog opened
again. Add is now off once the tab's list or the file's own list holds 256;
a new name goes after the file's entries, so a file with more than 256 keeps
Add off after a Delete as well.
- render: DocInfo::open_dest resolves /OpenAction (an explicit destination,
a /GoTo action's /D, or a name or string through /Names /Dests or the
catalog /Dests) with the existing bounded dest() resolver.
- ui-egui: apply_initial_view goes there with DocView::go_to_dest, so the
/XYZ point lands at the window's top-left and /FitH top at its top edge.
With "Always use my default zoom and page layout", only the page.
- organize, ui-egui: /ViewerPreferences /NonFullScreenPageMode (Table 147)
is read for /PageMode /FullScreen documents and names the panel shown
behind the full-screen prompt; such a document no longer gets the outline
panel only because it has an outline.
- organize: set_initial_view keeps an opening action whose page and
magnification are unchanged, instead of dropping its position or deleting
a named go-to.
- automation: doc_info reports open_destination.
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A Line annotation without an appearance was drawn along /L with its
endings there, ignoring /LL, /LLE, /LLO, /Cap, /CP and /CO. With /LL,
/L gives the ends of the leader lines, not of the line itself.
- The line sits |LL| + LLO from /L, on the left of travel for a
positive /LL; leader lines run from LLO off /L to LLE past the line.
- /LE endings are drawn at the line itself.
- /Cap true draws /Contents (or the plain text of /RC) in black
Helvetica 10, turned with the line: Inline breaks the stroke around
it, Top sets it above, /CO shifts it (with a tick when moved off).
- PdfCraft measurements keep /PCMeasureValue as their caption.
- undrawable_text reports caption text the standard font can't draw.
- Non-finite, huge and negative values, and a zero-length /L, are
handled leniently; captions are cut to 256 characters.
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* M12: XFA check boxes sit where their margins, caption and alignment put them
* M12: a check box's automatic caption room and auto height follow the box as drawn
* M12: a caption reserve of zero sizes the caption to its content, as no reserve does
The cell pixmap was round(scale x step) pixels and repeated, but the cell
was drawn, and the paint transform mapped back, at the unrounded scale.
So the pixmap repeated a fraction of a pixel too far at every step (31 px
for a 30.56 px step at 110 dpi), and cells drifted further from their
place with every step from the pattern's origin.
Vendored hayro patch (25), `tiling_cell_pixels`: the cell is drawn at
round(scale x step) / step, so one step is exactly the pixmap's side, and
the paint transform uses that same scale. The side stays within 1 and the
existing 3000 px cap; a non-finite product keeps the scale and a bounded
side.
Tests: crates/render/tests/it/tiling_cell_placement.rs (fill, turned and
scaled matrix, stroke, all at 110 dpi far from the origin; the helper's
bounds).
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
ROADMAP.md: kept both progress lines.
crates/optimize/README.md: PR's decoder sentence plus the target-version section from main.
Cargo.lock: auto-merged.
Conflicts: ATTRIBUTION.toml: took main's side (hashes recomputed after the merges). crates/optimize/src/lib.rs, crates/automation/src/lib.rs, tools.rs: Settings and tool schema keep object_streams (#3227) and lzw_to_flate (#4181); doc_optimize description names both options. crates/optimize/tests/optimize.rs: both sides' imports and tests kept.
Conflicts: docs/roadmap.md: all status lines kept, M10 row from main, M11 row with #3227's two sentences. parity/acrobat-features.toml: save-with-object-streams entry from #3227 with its test paths under tests/it/.
crates/engine/src/lib.rs: union of the added:: re-exports (paste_place/paste_rect from #4230, CHAR_SPACING_LIMIT).
crates/ui-egui/src/content_ui.rs: editor keeps #4178's anchored width and horizontal_align and #4266's spacing layouter; spaced_job takes the alignment so the custom layouter keeps it.
crates/ui-egui/tests/it/content.rs: kept both tests.
Conflicts:
- crates/ui-egui/src/i18n/mod.rs: kept main's side (main dropped the per-language translation tests; the PR's drawing_scale_labels_are_translated_in_every_catalog is not carried over).
- parity/acrobat-features.toml: measure.distance evidence: kept main's paths (tests/it/), appended the PR's two new entries.
crates/js/src/lib.rs: module doc app/util list has execMenuItem and scand; install() doc comment from main.
crates/js/src/tests.rs, crates/engine/src/tests.rs: both sides' appended tests kept.
parity/acrobat-features.toml: js notes: execMenuItem wording plus scand wording.
ROADMAP.md, docs/roadmap.md: kept both sides' status and progress-log lines; did not restore the older M14 status line that the branch had already trimmed.
parity/acrobat-features.toml: form.xfa-dynamic evidence: both sides' entries; notes: PR's metrics sentence replaces 'metrics are approximate' on top of main's text (word-level merge).
Conflicts: ROADMAP.md, docs/roadmap.md: both sides' status, progress and change-log lines; M10 row has the soft-mask sentence added to ours, M11 row from the earlier merge.
crates/forms/src/tests.rs: append conflict, kept both tests.
parity/acrobat-features.toml: form.fill-text-field evidence is the union; notes keep HEAD's text plus the comb-cells sentence.
Conflicts: ROADMAP.md, docs/roadmap.md: both sides' status, progress and change-log lines; M10 row has both sentences. parity/acrobat-features.toml: export.docx evidence has both tests, notes has both statements.
Conflicts:
- parity/acrobat-features.toml: comment.note: kept main's icon notes text, added the NoRotate sentence and the PR's three evidence entries.
- vendor/README.md: kept main's rows; added the PR's hayro-interpret patch as (53) with its test (53).
crates/ui-egui/src/object_ui.rs: main removed the tests module's translation test; kept the PR's two
new delete tests and dropped the translation test.