Skip to content

BUG: Collect the fonts declared in the AcroForm /DR dictionary - #3983

Merged
stefan6419846 merged 1 commit into
py-pdf:mainfrom
RavSinghChandan:fix-dr-fonts-not-collected
Aug 20, 2026
Merged

stefan6419846 merged 1 commit into
py-pdf:mainfrom
RavSinghChandan:fix-dr-fonts-not-collected

Conversation

@RavSinghChandan

Copy link
Copy Markdown
Contributor

_get_fonts_walk iterates the /DR font dictionary directly:

for f in cast(DictionaryObject, cast(DictionaryObject, obj["/DR"])["/Font"]):
    process_font(f)

Iterating a DictionaryObject yields its keys, so process_font receives the
font names rather than the font dictionaries. /BaseFont is never found on a
name, so every font that a form declares only in its default resources is
silently dropped from _get_fonts(). The /Resources branch a few lines below
already uses .values(), which is what made me look.

Also widened the process_font annotation from DictionaryObject to PdfObject.
The entries can be indirect references - that is why the function starts by
resolving its argument with get_object() - and a runtime protocol check
rejects them as declared. That accounts for 7 failures in test_page under
make testtype; they go to 0.

Added an offline test that builds an AcroForm carrying one /DR font. It fails
on main because the collected set comes back empty.

mypy reports the same 11 pre-existing errors before and after, none in this
file, and ruff check passes.

`_get_fonts_walk` iterates the /DR font dictionary directly:

    for f in cast(DictionaryObject, cast(DictionaryObject, obj["/DR"])["/Font"]):
        process_font(f)

Iterating a DictionaryObject yields its keys, so `process_font` receives
the font *names* rather than the font dictionaries. `/BaseFont` is never
found on a name, so every font that a form declares only in its default
resources is silently dropped from `_get_fonts()`. The /Resources branch
a few lines below already uses `.values()`.

Also widened the `process_font` annotation from DictionaryObject to
PdfObject. The entries can be indirect references, which is why the
function starts by resolving its argument with `get_object()`, and a
runtime protocol check rejects them as declared.

Added an offline test that builds an AcroForm carrying one /DR font; it
fails on main because the collected set comes back empty.
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.95%. Comparing base (b45aeba) to head (58d4752).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3983   +/-   ##
=======================================
  Coverage   97.95%   97.95%           
=======================================
  Files          57       57           
  Lines       11043    11043           
  Branches     2068     2068           
=======================================
  Hits        10817    10817           
  Misses        126      126           
  Partials      100      100           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@stefan6419846
stefan6419846 merged commit f98acfd into py-pdf:main Aug 20, 2026
63 of 76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants