Commit Graph
570 Commits
Author SHA1 Message Date
johnpetersa19andCopilot App 4eaba2bbcd M14: complete Brazilian Portuguese catalog
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-21 08:14:32 -03:00
Janiz-zzzandClaude Opus 5.5 0a78f31fec Add Finnish interface and date language
Adds a Finnish (Suomi, `fi`) catalog with 2,592 entries: every key of
the other bundled catalogs, written in sentence case from the English
labels. Finnish uses the one/other plural rule with the partitive
singular after any number but 1 (1 sivu, 2 sivua, 0 sivua).

Finnish is also a date language: calendar headings use the nominative
month (Lokakuu 2026) and dates the partitive (14. lokakuuta 2026).
Any fi-* locale selects it.

Tests cover registration, locale tags, persistence, plurals, calendar
wording, commands/tools, scanned UI literals, every bundled catalog key
and the Latin UI fonts. The catalog has its ATTRIBUTION.toml entry
(ATTRIBUTION.md regenerated with `cargo xtask assets --write`).

Clean-room, AI-assisted (Claude Code) translation; not yet proofread
line by line by a native speaker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 09:10:16 +03:00
Mex 37454d9ce1 M4: document indirect initial-view boolean handling
Update the M4 milestone note and revision history; preserve existing gaps and estimates.
2026-10-20 21:08:17 +02:00
Aman MehtarandClaude Code c7505930b8 M12: accept Identity CJK Unicode mappings in accessibility checks (#3673)
Treat predefined CJK CMaps and Adobe CID collections as alternative mapping routes. Resolve indirect metadata and reject unknown names and foreign registries without changing ToUnicode handling. Add synthetic checker and read-only automation regressions with red/green evidence.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-20 23:29:13 +05:30
robertobulltech 1451325a42 M2: preserve word spaces around TOC leaders (#3086) 2026-10-20 19:15:53 +02:00
PerchAnton 941fbe7cda M3: choose overlapping comment hover by annotation index (#3620) 2026-10-20 19:58:22 +03:00
hcchung1andClaude Sonnet 5.5 0ca7ed07fa fix(automation): a page whose paragraph listing was dropped at the cap is refused, not read by position (#2516)
The listings kept for paragraph numbers are capped at 256 pages, and the 257th cleared them all.
A page that lost its listing fell back to reading a number as a position in the page's current
paragraphs, so after an edit regrouped it a number could rewrite another paragraph.

Documents that lose a listing to the cap are remembered, and a page of one with no listing is
refused with a message to list it again. doc_close drops a document's listings and that mark.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 00:22:07 +08:00
PerchAnton 929455ad5b M3: fix multiline annotation hover bounds and paint order (#3541) 2026-10-20 19:20:56 +03:00
jpeskovandClaude 9175291a8f fix(render): draw missing spacing glyphs in Japanese CID substitutes as spaces (#3601)
UniJIS-UCS2-HW-H maps code 0x0020 to CID 231 / U+2002. The OpenType
substitute for a non-embedded Japanese CID font lacks that glyph, so
.notdef boxes were drawn. Type0Font::map_via_unicode now falls back to
the substitute's ordinary-space glyph for explicit spacing characters
its charmap lacks. Native and variation-selector glyphs keep priority;
PDF advances and Unicode text are unchanged.

Fixes #3601.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-20 17:33:37 +05:30
Ahmad Mujahid 3b3787078e Fix named properties in forms without resources 2026-10-20 15:39:35 +04:00
Ahmad Mujahid 1489436392 fix(print): preserve existing appearances without Subtype (#3532) 2026-10-20 14:34:40 +04:00
Ahmad Mujahid 25eb568839 fix(forms): preserve content stream comment boundaries (#3502) 2026-10-20 13:30:02 +04:00
Ahmad Mujahid ab9a5009ac Fix #3507: preserve content boundaries when merging image fragments 2026-10-20 13:23:20 +04:00
Fernando Areán MagánandClaude Opus 5 5fc66c4595 M14: refresh the Spanish catalog's ATTRIBUTION entry and date the parity figures
`cargo xtask assets` pins a SHA-256 for every catalog, so editing `es.tsv` left its
ATTRIBUTION.toml entry stale and `assets::tests::the_real_manifest_passes` failed on both
runners. Re-verified the file's provenance, updated the hash, recorded that the coverage
additions are AI-assisted and not separately native-reviewed -- as #2510 did for `lt` and
`vi` -- and regenerated ATTRIBUTION.md.

Review notes on docs/localization-parity.md:

- Lithuanian's `2,585 entries` was measured on 2026-10-13 and read as if `lt` were behind.
  Re-measured today it covers the whole 2,674-key union, so it is restated like `es` and `vi`.
- *How this was measured* now says outright that the union is a moving target: every change
  that adds a string widens it, a count only compares with others of the same date, and a
  catalog at 100% falls behind without losing a translation. Earlier revisions quote the
  union of their own date, not this one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-20 09:15:23 +02:00
Fernando AreánandClaude Opus 5 4ac7004292 M14: Spanish catalog covers the bundled key union
es.tsv was missing 143 of the 2,674 (context, English) keys the other
bundled catalogs carry, so those strings fell back to English inside an
otherwise Spanish interface: every calendar month and weekday, the whole
certificate context of the signature inspector, the X.509 key usages, the
signature-revision and digital-ID lines, password validation, eight plural
messages, the combine-from-folder strings, the rendering and stale-file
notices and the tooltips that spell their shortcut out.

Spanish now covers the whole union, as lt and vi do: 2,531 -> 2,674 of
2,674, measured as docs/localization-parity.md describes. Counts there and
in ROADMAP.md re-measured against the current union; vi is restated at
2,674 for the same reason, still 100%.

Translations reuse the vocabulary already in the file (ID digital, Acercar
/ alejar, Portapapeles, A doble cara, Cortar y apilar) and were written
from the English labels, not from another implementation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-20 08:20:16 +02:00
PerchAnton e3bf3afa81 M12: refresh XFA fix with current feature evidence (#2615) 2026-10-20 08:33:36 +03:00
PerchAnton 5ae7e5d1ca M12: refresh XFA fix with current feature evidence (#2619) 2026-10-20 08:30:32 +03:00
PerchAnton 5a49f7b626 M12: refresh XFA fix with current feature evidence (#2624) 2026-10-20 08:27:14 +03:00
PerchAnton 01dc4ac90f M12: refresh XFA fix with current feature evidence (#2648) 2026-10-20 08:23:25 +03:00
hcchung1andClaude Sonnet 5.5 acacf9485f fix(automation): hide_text_block resolves its number like text_edit, and a merged paragraph is not followed (#2516)
page_render's hide_text_block used the paragraph number as a position in the page's current
paragraphs, so after an edit regrouped the page it hid a different paragraph from the one
text_edit would rewrite. It now resolves the number against the text_paragraphs listing and is
refused when the paragraph is gone.

text_edit also accepted any overlapping paragraph that contained the requested text as the
edited one. When the edit merged the paragraph into a neighbour, the merged paragraph contains
that text too, so the number followed it and a second edit by that number dropped the
neighbour's text. The edited paragraph must now show exactly the requested text; a merged one
leaves the number stale.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 11:57:48 +08:00
jonathanwxh-cell 1c7ad8e465 fix: merge current main into optimizer compatibility branch 2026-10-20 10:52:38 +08:00
djmushin 39d0b953ca M6: treat imported MaxLen zero as unlimited 2026-10-19 22:03:50 -04:00
djmushin 0ba01a0557 M6: optimize AcroForm JavaScript snapshots and diffs 2026-10-19 22:03:49 -04:00
hcchung1 3909bebeec M7: a paragraph number keeps naming the paragraph text_paragraphs listed (#2516)
Paragraph numbers are positions in a list regrouped from geometry after
every edit, so an edit that merged a paragraph into its neighbour made the
next edit by number rewrite another paragraph and lose its text.

After text_paragraphs, text_edit and text_edit_layout find the listed
paragraph again by its text and box, and refuse one that no longer exists on
its own (list the page again). An edit's result names the numbers that are
gone in stale_paragraphs. The inline editor's switch-paragraph click holds
the same key instead of an index. Without a listing a number is a position,
as before. An identity that survives save and reopen is still #2508.
2026-10-20 10:02:06 +08:00
ffishmanandClaude Opus 5.5 0a56784df8 M9: read .p7b/.p7c certificate bundles for trust import
load_certificates now reads PKCS #7 certificate bundles (degenerate
SignedData, RFC 5652 §5.2) in DER and as PEM PKCS7/CMS blocks, the way
Windows, Acrobat and certificate authorities export chains. PEM END
lines must match their BEGIN label.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 20:32:37 -03:00
vangel76 7504799e05 M6: align secured-form highlight tests after rebase (#2273) 2026-10-20 01:11:01 +02:00
PerchAnton cc22faca2f M4: keep large named destination trees usable on page deletion 2026-10-19 23:47:18 +03:00
KnottyDyes 3c366d5e16 Render: radial luminosity fades have regression coverage 2026-10-19 13:27:31 -06:00
ec0a965074 M5.6: preserve nested annotation values in FDF exports (#1971)
* M5.6: preserve nested annotation values in FDF exports

Copy and renumber retained object graphs without expanding aliases or following
indirect cycles recursively. Refuse excessive work and propagate export errors
before the destination is written. Cover saved geometry, colour and borders,
shared graphs, streams, stale references and refusal through automation tools.

Co-Authored-By: Codex <noreply@openai.com>

* Bound FDF annotation copying before allocation

Keep selected aliases shared, budget retained keys and values before copying, and add direct-payload and alias-count regressions. Retain copied-graph limits and document source-memory scope.

* M5.6: bound FDF cache-eviction discovery and field values

Extend the concurrent annotation-budget correction while retaining its direct-payload and alias regressions. Record annotation positions instead of resolved bodies so cache eviction cannot pin repeated parsed copies; borrow direct values and budget retained entries before cloning. Count every emitted multi-select field value before allocating its output array.

Observed pre-fix allocation-cap and field-limit failures, then fixed tests passed. Final validation: 549 scoped XFDF/engine/automation tests passed, three existing ignored; strict all-targets Clippy, WASM, fmt, layers, assets, parity and diff checks passed.

AI assistance: OpenAI Codex for @MMexicann.

* M5.6: record bounded FDF export regression evidence

Record comment cache-eviction discovery and emitted-field-value budget regressions without changing feature scores or status. Describe copied-graph limits and existing source-parser limits precisely. Final 549 scoped tests, strict Clippy, WASM, fmt, layers, assets and parity passed.

AI assistance: OpenAI Codex for @MMexicann.

* M5.6: align FDF progress with budgeted discovery

Document lazy annotation positions, cache-eviction coverage and copied-graph limits while retaining the original nested-value progress entry and all upstream notes. Estimates unchanged.

AI assistance: OpenAI Codex for @MMexicann.

* M5.6: describe FDF discovery and copied-graph limits

Align exchange documentation with the tested lazy-position discovery implementation and its copied-graph limits. Source parsing/page discovery keep existing limits.

AI assistance: OpenAI Codex for @MMexicann.

* M5.6: align milestone notes with FDF discovery limits

Retain upstream milestone history and describe the tested discovery/copy budgets without increasing estimates or claiming a total source-memory bound.

AI assistance: OpenAI Codex for @MMexicann.

* M5.6: keep nested page links out of FDF exports

Preserve graph aliases and existing budgets; exclude direct and indirect Page/Pages type names. Add saved-PDF regression and bounded type-resolution controls. Both pre-fix failures observed; 46 scoped tests, strict Clippy, WASM and formatting passed.

* M5.6: document bounded nested page exclusion

Address maintainer feedback on the existing PR. Preserve upstream work and document the tested scope and remaining validation limits.

* M5.6: record nested page-reference regression evidence

Address maintainer feedback on the existing PR. Preserve upstream work and document the tested scope and remaining validation limits.

* M5.6: retain FDF limits in milestone evidence

Address maintainer feedback on the existing PR. Preserve upstream work and document the tested scope and remaining validation limits.

* M5.6: cite nested page-reference exclusion tests

Address maintainer feedback on the existing PR. Preserve upstream work and document the tested scope and remaining validation limits.

* M5.6: respect generations while identifying page references

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* XFDF: document stale Type preservation regression

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M5.6: record generation-aware page exclusion evidence

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M5.6: propagate FDF export errors in usage example

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M5.6: consolidate roadmap change and target fields

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-19 12:21:37 -06:00
Claude 62f306ba4c Merge branch 'main' of https://github.com/storytold/pdfcraft into fix/identity-h-tounicode
# Conflicts:
#	contributors/people.toml
2026-10-19 17:05:37 +00:00
5602fbba12 M10: Office export follows forms 50 deep and up to 50 000 a page and says where it stops (#3120) (#3426)
* M10: Office export reads forms as far as the renderer and says where it stops (#3120)

Export to Word, PowerPoint, HTML and RTF stopped at 12 nested forms and
4 096 forms a page and left the rest out silently. It now follows forms
50 deep, as the renderer does, and up to 50 000 a page (the renderer's
budget for nested paints), still bounded on hostile files.
doc_export_office lists pages past those limits in truncated_pages, with
a warning. New: reading_blocks_checked and export_office_checked;
reading_blocks and export_office keep their signatures.

Fixes #3120

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

* Tests: pin the form depth limit to the renderer's 50 (#3120)

The depth test built its chain from MAX_FORM_DEPTH, so it moved with the
constant. Write the renderer's limit out: depth 50 is read, depth 51 is
left out and reported. Fails with the constant at 49 and at 51.

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

* Export: say which forms count toward the page limit (#3120)

The page budget also counts forms the page draws itself, which the
renderer does not charge, so a page can be reported as cut although the
viewer shows it. The warning and the tool description now say so.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-19 13:02:44 -04:00
84bd488db3 M3: keep save shortcuts behind other dialogs (#3387)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:01:58 -04:00
32abf71049 Text: tracked glyphs retain their word boundaries (#3477)
* Text: tracked glyphs retain their word boundaries

* M7: cap inferred tracking at half an em so one-glyph words and cells keep their spaces

Adds the regression test from the #3477 review (fails without the cap).

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

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:57:52 -04:00
KnottyDyes 1bb3e916fe Docs: install the CLI and register it with MCP clients (#3478) 2026-10-19 12:57:29 -04:00
Nyanpasuwu 14fcc82a24 i18n: add Central Kurdish (Sorani) as an interface language
2,670 entries in ckb.tsv, written in logical order, with the same
(context, source) key set as ar.tsv. Registered with rtl: true and
plural_one_other (CLDR ckb: one, other); Sorani keeps the noun singular
after a numeral, so the 13 @plural rows usually read the same in both
forms.

RTL reuses the Arabic path: the catalog is put into display order by
bidi::display_rtl when it loads, so Kurdish has the same four limits
docs/localization.md lists for Arabic. No new layout or bidi code.

DATE_LANGUAGES gains Kurdish month and weekday names, because
date_languages_are_the_interface_languages keeps both registries in
step.

ku-* locales are not mapped to ckb on purpose: ku is the macrolanguage
and means Kurmanji in Latin script. Only ckb* tags resolve.
2026-10-19 19:32:21 +03:00
Claude 9f063cee10 docs: gap 2 and view.render-cid-fonts for /ToUnicode /Identity-H
The two Identity-H tests are evidence for view.render-cid-fonts, which
stays partial; gaps.md records the change under gap 2. Estimates unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LymhVaGZCWwB9HNEbLzeMM
2026-10-19 16:31:46 +00:00
PerchAnton 6bcfb872e2 M7: resolve main integration for PR #3000 2026-10-19 19:22:46 +03:00
PerchAnton 73a98ffd79 M12: resolve main integration for PR #2648 2026-10-19 19:12:49 +03:00
PerchAnton 4bba9e08c6 M12: resolve main integration for PR #2624 2026-10-19 19:07:47 +03:00
PerchAnton 0d502f028b M12: resolve main integration for PR #2619 2026-10-19 19:05:12 +03:00
PerchAnton b2477ff326 M12: resolve main integration for PR #2615 2026-10-19 19:01:17 +03:00
PerchAnton d1ea34e0db M7: resolve main integration for PR #3187 2026-10-19 18:59:01 +03:00
PerchAnton c975abbc02 M4: resolve main integration for PR #3311 2026-10-19 18:56:09 +03:00
PerchAnton a33cf0fe36 M1: resolve main integration for PR #3042 2026-10-19 18:43:18 +03:00
mtlcl410andClaude Fable 5.1 1e2e7cc79f M3: full screen shows one fitted page at a time, as Acrobat's Full Screen Mode (#1459)
Full screen is the page on black and nothing else: one page (or one spread,
when two-page view was on, #1353) fitted to the screen, from the current
page; a click, Space, Enter, the arrows and Page Up/Down turn pages, a
shift-click and Backspace go back; Esc brings the display from before
back at the page reached. The quick tools are not drawn in full screen.

Transitions, auto-advance, loop and the cursor hiding stay planned.

Refs #379.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RUNQSPVXx3dDBabRZHAnjz
2026-10-19 15:02:20 +08:00
6733e073ef Keep long menus usable in short windows (#3374)
* M14: keep long menus usable in short windows

* Menus: scroll each top-level menu once, from its caller, so View's list isn't nested in a second scroll area

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

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:49:34 -04:00
Earl Co 66f1085688 Keep document scroll position across viewer modes (#3362) 2026-10-19 02:48:18 -04:00
mtlcl410andClaude Opus 5.5 0de546587d fix(windows): present Direct3D 12 through a composition visual, so resizing doesn't stretch (#2738)
While the window was being resized, Windows stretched the window's swap
chain, still at the old size, to the new one: the text shimmered and the
left panel's width bounced for as long as the drag lasted. A DirectComposition
visual's last frame is shown at its own size instead. WGPU_DX12_PRESENTATION_SYSTEM
still overrides it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv2WwdgjmBz33GWkwgNn3Q
2026-10-19 09:09:01 +08:00
Earl Co 3086ee7a3d M11: reject hostile optimizer image dimensions 2026-10-19 02:45:16 +02:00
srt8hellcat2-ui db723fd087 M3: integrate page-edge shadow preference with current main (#1577) 2026-10-18 20:26:54 -04:00