ROADMAP.md, docs/roadmap.md: union of both sides' lines, each once.
parity/acrobat-features.toml: the XFA entry has both sides' evidence and notes (#2604 page areas, #2813 CLI layout).
Fixes#1645. For a dynamic XFA form, `info` reported the placeholder
page and field counts, and `text` and `render` read the placeholder
pages, while the app and the automation tools lay the template out.
The CLI now opens dynamic XFA forms through the engine session and uses
its laid-out document for page and field metadata, text and pixels.
`info` keeps the input's file size and also reports the original counts
as `pdf_pages` and `acroform_fields`; `text` checks the copy permission
before extracting. The input file is never written.
Checks run (rustc 1.99.0): cargo fmt --check; cargo clippy -p
pdfcraft-cli --all-targets -- -D warnings; cargo test -p pdfcraft-cli;
cargo xtask layers; cargo xtask assets.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* M3: type an exact zoom into the rail's zoom field
The rail's zoom percentage was a read-only label. It is now a text field:
Enter applies a typed percentage (150, 150%, 62.5 %), Escape or unparsable
input keeps the current zoom. The control channel's zoom option uses the
same parser.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M3: document parse_zoom_percent
* i18n: Vietnamese for the zoom field's tooltip
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
In a region that mixes sizes (a 24 pt title over 12 pt lines), the
inline editor's caret on a small row was as tall as the region's first
size and reached into the row below. egui draws the caret at least one
row of the TextEdit's font tall, and that font had the paragraph's first
size. Each row already carries its source row's height, so the
TextEdit's font is now half the region's smallest size and only sets
that floor.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Clamp the surface device descriptor to the adapter's capabilities while
preserving its maximum 2D texture extent. Cover V3D shader variables,
lower GL capabilities, alignment ordering and capable-device defaults.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Add a clean-room Romanian translation of the UI catalog (2,670 entries,
every bundled key), the CLDR plural rule for Romanian (one / few /
other, "20 de pagini"), the ATTRIBUTION.toml entry, coverage and plural
tests, and the localization docs and roadmap entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JadgGo4G2GHaAMNb3qyygk
crates/xfdf/README.md, parity/acrobat-features.toml: next's text, which has the same sentences without the formula-cell one the #2688 integration fix removed.
crates/xfdf/src/tests.rs: the XML comments test once, where next has it.
ROADMAP.md, docs/roadmap.md: union of both sides' lines, each once.
ROADMAP.md, docs/roadmap.md: union of both sides' log lines and milestone rows, each line once.
parity/acrobat-features.toml, crates/xfdf/README.md: next's text, a superset of main's (#1917, #2686 plus #2688).
crates/edit/src/tests.rs: both sides' new tests (#2558 and #3084).
crates/ui-egui/src/editing.rs: the picked picture is cleared on every edit, and a new drawing commits its raster (#3149).
The fix landed as #2698 (9dfc91e0) with its parity evidence, but no
progress-doc record did: add the status line and progress-log entry in
ROADMAP.md, the status line, revision row and M8 milestone note in
docs/roadmap.md, and gap 6's evidence and revision history in
docs/gaps.md — the wrong-result backlog the issue belongs to.
Estimates unchanged.
Notes and file attachments are saved with the NoRotate flag (/F bit 5),
but nothing honoured it: on a page with /Rotate the icon was fitted to
/Rect and turned with the page, and sat away from where it was placed.
The vendored renderer now honours NoRotate (hayro-interpret patch 37):
the appearance fitted to /Rect is turned against the page's rotation
about the rectangle's upper-left corner, which stays put (ISO 32000-2
12.5.3). Form fields and links stay in /Rect, where their click targets
come from. A counterrotated appearance, as stamps use, would be turned
twice by viewers that honour the flag.
Annotation::shown_rect gives the box the note is drawn in. The UI uses
it for hit-testing, outlines, moving, the hover pop-up, the Comments
panel flash and the edit composer; a resize maps it back to /Rect.
comment_add anchors an icon's displayed top-left at `at`, and
comment_list, doc_info and comment_edit use the drawn box.
This also covers the sticky-note part of #1869.
Observed in Acrobat Pro on the public ISCIII form: the once-only page keeps
its place when printing (7 pages with nothing typed) but is printed blank.
PdfCraft draws its content, and has no relevant attribute or print-off
layer yet; the note says so.
A page area with <occur min="1" max="1"> that the body never reached was
never laid out, so the public ISCIII form lost the page that holds its
finishing instructions and the TERMINAR MEMORIA button once the repeated
copies over the body pages were removed.
PageArea records occur min (0 without an <occur>). When the body has been
laid out, an area used fewer times than its minimum gets the pages it still
needs, in template order, after the body's pages. The form is 7 pages with
the once-only page last, which is what Acrobat Pro shows.
Save is chosen when the prompt opens, so Enter saves as before. The arrow keys
and Tab / Shift+Tab move the choice between Don't save, Cancel and Save, shown
with a focus ring; Enter or Space press the chosen button, Escape cancels.
Before, Enter always saved, even with another button reached by Tab.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Optimize decoded DCT images with the generic JPEG decoder, which converts
three components from YCbCr to RGB whenever the JPEG itself doesn't say
otherwise, and then dropped /DecodeParms. An RGB JPEG stored untransformed
(/ColorTransform 0 and no Adobe marker) therefore came out in other colours
when recompressed, resampled or merged from strips.
The samples are now read with the colour transform ISO 32000-2 §7.4.8
gives them: an Adobe APP14 marker's flag, else /ColorTransform (default 1).
Untransformed samples are taken as stored, and the result is written as a
plain YCbCr JPEG (or Flate), which needs no /DecodeParms. When the marker
and /ColorTransform disagree, a value is out of range, the parameters are
not paired with the filter as §7.4 pairs them, or the decoder reads the
components otherwise (named R, G and B), the image is left as it is.
The tests draw each image with PdfCraft's renderer before and after
Optimize: RGB JPEGs with and without an Adobe marker under each
/ColorTransform, CMYK JPEGs (still left alone) and JPEG strips merged into
one picture.
Part of #1201.