fix: render form widgets and signature appearances via FPDF_FFLDraw#6
Open
NadeemIqbal wants to merge 1 commit into
Open
fix: render form widgets and signature appearances via FPDF_FFLDraw#6NadeemIqbal wants to merge 1 commit into
NadeemIqbal wants to merge 1 commit into
Conversation
PDFium requires a two-pass render for pages with form widgets: FPDF_RenderPageBitmap draws static content, then FPDF_FFLDraw overlays interactive widget annotations (fillable form fields and digital signature appearances). ComposePdfReader only ran the first pass, so signed PDFs showed blank rectangles where signature widgets should be. The FPDF_ANNOT flag (already passed for RenderQuality.FULL) is insufficient on its own — per PDFium's API contract, widget annotations are *always* rendered via FPDF_FFLDraw regardless of that flag. Per-platform changes follow the same pattern: initialize a FPDF_FORMHANDLE once at openPdfDocument(), keep it for the document's lifetime, call the form-fill overlay sequence (FORM_OnAfterLoadPage → FPDF_FFLDraw → FORM_OnBeforeClosePage) after each FPDF_RenderPageBitmap when quality is FULL, and tear it down with FPDFDOC_ExitFormFillEnvironment before FPDF_CloseDocument in close(). PREVIEW renders (used for thumbnails) skip the extra pass to keep them cheap. The FPDF_FORMFILLINFO struct is zero-initialised with version=2 and null callbacks — sufficient for read-only static rendering. No interactive form-fill behaviour (mouse, keyboard, JavaScript actions) is wired up, matching the existing read-only display contract of the library. Implementation surface area: - JVM/Android: new nInitFormEnv/nCloseFormEnv JNI exports; render JNI functions take an extra form-handle parameter (0 = skip overlay). - iOS: cinterop .def now includes fpdf_formfill.h; the actual class stores FPDF_FORMHANDLE + the backing FPDF_FORMFILLINFO allocation in nativeHeap and frees both in close(). - Web: pdfium_worker.mjs keeps a per-document form handle in formByDoc/formInfoByDoc maps; renderPage gates FPDF_FFLDraw on the FPDF_ANNOT flag so PREVIEW thumbnails don't pay the cost. bblanchon's prebuilt PDFium binaries already export the form-fill symbols (verified via nm/grep on linux .so, mac .dylib, and pdfium.wasm glue), so no native-binary rebuild is needed. Verified: - :pdfium:smokeTest passes on a non-form PDF (64-parallel render+text+size stress) — form-fill init/teardown is correct for documents with no widgets. - All target Kotlin compilations succeed (jvm, android, iosArm64, iosSimulatorArm64, wasmJs, js). - Native builds succeed: JNI .dylib for darwin-aarch64/x86_64; Android NDK .so for arm64-v8a/armeabi-v7a/x86/x86_64. Closes NucleusFramework#5.
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.
PDFium requires a two-pass render for pages with form widgets: FPDF_RenderPageBitmap draws static content, then FPDF_FFLDraw overlays interactive widget annotations (fillable form fields and digital signature appearances). ComposePdfReader only ran the first pass, so signed PDFs showed blank rectangles where signature widgets should be. The FPDF_ANNOT flag (already passed for RenderQuality.FULL) is insufficient on its own — per PDFium's API contract, widget annotations are always rendered via FPDF_FFLDraw regardless of that flag.
Per-platform changes follow the same pattern: initialize a FPDF_FORMHANDLE once at openPdfDocument(), keep it for the document's lifetime, call the form-fill overlay sequence (FORM_OnAfterLoadPage → FPDF_FFLDraw → FORM_OnBeforeClosePage) after each FPDF_RenderPageBitmap when quality is FULL, and tear it down with FPDFDOC_ExitFormFillEnvironment before FPDF_CloseDocument in close(). PREVIEW renders (used for thumbnails) skip the extra pass to keep them cheap.
The FPDF_FORMFILLINFO struct is zero-initialised with version=2 and null callbacks — sufficient for read-only static rendering. No interactive form-fill behaviour (mouse, keyboard, JavaScript actions) is wired up, matching the existing read-only display contract of the library.
Implementation surface area:
bblanchon's prebuilt PDFium binaries already export the form-fill symbols (verified via nm/grep on linux .so, mac .dylib, and pdfium.wasm glue), so no native-binary rebuild is needed.
Verified:
Closes #5.