Commit Graph
432 Commits
Author SHA1 Message Date
mtlcl410andClaude Opus 5.5 3db28cc4e3 M5: stamps without an appearance draw the stamp they name (ISO 32000-2 Table 184)
A rubber stamp from another program with no normal appearance was not
drawn at all. The display copy now gives it one:

- the fourteen standard names of Table 184 draw that stamp with
  PdfCraft's stamp drawing (eight from the palette, six with labels of
  their own), fitted to /Rect, in /C or the stamp's colour;
- no /Name draws Draft, the table's default, unless /IT says the stamp
  is an image or a snapshot;
- any other name (names match byte for byte, §7.3.5) draws a thin grey
  frame with both diagonals, so the stamp stays visible and selectable.

The drawing is display-only, like the other comments without an
appearance: Save writes the file as it was, and build() still declines
these stamps, so restyling and flattening never write it into the file.
A stamp with its own /AP /N is never touched. stamp() now takes the
label and the sign-here flag instead of a StampKind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 09:15:12 +08:00
aiongg 487907adfb fix(links): resolve remote document paths with craft-docpath's resolve_absolute (#3730)
* fix(links): use resolve_absolute for remote document paths

* fix(ui): refuse output file names that end in a dot or a space

* ci: check that git dependencies come from storytold

* ci: release only with git dependencies from storytold

* ci: check git dependency sources on a locked, parsed Cargo.lock

The git-sources step in ci.yml and release.yml fails when Cargo.lock is
missing, when .cargo/config.toml replaces or patches a source, when
Cargo.lock is out of date with the manifests (cargo metadata --locked),
and when any package source parsed from Cargo.lock as TOML is a git
source outside github.com/storytold/. A grep on Cargo's usual spelling
missed single-quoted strings and stale lockfiles.

* fix(links): a Windows path on Unix is refused, not reported as needing a source

resolve_remote_document_path reported MissingSourcePath for any path that
resolved but not to an absolute one. With an absolute source, such a path
is one this platform cannot open (C:\x.pdf on Unix): it is now
NotLocal(Invalid). A relative target from a missing or relative source
still gives MissingSourcePath.

* ci: check the legacy .cargo/config for source replacement too

Cargo reads .cargo/config as well as .cargo/config.toml, so the
git-sources step greps both; grep -s keeps a missing file from
failing the step.

* ci: parse cargo config for source replacement, patches and path overrides
2026-10-23 13:02:41 -04:00
f46268fbe4 M9: visible signatures read upright on rotated pages (#4067)
* M9: visible signatures read upright on rotated pages

A visible digital signature placed on a page with /Rotate was drawn in
user space, so its graphic and details turned with the page: on scans
stored landscape with /Rotate 270 the signature came out sideways.
Stamps (#1398) and Fill & Sign marks (#2392) were already corrected;
signatures were not.

A new signature widget on a turned page gets /MK /R equal to the page
rotation (inherited rotation included, via pdfcraft_model::pages), and
its appearance is laid out in the box as displayed (sides swapped for a
quarter turn) with a /Matrix from pdfcraft_model::view_matrix_for that
maps it exactly onto /Rect. Signing an existing field follows that
field's own /MK /R, so a field without one is drawn as before. Pages
that are not turned produce the same bytes as before.

Tests: sign crate (layout equals the upright box's, /MK /R, /Matrix,
inherited /Rotate, existing fields with and without /MK /R, malformed
/MK /R) and an engine render test on 0/90/180/270 pages with the
quadrant image. Both fail with the fix reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep one evidence/notes pair in the sign.digital parity entry

---------

Co-authored-by: vjeko2404 <vjekoslav@outlook.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-23 10:43:54 -04:00
mtlcl410andClaude Opus 5.5 e6b9792539 M4: bookmarks show and set their title colour and style (ISO 32000-2 Tables 151, 152) (#4171)
* M4: the Bookmarks panel shows each bookmark's colour and style (#3193)

ISO 32000-2 §12.3.3: an outline item's /C is "An array of three numbers
in the range 0.0 to 1.0, representing the components in the DeviceRGB
colour space of the colour that shall be used for the outline entry's
text" (Table 151), and its /F flags say italic (bit 1) and bold (bit 2)
(Table 152). Both were ignored: every title was drawn in the theme's
text colour and face.

The inspector (OutlineItem) and the bookmark list (organize::Bookmark,
used once a document is edited) now read them: each component is kept
within 0-1, and black (the default) or a /C that isn't three numbers
reads as no colour. The panel draws bold titles in the semibold face,
italic ones slanted, and the colour as given, lightened towards the text
colour only as far as it needs to read on the panel (3:1), so dark blue
stays visible in the dark theme. bookmark_list reports color, bold and
italic where they differ from the defaults.

Mutants, each failing a test: italic or bold bit ignored (both readers,
the panel), black kept as a colour, no clamping, a four-number /C
accepted, colour ignored or truncated in the panel, the contrast floor
removed, always jumping to the text colour. Checks for non-finite
numbers were equivalent (clamping already covers any size), so they
are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* M4: set a bookmark's style and colour from its menu or bookmark_set_style (#3193)

#3193 asks for a way to mark bookmarks by colour, for example chapters
that are rarely used. ISO 32000-2 §12.3.3 gives every outline item a
title colour (/C, Table 151, DeviceRGB, default black) and style flags
(/F, Table 152: bit 1 italic, bit 2 bold, default 0); the previous
commit shows them, and this one lets the user change them.

- organize: set_bookmark_color writes /C, removing it for black (the
  default) and refusing a component outside 0-1; set_bookmark_style
  sets or clears the bold and italic bits, keeps any bit the table
  doesn't define, and removes /F when no bit is left.
- engine: SetBookmarkColor and SetBookmarkStyle edits, undoable, under
  the same assemble permission as the other bookmark edits. Their undo
  labels are the menus' own names, already translated in every
  catalogue.
- ui-egui: the bookmark menu gains Style (Bold and Italic check boxes)
  and Colour (the comment swatch grid, with Other colour...). Only
  existing UI strings are used.
- automation: bookmark_set_style takes any of color ([r, g, b], 0-1),
  bold and italic, and changes only what it is given.

Mutants, each failing a test: no range check (library and tool), black
kept as /C, a bit not set, a bit not cleared, an untouched bit cleared,
/F 0 written, the bits swapped (library and menu), the tool accepting
nothing to change or ignoring bold/italic, the menu's colour ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* M4: a colour and a style set in one bookmark_set_style call are one undo step (#3193)

Review on #4171 (CodeRabbit). Given both, the tool applied two edits,
so undo took back only the style and left the colour, and a failing
second edit left the first applied. They now go in one Edit::Batch
named "Style", all or nothing. "Colour" and "Style" join EDIT_LABELS,
and "Style" BATCH_LABELS, so the history can translate them.

The test sets colour and style together and undoes once; with the two
edits applied separately it fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:42:59 -04:00
Jayesh Prajapati 8af35de464 M5: stamp_custom places a picture fitted inside a rect (#4077) (#4233)
* M5: stamp_custom places a picture fitted inside a rect

stamp_custom only centred a PDF page or image at its natural size, at
most 200 pt, so a vector diagram could not be placed at a text column's
width. It now takes rect [x0, y0, x1, y1] (displayed-page points, like
at) as an alternative to at: the picture is scaled to fit inside the
box, keeping its shape, and centred in it. A PDF page stays a form
XObject, so it remains vector.

- Engine: Edit::AddCustomStamp fits the picture inside a non-point rect
  instead of stretching it (fit_picture). A box already of the
  picture's shape is kept exactly, so signatures and other callers that
  size the box themselves are unchanged. The displayed sides are
  swapped on quarter-turned pages, as for the natural size.
- Automation: rect is validated (four finite numbers, each side
  at least 1 pt and at most 14400 pt, the largest PDF page; not clipped
  to the page, like at); passing both at and rect,
  or neither, is refused. path still goes through the read root.
- Tool schema and description, parity note and evidence.

Fixes #4077

* M14: update ctutils to 0.4.5 for RUSTSEC-2026-0385

The dependency-advisory gate rejects ctutils 0.4.2 (non-constant-time
mask generation and u128 comparisons, fixed in 0.4.4). It comes in
through crypto-bigint for the signing crates. Only its version and
checksum change in Cargo.lock.

(cherry picked from commit 8a687ee2c6012e3d18399633d2fb9fb3742f02ae)
2026-10-23 10:42:20 -04:00
Jayesh Prajapati 6765ae0b5c M11: Convert to PDF/A needs the owner's permission on an encrypted document (#3921) (#4203)
Save as PDF/A removes the encryption (PDF/A forbids it), but it was gated
only by the modify permission, so a document opened with the user password
whose owner withheld printing or copying could be saved unencrypted with
every restriction gone. It now needs the same rights as Protect and Remove
security, also inside a batch.

Fixes #3921
2026-10-23 10:42:14 -04:00
skylar taylor-barrick f2e33db113 Regression tests for #246, #843 and #2028 (#4143)
* #2028: test that Edit text & images is the first Modify page item

Edit text & images was listed under Add content, though it changes what is already on the page. The test checks that the Edit a PDF catalogue lists it first under Modify page and not under Add content. With the item back under Add content it fails on the section assertion (left: Add content, right: Modify page).

* #246: test that start-up and the panic hook never use eprintln

eprintln! panics when standard error is a broken pipe, and a panic inside the panic hook aborts the process. The test scans the product code of the desktop main.rs (everything before the test module) and fails on any eprintln! outside a comment. With the old eprintln! calls restored in the panic hook and the log-file warning, it fails listing main.rs:188 and main.rs:227.

* #843: test that text typed into an open paragraph counts as unsaved work

An open paragraph with a draft that was not applied yet was not counted as unsaved work, so closing the tab or quitting skipped the save prompt. The test opens a paragraph, types into it, and checks that first_dirty() reports the tab (and not before typing, nor after the original text is typed back). Without the line_editor check in has_unsaved_work, first_dirty() stays None and the assertion fails (left: None, right: Some(0)).
2026-10-23 10:19:13 -04:00
Eric Kaden 8f292c66ae M6: scripts see xfa_version, and xfa_installed in XFA forms (#4142) 2026-10-23 10:19:09 -04:00
aiongg 35b5abd5b3 test(engine): show the truncated-page picture exports within a sufficient budget
The fixture's image stream held six bytes under /Length 4, and the test
only checked that the picture was missing at a zero budget, which a
picture that could not be prepared also passes. The stream is four
bytes, and the picture is first shown to export at a 1 MiB budget.
2026-10-22 21:42:02 +00:00
aiongg aa1c13f71c fix(engine): list a page truncated for both forms and pictures once 2026-10-22 20:56:02 +00:00
aiongg 923e499597 Merge upstream/main into fix/coderabbit-c5-forms-misc
Conflict in crates/content/src/lib.rs: main ends inline images where the
renderer's tokenizer ends them and counts the images whose end is a guess
(Parsed::ambiguous_images); this branch reads operators through the
streaming Ops iterator that parse collects. The iterator's BI branch takes
main's inline_image result and keeps the ambiguous-image count, which parse
copies into Parsed and Ops::ambiguous_images reports.
2026-10-22 20:51:14 +00:00
aiongg b72078871a fix(content): end inline images where the renderer ends them
Filtered inline image data has no length, so its end is an EI chosen
among candidates, and the content parser chose by a different rule
than the renderer's tokenizer (hayro-syntax): the renderer also takes an
EI with no whitespace before it, and checks a candidate by reading what
follows as operators. With image data such as "7FEI 1 0 0 1 200 0 cm",
the renderer ran a cm that redaction read as image data, so text was
drawn 200 pt from where removal and its verify pass looked.

The parser now takes each inline image's end from the renderer's
tokenizer (already in the tree through pdfcraft-cos), so both read the
same operators after the image; a test runs both on the same fixtures.
Only where that tokenizer reads no image (no EI it accepts, or
parameters it can't read) does the parser fall back to its own rules,
counting the image in Parsed::ambiguous_images, and applying redactions
refuses such a page as unreadable.
2026-10-22 15:17:44 -04:00
aiongg 22aa6d5f9a fix(redact): place glyphs with the inherited and ExtGState-set text state
The redaction interpreter started every form XObject with an empty text
state (no font, size 0, no spacing) although a form inherits its caller's
graphics state, and it ignored the /Font entry of an ExtGState set by gs.
Text shown that way was placed at the wrong positions, so removal and
the verify pass could both miss glyphs under a mark. Forms now start
from the caller's state, and gs sets the font and size as Tf does.

The engine's renderer cross-check test used the gs case as its example
of interpreter/renderer disagreement; it now runs the check directly on
an unredacted page, which also covers an input stream labelled as a
redaction overlay.
2026-10-22 15:17:44 -04:00
aiongg 6ca4431b50 fix(redact): check every input content stream, whatever it calls itself
Both checks for text left under applied redaction marks (redaction's own
verify pass and the engine's renderer cross-check) skipped any page
content stream whose dictionary said /PCMark /Redaction, so that the
overlay's label would not count. An input file could put that label on
its own content stream and keep it out of both checks. Applying
redactions now records the overlay streams it adds (stamp returns the
new stream), and only those are skipped.
2026-10-22 15:17:44 -04:00
aiongg f2f86455dd fix(engine): read long underscore runs in one pass
Word assembly checked whether the whole word so far was underscores for
every glyph it added, so a long run of underscores on one line took
quadratic time. The underscore state of the current word is kept as it
grows.
2026-10-22 18:02:33 +00:00
aiongg 467c8556ec fix(engine): encode each image once for Office export
Office export encoded and kept a separate copy of an image for every place
a page drew it, so a short content stream repeating Do on one large image
multiplied it into gigabytes before the writers' limits applied. Each image
object is now encoded once and its bytes shared (pdfcraft_export::Image
holds an Arc<[u8]>), distinct pictures share a 512 MiB budget whose
overflow lists the page as truncated, and RTF, which leaves pictures out,
prepares none.
2026-10-22 18:02:33 +00:00
aiongg 77480498b2 fix(engine): low-resolution printing prints only the chosen content
Pages printed as pictures were drawn with everything on them, so form fields only
printed the page content, and the document with stamps printed every comment. The
pictures are drawn from a copy holding only what the vector print draws.
2026-10-22 13:18:26 -04:00
aiongg 73f11b2a29 fix(engine): fail an action whose information-removal step fails
A step that applies an edit logged any error and carried on, which is right
for a flatten with nothing to flatten but not for removing hidden
information or sanitizing: on a signed file the removal was refused, and the
unchanged file was written out as the action's successful result. Those
steps now fail the action unless there was nothing to remove.
2026-10-22 13:18:26 -04:00
aiongg 28ab616eb6 fix(engine): print as low-resolution pictures when only that is allowed
Printing checked the print permission but not the separate high-quality one
(Table 22, bit 12), so a document limited to low-resolution printing came out
as its original vector pages, text included. Such a document now always
prints as pictures of at most 150 dpi, whatever the settings ask for.
2026-10-22 13:18:26 -04:00
aiongg 30300ae71b fix(engine): compare only documents that allow copying their text
Compare read both documents' words out with no check of the copying
permission, and its result, report and difference comments carry that text,
so a copy-restricted document's text could be taken out through a comparison.
Both documents must now allow copying.
2026-10-22 13:18:26 -04:00
aiongg 9526363152 Build each crate's integration tests as one binary (#4087)
* Build each crate's integration tests as one binary

Every tests/*.rs file is its own executable that links the whole crate
graph. Move each crate's test files into tests/it/ as modules of one
tests/it/main.rs, for apps/pdfcraft, apps/pdfcraft-cli, automation, cos,
crypt, engine, render, sign and ui-egui. ui-egui's ui_group binary and
the support modules move into tests/it/ too. Crates with a single test
file keep it. The test executables go from 150 to 52, and every crate
runs the same number of tests as before.

ui-egui perf keeps its own binary (own process): its frame-time budgets
would charge each measurement for the other tests running beside it.

What the move needs:
- include_str!/include_bytes! and #[path] paths gain one "../".
- ui-egui: one GPU lock in tests/it/main.rs replaces the five per-file
  ones (content, document_links, editing, fill_sign, view), so one
  process creates one wgpu device at a time. The drop-line test in ui.rs
  and the screenshot blocks behind PDFCRAFT_*_SHOT(S) and
  CRAFT_UI_DOCKING_DIR, which render without holding it, take it too.
- pdfcraft winit_wayland_scroll: the vendored winit source it compiles
  names crate::event, so that shim lives in main.rs.
- parity evidence names the new paths.

* Name the one-binary test paths in docs and comments

- READMEs, docs, ATTRIBUTION and source comments name tests/it/<file>.rs.
- The oracle README's example filters with --test it encryption::qpdf_agrees.
- pdfcraft's GPU lock comment points at the UI tests' shared lock in
  crates/ui-egui/tests/it/main.rs.
2026-10-22 11:28:58 -04:00
aiongg 472717fcd7 Merge upstream main 88dad98dd into next
# Conflicts:
#	ATTRIBUTION.md
#	ATTRIBUTION.toml
#	crates/engine/src/dates.rs
#	crates/ui-egui/src/i18n/ar.tsv
#	crates/ui-egui/src/i18n/bg.tsv
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/kk.tsv
#	crates/ui-egui/src/i18n/lt.tsv
#	crates/ui-egui/src/i18n/mod.rs
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sl.tsv
#	crates/ui-egui/src/i18n/te.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	crates/ui-egui/tests/fonts.rs
#	docs/localization-parity.md
#	docs/localization.md
#	docs/roadmap.md
#	parity/acrobat-features.toml
2026-10-22 05:22:09 +00:00
aiongg ad04768906 Merge r2 track t17: choice-pass takes
# Conflicts:
#	ATTRIBUTION.md
#	ATTRIBUTION.toml
#	apps/pdfcraft/src/main.rs
#	crates/engine/src/dates.rs
#	crates/fonts/src/lib.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/i18n/mod.rs
#	crates/ui-egui/src/system_fonts.rs
#	crates/ui-egui/src/theme.rs
#	crates/ui-egui/tests/content.rs
#	crates/ui-egui/tests/fonts.rs
2026-10-22 02:25:34 +00:00
aiongg 2c13fd9373 Merge r2 track t16: mixed: automation-mcp, crate:misc, crypt-security, export-convert, optimize, preflight-pdfa, save-io
# Conflicts:
#	ATTRIBUTION.toml
#	contributors/people.toml
#	crates/automation/src/comments.rs
#	crates/edit/src/tests.rs
#	crates/engine/src/tests.rs
#	parity/acrobat-features.toml
2026-10-22 02:23:58 +00:00
aiongg dcf2802f96 Merge r2 track t15: mixed: accessibility-tags, dialogs-prefs, javascript, organize-pages
# Conflicts:
#	crates/edit/src/tests.rs
#	crates/engine/src/tests.rs
2026-10-22 02:23:22 +00:00
aiongg 3cf35888d7 Merge r2 track t12: i18n, i18n: new language catalogues
# Conflicts:
#	ATTRIBUTION.toml
2026-10-22 02:21:42 +00:00
aiongg 123b214180 Merge r2 track t10: xfa 2026-10-22 02:21:06 +00:00
aiongg 2363b0619b Merge r2 track t09: print
# Conflicts:
#	ATTRIBUTION.toml
#	crates/ui-egui/src/lib.rs
2026-10-22 02:21:06 +00:00
aiongg a2c46a9298 Merge r2 track t06: annotations-comments
# Conflicts:
#	crates/automation/tests/automation.rs
#	crates/render/src/raster.rs
2026-10-22 02:19:23 +00:00
aiongg 8724f6b1a5 Merge r2 track t05: forms
# Conflicts:
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/forms_ui.rs
#	docs/ui-parity.md
2026-10-22 02:18:46 +00:00
aiongg 2bd66fbe90 Merge r2 track t03: viewer-ui
# Conflicts:
#	crates/automation/tests/automation.rs
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/content_ui.rs
#	crates/ui-egui/src/edit_text_ui.rs
#	crates/ui-egui/src/fill_sign.rs
#	crates/ui-egui/src/forms_ui.rs
#	crates/ui-egui/tests/editing.rs
2026-10-22 02:18:22 +00:00
aiongg 7bf122eea8 Merge r2 track t02: edit-content
# Conflicts:
#	crates/edit/src/tests.rs
#	crates/edit/src/text.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/edit_text_ui.rs
2026-10-22 02:17:34 +00:00
88dad98dd4 M14: add Norwegian Bokmål interface and date language (#1836)
* M14: add Norwegian Bokmål interface and date language

A 2,592-entry `nb.tsv` covering every key the other bundled catalogs have,
written from the meaning of the English labels (clean-room); terminology
reviewed by a native-speaking contributor. Registers `nb` with the English
one/other plural rule, adds Norwegian month and weekday names for Fill &
Sign dates, resolves `no` and `nn` locales to Bokmål until a Nynorsk catalog
exists, attributes the catalog and records it in parity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: translate the strings main added since the Norwegian catalog was written

69 keys (signature appearance labels, word count, full-screen prompt, print
as image, image crop, redaction mark appearance, …) and the attribution hash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: translate the picture-menu and label-paper strings in the Norwegian catalog

Seven keys main added (Cut/Redact Image, Create Link…, Recognize Text…,
Turn upside down, the 4 x 6 in label paper) and the attribution hash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: translate the page-group folding commands in the Norwegian catalog

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: drop the superseded localization summaries left beside the current ones

Concurrent merges on main left older copies of several localization
summaries next to their replacements. Review of #1836 flagged them:

- localization-parity.md: remove the 2026-10-13 status line and the
  14-language summary that still listed Norwegian as missing; the
  current summary keeps the Italian (and now Norwegian Bokmål)
  measurement dates.
- localization.md: keep one catalog-coverage paragraph (now naming
  Norwegian Bokmål, up to about 2,700 entries) and one font paragraph.
  The font paragraph folds in what only the older copies said: the
  installed Chinese face fallback (#826) and Slovenian's Latin faces and
  four plural forms.
- roadmap.md: end the M14 Missing list before the Fontconfig note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Co-authored-by: aiongg <aiongtaigi@gmail.com>
2026-10-21 22:05:23 -04:00
aiongg a52b8d9f4a Merge PR #3498: i18n: add Central Kurdish (Sorani) as an interface language
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: arrays sized 30.
ATTRIBUTION.md: both sides' rows; count regenerated after all merges.
docs/localization.md: main's text with the ckb name, code and catalog-list entry added.
2026-10-22 01:53:40 +00:00
aiongg 2250841fea Integration: #2714 Lao date names and drop the stray Preferences... key
DATE_LANGUAGES gains the lo row in the same position as in LANGUAGES, so
date_languages_are_the_interface_languages holds; lo.tsv loses a key that
matches no English source.
2026-10-22 01:53:24 +00:00
aiongg bf3a199fbb Merge PR #2505: G14: Romanian (ro) interface catalog
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows, arrays sized 28.
crates/ui-egui/tests/fonts.rs: both catalog lists.
ATTRIBUTION.md: both sides' rows; count regenerated after all merges.
ROADMAP.md: main's summary with Romanian added (15 more catalogs); both log lines.
docs/localization-parity.md: main's rows plus the ro row; 28 interface languages; both revision rows.
docs/localization.md: main's text with Română, the ro locales and code, and the PR's catalog-list edits.
2026-10-22 01:52:53 +00:00
aiongg 13b21c7f64 Merge PR #2227: M14: add Catalan interface and date localization
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows, arrays sized 27.
crates/ui-egui/tests/fonts.rs: both catalog lists; Catalan added to main's comment.
ATTRIBUTION.toml/.md: both sides' assets; hashes and counts regenerated after all merges.
ROADMAP.md: both log lines.
docs/localization-parity.md: main's rows plus the ca row; 27 interface languages; both revision rows.
docs/localization.md: main's text with Català, the ca locales, code and catalog paragraph added.
2026-10-22 01:52:24 +00:00
aiongg 2530f52d22 Merge PR #3101: feat(viewer): add optional gapless continuous page display
Conflict resolutions:
- ATTRIBUTION.toml: main's entries kept; #3101's page-gap provenance note appended to the 22 catalogs it translates (hashes recomputed separately).
- ATTRIBUTION.md: main's side kept; regenerated from ATTRIBUTION.toml separately.
- ROADMAP.md: #3101's two 2026-10-18 progress-log lines placed after the 2026-10-19 entries.
- docs/roadmap.md: both 2026-10-18 status lines kept; M3 row carries both sides' insertions.
2026-10-22 01:52:18 +00:00
aiongg b94393400d Merge PR #2141: i18n: add Thai (th) interface language
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows (fi, sq, th), arrays sized 26.
2026-10-22 01:51:26 +00:00
aiongg f0f4aeeb19 Merge PR #2079: i18n: add Albanian (sq) interface language
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows (vi, fi, sq), arrays sized 25.
crates/ui-egui/tests/fonts.rs: both catalog lists; Albanian added to main's comment.
ATTRIBUTION.toml/.md: both sides' assets; hashes and counts regenerated after all merges.
ROADMAP.md: both log lines.
docs/localization-parity.md: main's rows plus the sq row; 25 interface languages; both revision rows.
docs/localization.md: main's text with Shqip, the sq locales and code added.
2026-10-22 01:51:09 +00:00
aiongg d52247c7d7 Merge PR #1976: i18n: add Indonesian, Vietnamese, Hindi and Korean interfaces
Conflict resolutions:
- crates/ui-egui/src/system_fonts.rs: Hangul fallback kept from #2872 (U+D7A3 probe, its candidate list); #1976's duplicate probe, hangul_fallback and hangul_candidates dropped; #1976's hangul_candidates_are_font_files_without_adobe_designs test kept (checks #2872's list).
- crates/ui-egui/src/theme.rs: SYSTEM_HANGUL_FALLBACK and its fallback entry kept once, at #2872's position and doc wording.
- crates/ui-egui/tests/fonts.rs: #2872's system_fallback_covers_hangul kept, #1976's duplicate dropped.
- ATTRIBUTION.md: asset count 279 (both sides' rows).
2026-10-22 01:50:27 +00:00
aiongg 456b96d06b Merge PR #2454: M5: year-first slash dates (yyyy/mm/dd, yyyy/m/d) for Fill & Sign and headers 2026-10-22 01:49:17 +00:00
aiongg da7f592cd0 Merge PR #1648: XFA: decode BMP and TIFF pictures
crates/xfa/src/tests.rs: union of fixture imports (tiny_bmp, tiny_tiff).
parity/acrobat-features.toml: form.xfa and the XFA image entry: evidence lists unioned, notes take both sides' insertions.
2026-10-22 01:49:05 +00:00
aiongg 4949724ec8 Merge PR #3875: M4: a new bookmark goes to where the reader is (#3865) 2026-10-22 01:48:54 +00:00
aiongg a447dd3db5 Merge PR #2731: Layers panel: Reset to Initial Visibility
Conflicts:
- ATTRIBUTION.toml: ours (sha256 lines only); hashes recomputed at the end of the track
- crates/engine/Cargo.toml: main's workspace chrono entry, plus the PR's pdfcraft-testkit dev-dependency
2026-10-22 01:48:51 +00:00
aiongg be2b7ae411 Merge PR #3452: fix(engine): a reload keeps reading colours and hidden comments (#3443) 2026-10-22 01:48:35 +00:00
aiongg a663f2e9c8 Merge PR #2825: fix(cli): info, text, render and audit take the owner password of R2–R4 files 2026-10-22 01:48:29 +00:00
aiongg 9865f27d8c Merge PR #2619: fix(xfa): run click scripts for every repeated print button
ROADMAP.md, docs/roadmap.md: both status lines and progress-log lines kept; M12 row takes both 'Done since' insertions.
crates/automation/tests/automation.rs, crates/xfa/src/fixtures.rs: union of #2624's and #2619's tests and fixtures.
parity/acrobat-features.toml: form.xfa evidence lists unioned, notes take both sides' insertions.
2026-10-22 01:48:18 +00:00
aiongg ca2e7f8ffd Merge PR #2840: M6: detected form fields get no border or fill
crates/engine/src/js.rs: auto_detect_fields keeps main's comb and turn handling, builds props with no border and no fill for every field, and pushes SetFieldProps unconditionally (the review's fix)
parity/acrobat-features.toml: form.detect-fields keeps main's comb evidence and notes and adds the no-border test and sentence
2026-10-22 01:47:29 +00:00
aiongg 844e35781a Integration: #2624 doc comment of xfa_scripts_initialize_calculate_validate_toggle_and_add_rows back on its test
The #2624 merge inserted its engine tests between #3782's doc comment and the test it documents.
2026-10-22 01:47:22 +00:00