Skip to content

Commit b14e03c

Browse files
committed
fix: render form widgets and signature appearances via FPDF_FFLDraw
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 #5.
1 parent 6f0ebb0 commit b14e03c

10 files changed

Lines changed: 190 additions & 14 deletions

File tree

pdfium/src/androidMain/cpp/pdfium_android.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <cstring>
1010

1111
#include "fpdfview.h"
12+
#include "fpdf_formfill.h"
1213

1314
#define LOG_TAG "pdfiumjni"
1415
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
@@ -17,7 +18,7 @@ extern "C" {
1718

1819
JNIEXPORT jboolean JNICALL
1920
Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nRenderPageToBitmap(
20-
JNIEnv* env, jclass, jlong page, jobject bitmap,
21+
JNIEnv* env, jclass, jlong page, jlong form, jobject bitmap,
2122
jint width, jint height, jint flags) {
2223
if (page == 0 || bitmap == nullptr) return JNI_FALSE;
2324

@@ -48,8 +49,15 @@ Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nRenderPageToBitmap(
4849
return JNI_FALSE;
4950
}
5051
FPDFBitmap_FillRect(bmp, 0, 0, width, height, 0xFFFFFFFF);
51-
FPDF_RenderPageBitmap(bmp, reinterpret_cast<FPDF_PAGE>(page),
52-
0, 0, width, height, 0, flags | FPDF_REVERSE_BYTE_ORDER);
52+
const int renderFlags = flags | FPDF_REVERSE_BYTE_ORDER;
53+
FPDF_PAGE p = reinterpret_cast<FPDF_PAGE>(page);
54+
FPDF_RenderPageBitmap(bmp, p, 0, 0, width, height, 0, renderFlags);
55+
if (form != 0) {
56+
FPDF_FORMHANDLE fh = reinterpret_cast<FPDF_FORMHANDLE>(form);
57+
FORM_OnAfterLoadPage(p, fh);
58+
FPDF_FFLDraw(fh, bmp, p, 0, 0, width, height, 0, renderFlags);
59+
FORM_OnBeforeClosePage(p, fh);
60+
}
5361
FPDFBitmap_Destroy(bmp);
5462

5563
AndroidBitmap_unlockPixels(env, bitmap);

pdfium/src/androidMain/kotlin/dev/nucleusframework/pdfium/PdfDocument.android.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ internal actual class PdfDocument internal constructor(
1616
private val bufferAddr: Long,
1717
private val bufferSize: Int,
1818
private val handles: LongArray,
19+
// Per-document FPDF_FORMHANDLE (parallel to [handles]). May be 0 if PDFium refused;
20+
// render code falls back to no widget overlay in that case.
21+
private val formHandles: LongArray,
1922
private val dispatchers: Array<CoroutineDispatcher>,
2023
private val executors: Array<ExecutorService>,
2124
) {
@@ -64,6 +67,9 @@ internal actual class PdfDocument internal constructor(
6467
try {
6568
val ok = PdfiumBridge.nRenderPageToBitmap(
6669
page = page,
70+
// PREVIEW skips form-fill to keep thumbnails cheap; FULL passes the form
71+
// handle so signatures + interactive widgets render correctly.
72+
form = if (quality == RenderQuality.FULL) formHandles[slot] else 0L,
6773
bitmap = bitmap,
6874
width = widthPx,
6975
height = heightPx,
@@ -139,6 +145,8 @@ internal actual class PdfDocument internal constructor(
139145
runBlocking {
140146
for (i in handles.indices) {
141147
withContext(dispatchers[i]) {
148+
// Form-fill env must be torn down BEFORE its underlying document.
149+
PdfiumBridge.nCloseFormEnv(formHandles[i])
142150
PdfiumBridge.nCloseDocument(handles[i])
143151
}
144152
}
@@ -175,7 +183,8 @@ internal actual suspend fun openPdfDocument(bytes: ByteArray, password: String?)
175183
val pairs = Array(POOL_SIZE) { Pdfium.newDispatcher() }
176184
val dispatchers = Array(POOL_SIZE) { pairs[it].first }
177185
val executors = Array(POOL_SIZE) { pairs[it].second }
178-
PdfDocument(bufferAddr, bytes.size, handles, dispatchers, executors)
186+
val formHandles = LongArray(POOL_SIZE) { PdfiumBridge.nInitFormEnv(handles[it]) }
187+
PdfDocument(bufferAddr, bytes.size, handles, formHandles, dispatchers, executors)
179188
} catch (t: Throwable) {
180189
PdfiumBridge.nFreeBuffer(bufferAddr)
181190
throw t

pdfium/src/androidMain/kotlin/dev/nucleusframework/pdfium/jvm/PdfiumBridge.android.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,23 @@ internal object PdfiumBridge {
2828
height: Int,
2929
swapRedBlue: Boolean,
3030
): Boolean
31-
/** Android-only zero-copy render: locks the Bitmap's pixels and writes directly. */
31+
/**
32+
* Android-only zero-copy render: locks the Bitmap's pixels and writes directly.
33+
* [form] is an optional FPDF_FORMHANDLE from [nInitFormEnv] — pass 0 to skip widget overlay;
34+
* non-zero enables FPDF_FFLDraw rendering of form fields and signature appearances.
35+
*/
3236
@JvmStatic external fun nRenderPageToBitmap(
3337
page: Long,
38+
form: Long,
3439
bitmap: android.graphics.Bitmap,
3540
width: Int,
3641
height: Int,
3742
flags: Int,
3843
): Boolean
44+
/** Init form-fill environment for [doc]. Returns 0 on failure. */
45+
@JvmStatic external fun nInitFormEnv(doc: Long): Long
46+
/** Tear down a form handle. Must run before the underlying document is closed. */
47+
@JvmStatic external fun nCloseFormEnv(form: Long)
3948
@JvmStatic external fun nGetPageText(page: Long): String?
4049
@JvmStatic external fun nCountTextRects(page: Long): Int
4150
@JvmStatic external fun nExtractTextRects(

pdfium/src/commonMain/kotlin/dev/nucleusframework/pdfium/RenderQuality.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package dev.nucleusframework.pdfium
22

33
/**
44
* Render quality tiers. Controls which PDFium flags are applied.
5-
* - [PREVIEW] — fastest, no annotations, no LCD text. For thumbnails and initial progressive frames.
6-
* - [FULL] — annotations on, no LCD text. ~15–25% faster than LCD-enabled while still sharp.
5+
* - [PREVIEW] — fastest, no annotations, no form widgets, no LCD text. For thumbnails and
6+
* initial progressive frames.
7+
* - [FULL] — annotations on (FPDF_ANNOT) AND form-widget overlay (FPDF_FFLDraw, used to
8+
* render fillable form fields and digital signature appearances), no LCD text. ~15–25%
9+
* faster than LCD-enabled while still sharp.
710
*/
811
enum class RenderQuality { PREVIEW, FULL }

pdfium/src/iosMain/kotlin/dev/nucleusframework/pdfium/PdfDocument.ios.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ import dev.nucleusframework.pdfium.native.FPDFText_GetUnicode
1717
import dev.nucleusframework.pdfium.native.FPDFText_LoadPage
1818
import kotlinx.cinterop.DoubleVar
1919
import kotlinx.cinterop.value
20+
import dev.nucleusframework.pdfium.native.FORM_OnAfterLoadPage
21+
import dev.nucleusframework.pdfium.native.FORM_OnBeforeClosePage
22+
import dev.nucleusframework.pdfium.native.FPDFDOC_ExitFormFillEnvironment
23+
import dev.nucleusframework.pdfium.native.FPDFDOC_InitFormFillEnvironment
2024
import dev.nucleusframework.pdfium.native.FPDF_ANNOT
2125
import dev.nucleusframework.pdfium.native.FPDF_CloseDocument
2226
import dev.nucleusframework.pdfium.native.FPDF_ClosePage
27+
import dev.nucleusframework.pdfium.native.FPDF_FFLDraw
28+
import dev.nucleusframework.pdfium.native.FPDF_FORMFILLINFO
2329
import dev.nucleusframework.pdfium.native.FPDF_GetLastError
2430
import dev.nucleusframework.pdfium.native.FPDF_GetMetaText
2531
import dev.nucleusframework.pdfium.native.FPDF_GetPageCount
@@ -31,6 +37,8 @@ import dev.nucleusframework.pdfium.native.FPDF_LoadMemDocument64
3137
import dev.nucleusframework.pdfium.native.FPDF_LoadPage
3238
import dev.nucleusframework.pdfium.native.FPDF_RenderPageBitmap
3339
import cnames.structs.fpdf_document_t__
40+
import cnames.structs.fpdf_form_handle_t__
41+
import kotlinx.cinterop.nativeHeap
3442
import kotlin.concurrent.AtomicReference
3543
import kotlinx.cinterop.ByteVar
3644
import kotlinx.cinterop.CPointer
@@ -81,6 +89,11 @@ internal actual class PdfDocument(
8189
// The pin must stay alive until close() or PDFium will dereference freed memory on the
8290
// next FPDF_LoadPage / FPDF_GetMetaText call.
8391
private val pinnedBuffer: Pinned<ByteArray>,
92+
// Per-document FPDF_FORMHANDLE used for FPDF_FFLDraw widget overlay (signatures, form
93+
// fields). May be null if PDFium refused init — render falls back to no overlay.
94+
private val formHandle: CPointer<fpdf_form_handle_t__>?,
95+
// The FPDF_FORMFILLINFO backing the form handle. Must out-live the handle; freed in close().
96+
private val formInfoPtr: CPointer<FPDF_FORMFILLINFO>?,
8497
) {
8598
actual val pageCount: Int = FPDF_GetPageCount(handle)
8699
actual val metadata: PdfMetadata = PdfMetadata(
@@ -127,6 +140,13 @@ internal actual class PdfDocument(
127140
RenderQuality.FULL -> FPDF_ANNOT
128141
}
129142
FPDF_RenderPageBitmap(bmp, page, 0, 0, widthPx, heightPx, 0, flags)
143+
// Form widget overlay (signatures, fillable fields). Only at FULL quality —
144+
// PREVIEW renders are thumbnails and don't need the extra pass.
145+
if (quality == RenderQuality.FULL && formHandle != null) {
146+
FORM_OnAfterLoadPage(page, formHandle)
147+
FPDF_FFLDraw(formHandle, bmp, page, 0, 0, widthPx, heightPx, 0, flags)
148+
FORM_OnBeforeClosePage(page, formHandle)
149+
}
130150
FPDFBitmap_Destroy(bmp)
131151
} finally {
132152
FPDF_ClosePage(page)
@@ -238,6 +258,10 @@ internal actual class PdfDocument(
238258
}
239259

240260
actual fun close() {
261+
// Form-fill env must be torn down BEFORE the document — PDFium dereferences the
262+
// document inside FPDFDOC_ExitFormFillEnvironment.
263+
if (formHandle != null) FPDFDOC_ExitFormFillEnvironment(formHandle)
264+
if (formInfoPtr != null) nativeHeap.free(formInfoPtr.rawValue)
241265
FPDF_CloseDocument(handle)
242266
pinnedBuffer.unpin()
243267
}
@@ -277,5 +301,11 @@ internal actual suspend fun openPdfDocument(bytes: ByteArray, password: String?)
277301
pinned.unpin()
278302
error("PDFium refused to open document (err=$err)")
279303
}
280-
PdfDocument(handle, pinned)
304+
// Form-fill env: minimal callbacks (version=2, all null) is enough for static widget
305+
// rendering. The struct lives in nativeHeap because PDFium retains a borrowed pointer
306+
// to it for the form handle's lifetime.
307+
val formInfo = nativeHeap.alloc<FPDF_FORMFILLINFO>().apply { version = 2 }
308+
val formHandle = FPDFDOC_InitFormFillEnvironment(handle, formInfo.ptr)
309+
if (formHandle == null) nativeHeap.free(formInfo.rawPtr)
310+
PdfDocument(handle, pinned, formHandle, if (formHandle != null) formInfo.ptr else null)
281311
}

pdfium/src/jvmMain/kotlin/dev/nucleusframework/pdfium/PdfDocument.jvm.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ internal actual class PdfDocument internal constructor(
2626
private val bufferAddr: Long,
2727
private val bufferSize: Int,
2828
private val handles: LongArray,
29+
// Per-document FPDF_FORMHANDLE (parallel to [handles]). May be 0 if PDFium refused to
30+
// init the form-fill environment for that handle; render code falls back to no overlay.
31+
private val formHandles: LongArray,
2932
private val dispatchers: Array<CoroutineDispatcher>,
3033
private val executors: Array<ExecutorService>,
3134
) {
@@ -78,6 +81,9 @@ internal actual class PdfDocument internal constructor(
7881
try {
7982
val ok = PdfiumBridge.nRenderPageToAddress(
8083
page = page,
84+
// PREVIEW skips form-fill to keep thumbnail renders cheap; FULL passes the
85+
// form handle so signatures + interactive widgets render correctly.
86+
form = if (quality == RenderQuality.FULL) formHandles[slot] else 0L,
8187
address = addr,
8288
width = widthPx,
8389
height = heightPx,
@@ -155,6 +161,9 @@ internal actual class PdfDocument internal constructor(
155161
runBlocking {
156162
for (i in handles.indices) {
157163
withContext(dispatchers[i]) {
164+
// Form-fill env must be torn down BEFORE its underlying document —
165+
// FPDFDOC_ExitFormFillEnvironment dereferences the FPDF_DOCUMENT.
166+
PdfiumBridge.nCloseFormEnv(formHandles[i])
158167
PdfiumBridge.nCloseDocument(handles[i])
159168
}
160169
}
@@ -195,7 +204,11 @@ internal actual suspend fun openPdfDocument(bytes: ByteArray, password: String?)
195204
val pairs = Array(POOL_SIZE) { Pdfium.newDispatcher() }
196205
val dispatchers = Array(POOL_SIZE) { pairs[it].first }
197206
val executors = Array(POOL_SIZE) { pairs[it].second }
198-
PdfDocument(bufferAddr, bytes.size, handles, dispatchers, executors)
207+
// Init one form-fill env per document handle. PDFium tolerates docs without forms
208+
// (the handle still returns non-zero) — FPDF_FFLDraw is a no-op for pages with
209+
// no widgets, so eager init costs only a small struct allocation per document.
210+
val formHandles = LongArray(POOL_SIZE) { PdfiumBridge.nInitFormEnv(handles[it]) }
211+
PdfDocument(bufferAddr, bytes.size, handles, formHandles, dispatchers, executors)
199212
} catch (t: Throwable) {
200213
PdfiumBridge.nFreeBuffer(bufferAddr)
201214
throw t

pdfium/src/jvmMain/kotlin/dev/nucleusframework/pdfium/jvm/PdfiumBridge.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,27 @@ internal object PdfiumBridge {
2828
height: Int,
2929
swapRedBlue: Boolean,
3030
): Boolean
31-
/** Zero-copy render: writes directly at [address]. Flags = `FPDF_ANNOT | FPDF_LCD_TEXT | …`. */
31+
/**
32+
* Zero-copy render: writes directly at [address]. Flags = `FPDF_ANNOT | FPDF_LCD_TEXT | …`.
33+
* [form] is an optional FPDF_FORMHANDLE from [nInitFormEnv] — pass 0 to skip widget overlay;
34+
* non-zero enables FPDF_FFLDraw rendering of form fields and signature appearances.
35+
*/
3236
@JvmStatic external fun nRenderPageToAddress(
3337
page: Long,
38+
form: Long,
3439
address: Long,
3540
width: Int,
3641
height: Int,
3742
flags: Int,
3843
): Boolean
44+
/**
45+
* Initialize a form-fill environment for the given document handle. Returns 0 if PDFium
46+
* refuses (e.g. document already closed). Must be paired with [nCloseFormEnv] before
47+
* [nCloseDocument] runs.
48+
*/
49+
@JvmStatic external fun nInitFormEnv(doc: Long): Long
50+
/** Tear down the form handle. Safe to call with 0. */
51+
@JvmStatic external fun nCloseFormEnv(form: Long)
3952
@JvmStatic external fun nGetPageText(page: Long): String?
4053
/** Count of line-level text rectangles on the given page. */
4154
@JvmStatic external fun nCountTextRects(page: Long): Int

pdfium/src/jvmMain/native/pdfium_jni.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "fpdfview.h"
1414
#include "fpdf_doc.h"
15+
#include "fpdf_formfill.h"
1516
#include "fpdf_text.h"
1617

1718
namespace {
@@ -184,10 +185,15 @@ Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nRenderPage(
184185
* Layout: BGRA, stride = width*4. Caller owns the memory; we only write.
185186
* [flags] is a bitmask from fpdfview.h (FPDF_ANNOT, FPDF_LCD_TEXT, FPDF_REVERSE_BYTE_ORDER, …).
186187
* Passing 0 yields the fastest render (draft quality).
188+
*
189+
* [form] is an optional FPDF_FORMHANDLE (from nInitFormEnv) — pass 0 to skip widget rendering.
190+
* When non-zero, FPDF_FFLDraw overlays form-field appearances (interactive widgets and
191+
* signature appearance streams) on top of the page contents. PDFium documents this as the
192+
* required second pass for displaying form widgets correctly.
187193
*/
188194
JNIEXPORT jboolean JNICALL
189195
Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nRenderPageToAddress(
190-
JNIEnv*, jclass, jlong page, jlong address,
196+
JNIEnv*, jclass, jlong page, jlong form, jlong address,
191197
jint width, jint height, jint flags) {
192198
if (page == 0 || address == 0) return JNI_FALSE;
193199
void* buffer = reinterpret_cast<void*>(address);
@@ -196,12 +202,52 @@ Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nRenderPageToAddress(
196202
FPDF_BITMAP bmp = FPDFBitmap_CreateEx(width, height, FPDFBitmap_BGRA, buffer, stride);
197203
if (!bmp) return JNI_FALSE;
198204
FPDFBitmap_FillRect(bmp, 0, 0, width, height, 0xFFFFFFFF);
199-
FPDF_RenderPageBitmap(bmp, reinterpret_cast<FPDF_PAGE>(page),
200-
0, 0, width, height, 0, flags);
205+
FPDF_PAGE p = reinterpret_cast<FPDF_PAGE>(page);
206+
FPDF_RenderPageBitmap(bmp, p, 0, 0, width, height, 0, flags);
207+
if (form != 0) {
208+
FPDF_FORMHANDLE fh = reinterpret_cast<FPDF_FORMHANDLE>(form);
209+
FORM_OnAfterLoadPage(p, fh);
210+
FPDF_FFLDraw(fh, bmp, p, 0, 0, width, height, 0, flags);
211+
FORM_OnBeforeClosePage(p, fh);
212+
}
201213
FPDFBitmap_Destroy(bmp);
202214
return JNI_TRUE;
203215
}
204216

217+
// Minimal FPDF_FORMFILLINFO for read-only widget rendering. All callbacks left null —
218+
// PDFium tolerates this for static-render use cases (no JavaScript, no field interaction).
219+
// Must out-live the FPDF_FORMHANDLE returned by FPDFDOC_InitFormFillEnvironment, so it's
220+
// declared with static storage. A single shared instance across documents is safe: the
221+
// struct holds no per-document state.
222+
namespace { FPDF_FORMFILLINFO g_formInfo = []() { FPDF_FORMFILLINFO i{}; i.version = 2; return i; }(); }
223+
224+
/**
225+
* Initialize a form-fill environment for [doc] and return its handle. The handle is
226+
* passed to [nRenderPageToAddress] / [nRenderPageToBitmap] so PDFium can overlay
227+
* widget annotations (form fields, signatures) on top of rendered pages. Returns 0
228+
* if PDFium refuses; caller may continue without form-fill in that case.
229+
*/
230+
JNIEXPORT jlong JNICALL
231+
Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nInitFormEnv(
232+
JNIEnv*, jclass, jlong doc) {
233+
if (doc == 0) return 0;
234+
FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(
235+
reinterpret_cast<FPDF_DOCUMENT>(doc), &g_formInfo);
236+
return reinterpret_cast<jlong>(form);
237+
}
238+
239+
/**
240+
* Tear down the form-fill environment created by [nInitFormEnv]. Must be called BEFORE
241+
* the underlying FPDF_DOCUMENT is closed — PDFium will crash if you exit the document
242+
* first.
243+
*/
244+
JNIEXPORT void JNICALL
245+
Java_dev_nucleusframework_pdfium_jvm_PdfiumBridge_nCloseFormEnv(
246+
JNIEnv*, jclass, jlong form) {
247+
if (form == 0) return;
248+
FPDFDOC_ExitFormFillEnvironment(reinterpret_cast<FPDF_FORMHANDLE>(form));
249+
}
250+
205251
/**
206252
* Allocate a native buffer and copy the Java byte array into it. Returns a raw pointer
207253
* that can be passed to [nOpenDocumentFromMemory] — the pointer must outlive every

pdfium/src/nativeInterop/cinterop/pdfium.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package = dev.nucleusframework.pdfium.native
22
language = C
3-
headers = fpdfview.h fpdf_doc.h fpdf_text.h
3+
headers = fpdfview.h fpdf_doc.h fpdf_formfill.h fpdf_text.h
44
headerFilter = fpdf*.h
55

66
# Headers are staged by the Gradle task `installPdfiumHeaders` under build/pdfium/include.

0 commit comments

Comments
 (0)