Embedpdf/feature/forms - #31
Merged
Merged
Conversation
Introduce runtime-registered font support and per-annotation font subsetting for FreeText appearance generation. Adds CPDF_AnnotFontMap and CPDF_AnnotFontSubset to route fallback lookups to CFX_FontRegistry, create marker font entries in the AcroForm DR, and produce subsetted Type0/CIDFont dictionaries (using HarfBuzz) that embed only glyphs used by an annotation/layer. Update CPDF_Font::FallbackFontFromCharcode to prefer registered fonts and create runtime fallbacks, and switch FreeText AP generation to use CPDF_AnnotFontMap so resources include any registered fallback/subset fonts actually used. Expose UpdateDefaultAppearanceRegisteredFont to set a DA referencing a registered runtime font. Update BUILD.gn to include the new files and third_party/harfbuzz-ng, and add supporting CFX_FontRegistry and public/epdf_font glue.
Persist registered-font identity in marker font dictionaries and make font registry behavior robust. - Store registered font id in marker font dict (key "EmbedPDFRegisteredFontId") and add CPDF_AnnotFontSubset::GetRegisteredFontIdFromMarkerFontDict to read it. CPDF_AnnotFontMap now checks the marker dict for identity instead of inferring from BaseFont/resource alias. - Create marker font dicts with the new id field; make subset base-name comment deterministic. - Prevent CFX_FontRegistry::ClearRegisteredFonts from resetting next_font_id to avoid reusing ids that may still be referenced by existing document markers. - Update CPVT_FontMap unicode/charcode logic to use CharCodeFromUnicode checks and safe numeric conversions; preserve upstream appearance font selection behavior. - Add/adjust tests and helpers in fpdfsdk to validate stable appearance streams, alias-suffix survival, fallback rendering, checksums, and related utilities. - Update public API docs for font registration to clarify thread/ownership rules and ClearRegisteredFonts semantics. Also includes small cleanup/refactors and added includes needed by new code and tests.
Prefer registered-font mapping when generating appearance streams for persistent form widgets: if the target is persistent and there are registered fallback fonts or the font dict indicates a registered subset, create a CPDF_AnnotFontMap with registered fallbacks and embed the corresponding Font resources. Refactor duplicated AP generation into a lambda to reduce code duplication and preserve the previous CPVT_FontMap path for non-registered cases. Add CFX_FontRegistry::HasFallbackFonts() and its declaration. Add tests and a DroidSansFallbackFull.ttf test font, plus helpers to register and assert registered fallback behaviour for FreeText, TextField, ComboBox, and ListBox Korean glyphs. Also include small test fixes (initializer_list include, wchar_t usage).
Introduce a session-free EPDF form snapshot API and related utilities to support EmbedPDF use-cases. Adds a large new implementation (fpdfsdk/epdf_form.cpp) and public/epdf_form.h plus embedder tests and test PDF resources. Extend CPDF_InteractiveForm with ResolveCurrentDict and ReconcileWidget to rebind dictionaries to a document's current view and recover widgets reachable from page /Annots but missing from /AcroForm /Fields. Make ExportToFDF honor a skip_empty_required flag to preserve historic omit-empty-required behavior. Add whitespace-exact XML serialization APIs (CFX_XMLNode::SaveCompact and CFX_XMLElement::SaveCompact) to avoid corrupting xml:space="preserve" payloads, and unconditionally include CFX_MemoryStream in the build. Numerous helper routines implement form snapshotting, write transactions (toggles, text, choice), FDF/XFDF import/export, and layer-correctness rules. Update BUILD.gn files to expose new sources and tests. Tests/resources for recovered/orphan widgets and toggle fields are added.
Introduce EmbedPDF PieceInfo support: add public header and full implementation for namespace-scoped document/page PieceInfo metadata (typed values, last-modified timestamps, arrays, clear operations, and page/document variants). Add embedder tests covering save/reload and layer/delta flows. Update BUILD.gn and fpdfsdk/BUILD.gn to expose the new header and include the new sources, and switch component("pdfium") to shared_library("pdfium") while adding resources.rc to its sources.
Introduce EmbedPDF APIs and implementations: adds detached, read-only action model (epdf_action.* + helpers + public/epdf_action.h) with embedder tests; implements layer-safe selective annotation/page flattening (epdf_flatten.cpp) and test resources. Plumbing and API changes: expose CPDF_AnnotContext::GetAnnotIndex(), add CPDF_GenerateAP::GenerateFormAPWithValueOverride and thread value_override through AP generation to allow regenerating widget appearances without changing /V, and adjust CPDF_GenerateAP::GenerateFormAP calls. Fix CPDF_InteractiveForm export logic for skip_empty_required to correctly treat missing/null/array values. Update BUILD.gn entries and public headers to export new APIs and add fpdfsdk build sources and tests. Adds test PDFs/resources for flattening.
Compute the true painted bounds of /InkList by accumulating all ink points into an ink_bounds rectangle and inflating it by half the border width. Only expand the annotation /Rect when the painted bounds would otherwise be clipped, and only then persist the change for persistent targets. This prevents unconditional inflation of /Rect on every regeneration (which could cause unbounded growth) and makes appearance updates idempotent.
Add EmbedPDF attachment extraction APIs and file-attachment appearance generation. Implement EPDFDoc_GetAttachmentKey and EPDFDoc_GetAttachmentIndexByKey, the EPDFAttachmentExtractStatus enum, EPDFAttachment_ExtractFile and EPDFAttachment_ExtractFileToOwnedBuffer, and wire them into the public header. Introduce a streaming inflate helper FlateModule::FlateDecodeToSink (and its SinkDecodeStatus) to decode large/Flate-compressed embedded files without materializing the full output; add corresponding unit tests. Implement ExtractAttachmentFileToSink and supporting logic in fpdfsdk/fpdf_attachment.cpp (filter classification, sink-based and in-memory paths, size capping and error mapping). Add GenerateFileAttachmentSymbolAP/GenerateFileAttachmentAP and rotation/float-handling fixes in cpdf_generateap.cpp so file-attachment icons render correctly. Update API test checks and add extensive embedder tests for the new extraction APIs. Misc: include and build fixes and small helper utilities.
Expose a way to resolve a destination to its page dictionary object number. Implements CPDF_Dest::GetPageObjectNumber (handles numeric page indexes and page dictionary references, validates page visibility and XFA/extension cases) and exports EPDFDest_GetPageObjectNumber in the public API. Adds unit tests covering numeric and dictionary destinations and invalid references, updates headers and includes, and makes minor formatting/whitespace fixes in the C API test harness.
Retain action dictionaries on ActionNodeRecord so node payloads can be read on demand. Implement EPDFAction_GetNodeDest, EPDFAction_GetNodeURI, EPDFAction_GetNodeFilePath and EPDFAction_GetNodeName (with header docs) to expose goto/URI/file/name payloads; these getters consult the retained dictionary and may require the originating FPDF_DOCUMENT for name resolution. Update AppendAction to keep the dictionary alive. Make EPDFAnnot_SetAction remove any direct /Dest (ISO 32000-1 compliance) and add EPDFAnnot_RemoveAction and EPDFAnnot_RemoveDest with a shared RemoveLinkDictEntry helper. Add unit tests covering URI, destination, file path and named-action payloads and a missing include required by the tests.
Avoid resource-pruning bugs when content streams are appended by tracking whether this pass regenerated every existing content stream (CPDF_PageContentGenerator: CountExistingContentStreams + UpdateResourcesDict(regenerated_all_streams)). Rewrite redaction appearance generation to synthesize/flatten a final overlay form when no /RO is present: add helpers to get redact regions/BBox, build Form XObjects (MakeRedactFormStream / BuildRedactOverlayForm), layout overlay text with /DA and /Repeat, and emit overlay ops (AppendRedactOverlayOps). Update GenerateRedactAP to use the new overlay form and commonize resources. Simplify the public redaction APIs and internal reporting: remove the complex removed-annotation report buffers and replace them with an optional out_removed_annot_count that returns the number of non-REDACT annotations removed as a side-effect. Ensure pages are parsed before applying redactions and resolve overlays (pre-baked /RO wins, otherwise synthesize). Update public header signatures accordingly and add a test PDF (testing/resources/redact_inherited_colorspace.pdf) for inherited colorspace cases. Misc: minor include cleanups and refactors.
Allow appearance generation for non-persistent targets by creating an ephemeral AcroForm view instead of failing when the document lacks /AcroForm. Relax DR (/DR) handling so a missing or font-less /DR does not veto generation: persistent targets seed or mutate the document's DR/Font to add a fallback, while ephemeral targets use a direct fallback font dict without mutating the doc. Introduce a reconciled form view and related helpers in epdf_form.cpp: BuildReconciledForm, FinishTxnControl, CollectRawTxnControls, ReconciledFieldByObjNum, CollectReconciledTxnControls and an overload of CollectTxnControls that accepts an optional reconciled CPDF_InteractiveForm. Transactional control collection now prefers the reconciled (merged) widget set and falls back to the raw /Kids walk when needed. Update callers to accept and pass the reconciled view where appropriate (including using a fresh reconciled form during repair/bake steps). These changes improve correctness for multi-plane documents (e.g. recovered fields, twin widgets) and avoid unnecessary document mutation for ephemeral operations.
Add MirrorFieldValueToTwinControls to copy /V, /I and /RV from a promoted field to same-FQN twin control dictionaries (same-name twins living in their own plane) and call it from ApplyTextValue, ApplyChoiceValues and EPDFForm_ResetField so appearance generation sees the value. Update form/embedder tests by adding a two_plane_form.pdf fixture and a TwoPlaneTwinWidgetsFillTogether test that verifies toggles, text commits, and /DR seeding cover both twins. Adjust annotation appearance-related expectations (rect/BBox inflation) and refactor many fpdfsdk tests: rename MemoryFontFileAccess->MemoryFileAccess, replace detailed redaction-report helpers with simpler removed-count helpers, add bitmap/render helpers and numerous redaction overlay tests, and modernize action/form test usage (ScopedPage, null-model handling, widget creation via annot+field attach). Also tweak DestGetPageObjectNumber behavior for out-of-range legacy Dests and various minor test cleanups.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.