Skip to content

Copy pages with the form fields of their widgets - #89

Merged
bobsingor merged 2 commits into
embedpdf/mainfrom
embedpdf/fix/import-acroform
Oct 28, 2026
Merged

bobsingor merged 2 commits into
embedpdf/mainfrom
embedpdf/fix/import-acroform

Conversation

@bobsingor

Copy link
Copy Markdown
Contributor

FPDF_ImportPagesByIndex copies a page's widgets but not their fields: the page copier skips /Parent, so each copied widget keeps naming the source's field by its number, which names nothing (or something else) once saved, and the destination gets no /AcroForm.

EPDFDoc_ImportPages copies the pages the same way, then the fields above the copied widgets: each once, its /Kids limited to what was copied, the widgets' and fields' /Parent pointed at the copies. The copied top-level fields join the destination's /AcroForm /Fields (made when it has none), with the source's /DR resources (a font whose name the destination uses for another font gets a free name, and the copied /DA strings follow), its /DA and /Q where the destination says otherwise, /NeedAppearances, the copied fields' /CO places and SignaturesExist. A copied pop-up's /Parent names its annotation's copy. Names are kept: EPDFDoc_GetImportFieldRoots and EPDFForm_GetFieldPartialName let the caller rename first.

CPDF_PageOrganizer gains three public members backing it, tagged epdf-api.

FPDF_ImportPagesByIndex copies a page's widgets but not their fields: the
page copier skips /Parent, so each copied widget keeps naming the source's
field by its number, which names nothing (or something else) once saved,
and the destination gets no /AcroForm.

EPDFDoc_ImportPages copies the pages the same way, then the fields above
the copied widgets: each once, its /Kids limited to what was copied, the
widgets' and fields' /Parent pointed at the copies. The copied top-level
fields join the destination's /AcroForm /Fields (made when it has none),
with the source's /DR resources (a font whose name the destination uses
for another font gets a free name, and the copied /DA strings follow), its
/DA and /Q where the destination says otherwise, /NeedAppearances, the
copied fields' /CO places and SignaturesExist. A copied pop-up's /Parent
names its annotation's copy. Names are kept: EPDFDoc_GetImportFieldRoots
and EPDFForm_GetFieldPartialName let the caller rename first.

CPDF_PageOrganizer gains three public members backing it, tagged
epdf-api.
Two review findings in EPDFDoc_ImportPages:

- Fonts were compared by subtype, base font and encoding only, so a font
  with other /Widths (or descriptor metrics, or a /ToUnicode map) was
  taken for the destination's and the copied fields drew with the wrong
  widths. A font is now shared only when both definitions match key for
  key, resolved all the way down; anything with a stream counts as
  different. Acrobat's identical /Helv stays shared.
- The /DA rewrite had its own tokenizer, which read a comment between the
  font name and Tf as words: "/F1 % note" then "10 Tf" kept /F1 while the
  resource was renamed. It now reads with CPDF_SimpleParser, which skips
  comments as a viewer does.

Regression tests for both, and one that a font defined the same way stays
shared.
@bobsingor
bobsingor force-pushed the embedpdf/fix/import-acroform branch from 26ca4e4 to cf7b7d5 Compare October 28, 2026 12:57
@bobsingor
bobsingor merged commit 4987bc9 into embedpdf/main Oct 28, 2026
1 check passed
@bobsingor
bobsingor deleted the embedpdf/fix/import-acroform branch October 28, 2026 12:58
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.

1 participant