Android API reference
Generated from the library's Kotlin sources, which compile under explicit API mode — so everything listed here is everything published. For a guided introduction, start with the Android guide.
Package com.pdfsdk.editor: 64 public types and 353 members, generated from the SDK's sources at build time, so this page cannot drift from them.
- The editor —
Top-level functions,PdfEditorTool,PdfEditorMode,PdfEditorView - Customization —
PdfEditorLocalization,PdfEditorLayoutDirection,PdfSignaturePlacement,PdfEditorConfiguration,PdfEditorConfiguration.Companion,PdfEditorFont,PdfEditorColors,PdfEditorStamp,PdfEditorStamp.Companion,PdfEditorSignatureMethod,PdfEditorCustomAction,PdfEditorActionHandler,PdfEditorPdfCallback,PdfEditorActionContext,PdfEditorToolbarItem,PdfEditorToolbarItem.Tool,PdfEditorToolbarItem.Custom,PdfEditorMenuEntry,PdfEditorMenuEntry.Item,PdfEditorMenuEntry.Custom,PdfEditorHeaderButton,PdfEditorAction,PdfEditorMenuItem,PdfEditorColorScheme,PdfEditorHandleShape,PdfEditorMarkupStyle,PdfEditorInkStyle,PdfEditorToolDefaults - Signing —
PdfCmsSigner,PdfEditorSigning,PdfSignatureReport - Document API —
PdfDocumentBridgeException,PdfRect,PdfLayer,PdfLayer.Kind,PdfLayer.Shape,PdfSearchMatch,PdfFormField,PdfFormField.Kind,PdfMetadataKey,PdfFontFamily,PdfZOrder,PdfMarkupKind,PdfImageKind,PdfFormFieldKind,PdfTextResult,PdfDocumentException,PdfDocumentException.CannotOpen,PdfDocumentException.NotFound,PdfDocumentException.UnsupportedGlyphs,PdfDocumentException.Failed,PdfDocumentEditor,PdfDocumentListener - SDK, licensing and callbacks —
PdfEditorSdk,PdfEditorLicense,PdfEditorLicense.Status,PdfEditorFont.Companion,PdfBytesListener,PdfEditorCloseListener,UnsavedChangesListener
The editor
Top-level functions
openBridgedDocument
public fun openBridgedDocument(
bytes: ByteArray,
password: String?,
): PdfDocumentEditor =Open a document for a binding, with bridge errors.
perform
public fun PdfDocumentEditor.perform(
op: String,
args: Map<String, Any?> = emptyMap(),
): Any? = tryRun one document operation for a binding. See the file header for the conventions.
PdfSignaturesScreen
public fun PdfSignaturesScreen(
pdfBytes: ByteArray,
onClose: () -> Unit,
): Unit =A read-only report on the digital signatures in a PDF: who signed, when, whether the bytes they signed still match, and what the covered byte-range leaves out.
Separate from PdfEditorScreen on purpose — verification is something a host wants to show ABOUT a document (behind an overflow item, in a details sheet) without putting the user into an editor. It is presentation only: hand it the bytes, it verifies them off the main thread and renders the result.
The verifier checks the signature MATHEMATICALLY — the digest, the byte range, the public key in the embedded certificate. It does NOT evaluate whether that certificate is trusted, so a self-signed signature and one from a public CA are reported the same way. Present it as "the document has not been altered since signing", not as "this signer is who they say they are".
PdfEditorScreen
public fun PdfEditorScreen(
pdfPath: String,
password: String? = null,
initialMode: PdfEditorMode? = null,
initialTool: PdfEditorTool? = null,
configuration: PdfEditorConfiguration = PdfEditorConfiguration(),
onSave: (ByteArray) -> Unit,
onClose: () -> Unit,
onSharePdf: ((ByteArray) -> Unit)? = null,
onPrint: ((ByteArray) -> Unit)? = null,
onFlattenAndShare: ((ByteArray) -> Unit)? = null,
onDigitallySigned: ((ByteArray) -> Unit)? = null,
onUnsavedChangesChanged: ((Boolean) -> Unit)? = null,
onDocumentReady: ((PdfDocumentEditor) -> Unit)? = null,
)PdfEditorTool
public enum class PdfEditorTool(internal val action: EditorToolAction)A specific tool the HOST can pre-arm when it presents the editor, INDEPENDENT of the initial mode. Arming behaves exactly as if the user tapped that tool in the mode toolbar.
ADD_TEXT
ADD_TEXT(EditorToolAction.Insert(InsertTool.TEXT))IMAGE
IMAGE(EditorToolAction.Insert(InsertTool.IMAGE))LINK
LINK(EditorToolAction.Link)INSERT_PAGE
INSERT_PAGE(EditorToolAction.InsertPage)MULTI_SELECT
MULTI_SELECT(EditorToolAction.Multi)HIGHLIGHT
HIGHLIGHT(EditorToolAction.Insert(InsertTool.HIGHLIGHT))UNDERLINE
UNDERLINE(EditorToolAction.Insert(InsertTool.UNDERLINE))STRIKEOUT
STRIKEOUT(EditorToolAction.Insert(InsertTool.STRIKEOUT))SQUIGGLY
SQUIGGLY(EditorToolAction.Insert(InsertTool.SQUIGGLY))SIGNATURE
SIGNATURE(EditorToolAction.Insert(InsertTool.SIGNATURE))STAMP
STAMP(EditorToolAction.Insert(InsertTool.STAMP))NOTE
NOTE(EditorToolAction.Insert(InsertTool.NOTE))DRAW
DRAW(EditorToolAction.Insert(InsertTool.DRAW))SHAPE_RECTANGLE
SHAPE_RECTANGLE(EditorToolAction.Shape(ShapeKind.RECTANGLE))SHAPE_ELLIPSE
SHAPE_ELLIPSE(EditorToolAction.Shape(ShapeKind.ELLIPSE))SHAPE_LINE
SHAPE_LINE(EditorToolAction.Shape(ShapeKind.LINE))SHAPE_ARROW
SHAPE_ARROW(EditorToolAction.Shape(ShapeKind.ARROW))FORM_TEXT_FIELD
FORM_TEXT_FIELD(EditorToolAction.FormField(FormFieldKind.TEXT_FIELD))FORM_CHECK_BOX
FORM_CHECK_BOX(EditorToolAction.FormField(FormFieldKind.CHECK_BOX))FORM_RADIO_BUTTON
FORM_RADIO_BUTTON(EditorToolAction.FormField(FormFieldKind.RADIO_BUTTON))FORM_LIST_BOX
FORM_LIST_BOX(EditorToolAction.FormField(FormFieldKind.LIST_BOX))FORM_DROPDOWN
FORM_DROPDOWN(EditorToolAction.FormField(FormFieldKind.DROPDOWN))PdfEditorMode
public enum class PdfEditorModeWhich editor the host opens in — the public face of the mode model.
This is deliberately NOT the internal EditorMode. That enum carries each mode's icon, tint, toolbar contents and selection rules, all of which are implementation; a host that named it would be coupled to every one of them. The two are mapped in one place, internalMode, so a mode can be re-tooled, re-tinted or re-ordered internally without touching a published type.
VIEWER
VIEWERRead-only. No toolbar, no selection, no undo pill — just the document.
EDIT
EDITContent editing: select, move, restyle and retype what is already on the page.
FORMS
FORMSAcroForm authoring: place and configure text fields, check boxes, radios, lists and dropdowns.
ANNOTATE
ANNOTATEText markup: highlight, underline, strikethrough and squiggly over existing text.
FILL_AND_SIGN
FILL_AND_SIGNFill & Sign: signatures, stamps and free text, for a form the user is completing rather than building.
INSERT
INSERTInsert: pages, images, signatures, notes and text boxes.
DRAW
DRAWFreehand ink and the shape primitives.
PdfEditorView
public class PdfEditorView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : AbstractComposeView(context, attrs, defStyleAttr)The editor as a plain Android android.view.View, for hosts that are not written in Compose.
PdfEditorScreen is a @Composable, which is only an entry point if the host is already composing. An Activity with an XML layout, a Fragment, or a Java codebase could not call it at all without first standing up a ComposeView and learning enough Compose to do it correctly — so the SDK shipped with an entry point a large part of its audience could not use. This is that entry point: set the properties, add the view, done.
val editor = PdfEditorView(this).apply {
pdfPath = file.absolutePath
onSave = PdfBytesListener { bytes -> file.writeBytes(bytes) }
onClose = PdfEditorCloseListener { finish() }
}
setContentView(editor)From Java the same listeners are ordinary single-method interfaces.
Nothing is rendered until pdfPath is set, and every property may be changed afterwards — the editor re-composes.
In a Fragment, add this in onCreateView and set the standard disposal strategy, so the composition is torn down with the fragment's view rather than with the window:
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)pdfPath
public var pdfPath: String? by mutableStateOf(null)A WRITABLE file path to the PDF. The editor renders nothing while this is null.
password
public var password: String? by mutableStateOf(null)Password for an encrypted document; the editor prompts when this is missing or wrong.
initialMode
public var initialMode: PdfEditorMode? by mutableStateOf(null)Mode to open in. Null derives it from initialTool, else the content editor.
initialTool
public var initialTool: PdfEditorTool? by mutableStateOf(null)A tool to pre-arm, independent of the mode.
configuration
public var configuration: PdfEditorConfiguration by mutableStateOf(PdfEditorConfiguration())Modes, tools, ⋮-menu items, colour scheme, tool styles, zoom and haptics — see PdfEditorConfiguration.
onSave
public var onSave: PdfBytesListener? by mutableStateOf(null)Called with the edited PDF when the user taps Done.
onClose
public var onClose: PdfEditorCloseListener? by mutableStateOf(null)Called when the user leaves the editor (back, or the close button) — not on Done.
onSharePdf
public var onSharePdf: PdfBytesListener? by mutableStateOf(null)Intercepts the ⋮ menu's Share; unset, the editor presents the platform share sheet.
onPrint
public var onPrint: PdfBytesListener? by mutableStateOf(null)Intercepts Print; unset, the editor drives Android's own print framework.
onFlattenAndShare
public var onFlattenAndShare: PdfBytesListener? by mutableStateOf(null)Intercepts Flatten & Share — the same bytes with the form fields flattened.
onDigitallySigned
public var onDigitallySigned: PdfBytesListener? by mutableStateOf(null)Called with the signed bytes after a digital signature is applied.
onUnsavedChangesChanged
public var onUnsavedChangesChanged: UnsavedChangesListener? by mutableStateOf(null)Called whenever the dirty flag flips.
onDocumentReady
public var onDocumentReady: PdfDocumentListener? by mutableStateOf(null)The open document from code: read layers, change and add them, fill forms (main thread).
Customization
PdfEditorLocalization
public class PdfEditorLocalization(
public val language: String? = null,
public val strings: Map<String, String> = emptyMap(),
public val provider: ((key: String, english: String) -> String?)? = null,
public val layoutDirection: PdfEditorLayoutDirection = PdfEditorLayoutDirection.AUTOMATIC,
)LOCALIZATION — every word the editor shows has a stable KEY (the same key on every platform: Android, iOS, Flutter, React Native) and English as its built-in text. A host translates the editor in any of three ways, checked in this order: 1. strings — key → text (e.g. loaded from the host's own translation files or a server); 2. provider — a function asked for each key, for hosts with their own localization system; 3. Anything left untranslated stays English. toolTitles, modeTitles, actionTitles and menuItemTitles win over all three. The full key list with the English text is docs/localization/strings.json.
Placeholders in strings and provider text are positional: "Page {1} of {2}"; a translation may reorder them. A count string has two keys: <key>_one for one, <key> for the rest.
language
public val language: String? = nullThe editor's language as a BCP-47 tag ("hi", "ar", "pt-BR"). null = the app's current locale.
strings
public val strings: Map<String, String> = emptyMap()provider
public val provider: ((key: String, english: String) -> String?)? = nullAsked for every key strings doesn't have; return null to fall through.
layoutDirection
public val layoutDirection: PdfEditorLayoutDirection = PdfEditorLayoutDirection.AUTOMATICPdfEditorLayoutDirection
public enum class PdfEditorLayoutDirectionAUTOMATIC
AUTOMATICLEFT_TO_RIGHT
LEFT_TO_RIGHTRIGHT_TO_LEFT
RIGHT_TO_LEFTPdfSignaturePlacement
public enum class PdfSignaturePlacementWhere a visible signature is drawn. INVISIBLE seals the document without marking the page.
INVISIBLE
INVISIBLEBOTTOM_LEFT
BOTTOM_LEFTBOTTOM_RIGHT
BOTTOM_RIGHTTOP_LEFT
TOP_LEFTTOP_RIGHT
TOP_RIGHTPdfEditorConfiguration
public class PdfEditorConfigurationWhat the HOST app can customise about one editor: which modes and tools it offers, which ⋮-menu items it shows, its colour scheme, the tools' first-use styles, the zoom range and haptics. The Android twin of iOS PDFEditorConfiguration.
Every option only NARROWS or RESTYLES what the editor already does — nothing here reaches the engine's geometry (handles, hit slop, keyboard lift), so no setting can leave the editor in a state it was never tested in. Values outside what the editor supports are clamped, never trusted.
val config = PdfEditorConfiguration().apply {
modes = listOf(PdfEditorMode.VIEWER, PdfEditorMode.ANNOTATE, PdfEditorMode.FILL_AND_SIGN)
hiddenTools = setOf(PdfEditorTool.STAMP)
hiddenMenuItems = setOf(PdfEditorMenuItem.PRINT, PdfEditorMenuItem.RESET_TO_ORIGINAL)
colorScheme = PdfEditorColorScheme.DARK
toolDefaults.highlight = PdfEditorMarkupStyle(0xFF34C759.toInt(), opacity = 0.4f)
}
PdfEditorScreen(pdfPath, configuration = config, onSave = ::save, onClose = ::close)A plain class with settable properties (not a data class), so later releases can add options without breaking apps compiled against this one.
modes
public var modes: List<PdfEditorMode> = emptyList()The modes the Tools sheet offers, in the order given. Duplicates are dropped. Empty means every mode. A mode whose tools are ALL hidden (see hiddenTools) is dropped too, except VIEWER, which has no tools. With one mode left, the header shows its name without the mode picker.
initialMode must be one of these; otherwise the editor opens in the first one.
hiddenTools
public var hiddenTools: Set<PdfEditorTool> = emptySet()Tools removed from every mode's toolbar. ADD_TEXT appears in several modes and is hidden in all of them. An initialTool that is hidden is not armed.
hiddenMenuItems
public var hiddenMenuItems: Set<PdfEditorMenuItem> = emptySet()Items removed from the ⋮ menu. Items the document can't use (form items without a form) are hidden regardless.
colorScheme
public var colorScheme: PdfEditorColorScheme = PdfEditorColorScheme.SYSTEMLight, dark, or follow the system (default).
toolDefaults
public var toolDefaults: PdfEditorToolDefaults = PdfEditorToolDefaults()The style each tool starts with the first time it is used. Once the user picks a colour or opacity, the editor remembers their choice on this device and that wins, exactly as it does today.
minZoom
public var minZoom: Float = SUPPORTED_MIN_ZOOMThe smallest page zoom, where 1 is the page fitted to the screen. Clamped to 0.5…1: this can narrow the range but not widen it past what the editor renders crisply.
maxZoom
public var maxZoom: Float = SUPPORTED_MAX_ZOOMThe largest page zoom. Clamped to 1…3. minZoom = 1f, maxZoom = 1f turns pinch-zoom off.
haptics
public var haptics: Boolean = trueHaptic feedback on taps and snaps. Default on.
showsUsageHints
public var showsUsageHints: Boolean = trueDefault on.
interfaceFontFamily
public var interfaceFontFamily: androidx.compose.ui.text.font.FontFamily? = nullThe font family for the editor's own text — toolbar labels, the header, sheets, dialogs, menus — e.g. FontFamily(Font(R.font.brand_regular), Font(R.font.brand_medium, FontWeight.Medium)). Sizes stay the editor's; weights come from the family's own faces. Null (the default) is the system font. The document's own text is never set in it.
fonts
public var fonts: List<PdfEditorFont> = emptyList()Fonts of your own for the DOCUMENT's text, listed first in the text font picker under fontsTitle. Each must be a TrueType/OpenType file with ordinary outlines; one that isn't is skipped and logged. Applying one embeds it in the PDF, like any other font the user picks.
fontsTitle
public var fontsTitle: String = "Featured"The picker section fonts appear under.
showsStandardFonts
public var showsStandardFonts: Boolean = trueThe picker's other sections: the three standard PDF fonts (Helvetica, Times, Courier), the PDF's own embedded fonts, the device's fonts, and the fonts the user imported (with the "+" that imports one). Hide them to limit text to your fonts.
showsDocumentFonts
public var showsDocumentFonts: Boolean = trueshowsDeviceFonts
public var showsDeviceFonts: Boolean = trueallowsFontImport
public var allowsFontImport: Boolean = truenewTextFont
public var newTextFont: PdfEditorFont? = nullA font of yours for NEW text: a box the user places is set in it. Its size and colour still follow the text around it, as they always do. Validated like fonts (one that isn't usable is ignored and logged) and embedded when the first box is placed. Null (the default) matches the page's own text.
selectionColor
@ColorInt public var selectionColor: Int? = nullThe colour of the selection: the box around a selected layer, its handles' rings, the rotation knob, the text caret, the text-selection band and its grab handles, and the guide that marks alignment with the page. ARGB; always drawn opaque. Null = the accent (colors), else system blue. selectionColorDark overrides it in the dark scheme.
selectionColorDark
@ColorInt public var selectionColorDark: Int? = nullhandleFillColor
@ColorInt public var handleFillColor: Int? = nullThe handles' (and the rotation knob's) fill. Null = white.
handleShape
public var handleShape: PdfEditorHandleShape = PdfEditorHandleShape.ROUNDED_SQUAREhandleScale
public var handleScale: Float = 1fHandle and knob size, 0.75…1.5 (clamped). A mouse's reach for them follows the size; a finger's is already wider than the largest handle, and how small a layer can be resized doesn't change.
selectionBorderWidth
public var selectionBorderWidth: Float = 1.5fThe selection box's and the handles' outline, in dp: 1…3 (clamped).
rotateIcon
@DrawableRes public var rotateIcon: Int? = nullThe glyph inside the rotation knob, drawn as a template: its shape, filled with selectionColor. A drawable resource (a single-colour vector works best); it's fitted into the knob. Null = the built-in arrow.
searchHighlightColor
@ColorInt public var searchHighlightColor: Int? = nullThe wash over every search match, and over the current one (with a ring). ARGB; only the colour is used: the translucency is the editor's, so the text under a highlight always reads. Null = yellow / orange.
searchCurrentHighlightColor
@ColorInt public var searchCurrentHighlightColor: Int? = nullcolors
public var colors: PdfEditorColors = PdfEditorColors()THE EDITOR'S OWN COLOURS — its accent, the canvas around the pages, the toolbars and the panels, and what is drawn on them. Every field left null keeps the editor's own colour, so a host can change one thing (just the accent) without taking on the rest.
colors applies in both schemes; colorsDark overrides it field by field in the dark one, the same way selectionColorDark overrides selectionColor. A host that pins colorScheme needs only colors.
The editor keeps its contrast decisions: whether the chrome reads as light or dark (the status-bar icons, the chips, the shadows) follows the luminance of PdfEditorColors.toolbarBackground, so a dark brand bar on a light phone still gets white status-bar icons.
colorsDark
public var colorsDark: PdfEditorColors = PdfEditorColors()localization
public var localization: PdfEditorLocalization = PdfEditorLocalization()THE EDITOR'S LANGUAGE — every word it shows, by key: a map, a lookup function, or the host's own values-<language>/strings.xml with the pe_ names. Untranslated keys stay English; right-to-left languages flip the chrome. The key list is docs/localization/strings.json. The names below (toolTitles…) win over it. See PdfEditorLocalization.
markupColors
public var markupColors: List<Int> = emptyList()The Annotate colour row (highlight, underline, strikethrough, squiggly), ARGB, left to right. Empty = the editor's own.
inkColors
public var inkColors: List<Int> = emptyList()The Draw ink bar's colours, ARGB. Empty = the editor's own.
signatureColors
public var signatureColors: List<Int> = emptyList()The signature pad's ink colours, ARGB; the first is the default ink. Empty = the editor's own.
stamps
public var stamps: List<PdfEditorStamp> = emptyList()The Stamp tool's presets, in order. Empty = the editor's own (APPROVED, DRAFT, CONFIDENTIAL, REJECTED, FINAL and today's date). Use PdfEditorStamp.date for a stamp that reads the day it's placed.
allowsCustomStamp
public var allowsCustomStamp: Boolean = trueThe stamp picker's Custom Photo button.
fontSizes
public var fontSizes: List<Int> = emptyList()The font-size list, in points (1…400, duplicates dropped, sorted). Empty = the editor's own 8…144.
signatureMethods
public var signatureMethods: List<PdfEditorSignatureMethod> = emptyList()The signature pad's tabs, in order. Empty = all of them. E_SIGN shows only when digital signing is wired, and a list that leaves nothing falls back to DRAW.
signaturePlacement
public var signaturePlacement: PdfSignaturePlacement = PdfSignaturePlacement.BOTTOM_RIGHTWhere the e-Sign tab's Placement picker starts (the user can still change it). Default BOTTOM_RIGHT.
showsUndoRedo
public var showsUndoRedo: Boolean = trueThe floating pills along the bottom: undo / redo, the page navigator, and zoom.
showsPageNavigator
public var showsPageNavigator: Boolean = trueshowsZoomControls
public var showsZoomControls: Boolean = truetoolTitles
public var toolTitles: Map<PdfEditorTool, String> = emptyMap()Your own names for tools, e.g. mapOf(PdfEditorTool.HIGHLIGHT to "Mark"). A tool that appears in several modes (ADD_TEXT) takes the name everywhere. Blank names are ignored.
toolIcons
public var toolIcons: Map<PdfEditorTool, Int> = emptyMap()Your own icons for tools, as drawable resources (vector drawables work best). Drawn as a tinted template at 21dp — blue when armed, like the built-in glyphs — so use a single-colour shape.
modeTitles
public var modeTitles: Map<PdfEditorMode, String> = emptyMap()Your own names for modes: the header and the Tools sheet.
modeIcons
public var modeIcons: Map<PdfEditorMode, Int> = emptyMap()Your own icons for modes in the Tools sheet, drawn as a template on the mode's coloured tile.
menuItemTitles
public var menuItemTitles: Map<PdfEditorMenuItem, String> = emptyMap()Your own names and icons for the ⋮ menu's items.
menuItemIcons
public var menuItemIcons: Map<PdfEditorMenuItem, Int> = emptyMap()headerIcons
public var headerIcons: Map<PdfEditorHeaderButton, Int> = emptyMap()Your own icons for the header's buttons, drawn as a template.
actionTitles
public var actionTitles: Map<PdfEditorAction, String> = emptyMap()Your own names for the SUB-TOOLS — the controls that appear once something is selected (the property bar's Edit, Color, Font, Crop, Cut, Delete…), the floating Edit · Duplicate · Delete menu, and the page panel's actions. A name applies wherever that action appears. Blank names are ignored.
actionIcons
public var actionIcons: Map<PdfEditorAction, Int> = emptyMap()Your own icons for sub-tools, as drawable resources drawn as tinted templates, like toolIcons. Colour wells, steppers and the size button show a value rather than an icon, so an icon there is ignored.
hiddenActions
public var hiddenActions: Set<PdfEditorAction> = emptySet()Sub-tools removed wherever they appear. An action you hide is simply not offered — nothing replaces it.
actionOrder
public var actionOrder: List<PdfEditorAction> = emptyList()Listed sub-tools first, in this order, in every property bar that has them; the rest keep the editor's order. The bar's group dividers follow the new order.
customTools
public var customTools: Map<PdfEditorMode, List<PdfEditorCustomAction>> = emptyMap()A tap commits any edit in progress and calls the handler; the editor does nothing else. A mode with only custom tools still shows its toolbar — even VIEWER.
customMenuItems
public var customMenuItems: List<PdfEditorCustomAction> = emptyList()⋮ menu items of your own, after the built-in items (reorder with menuOrder).
toolOrder
public var toolOrder: Map<PdfEditorMode, List<PdfEditorToolbarItem>> = emptyMap()The order of a mode's toolbar. Listed items come first, in this order; everything else the mode has follows in its usual order, so ordering never hides a tool (that's hiddenTools). A tool the mode doesn't carry is ignored: tools can be reordered within a mode, not moved to another.
toolOrder = mapOf(PdfEditorMode.FILL_AND_SIGN to listOf(
PdfEditorToolbarItem.Custom("approve"), PdfEditorToolbarItem.Tool(PdfEditorTool.SIGNATURE)))menuOrder
public var menuOrder: List<PdfEditorMenuEntry> = emptyList()The order of the ⋮ menu, with the same rule: listed items first, the rest after in the usual order.
PdfEditorConfiguration.Companion
public companion objectSUPPORTED_MIN_ZOOM
public const val SUPPORTED_MIN_ZOOM: Float = ZOOM_MINThe widest zoom range the editor supports.
SUPPORTED_MAX_ZOOM
public const val SUPPORTED_MAX_ZOOM: Float = ZOOM_MAXfromOptions
@JvmStatic public fun fromOptions(options: Map<String, Any?>): PdfEditorConfiguration =A configuration from plain values — the shape the Flutter and React Native packages send over their channels. Keys are the option names (modes, hiddenTools, selectionColor, …); names are the cross-platform camelCase ones (fillAndSign, formDropdown, sharePdf); colours are #RRGGBB strings; zoom is minZoom / maxZoom; fonts are file paths. The iOS SDK reads the same keys (PDFEditorConfiguration(options:)). Anything unknown is skipped and logged, never fatal, so a newer package still opens the editor on an older SDK. Icons and custom actions don't cross a channel.
modeNamed
@JvmStatic public fun modeNamed(name: String): PdfEditorMode? = when (name)The mode for a cross-platform name: viewer, edit, forms, annotate, fillAndSign, insert, draw.
toolNamed
@JvmStatic public fun toolNamed(name: String): PdfEditorTool? =The tool for a cross-platform name (addText, formDropdown, …): the entry's name in camelCase.
actionNamed
@JvmStatic public fun actionNamed(name: String): PdfEditorAction? =The sub-tool for a cross-platform name (editText, fontSize, rotatePageLeft, …).
menuItemNamed
@JvmStatic public fun menuItemNamed(name: String): PdfEditorMenuItem? =The ⋮ item for a cross-platform name (search, sharePdf, flattenDocument, …).
PdfEditorFont
public class PdfEditorFontA font file of the host's, for PdfEditorConfiguration.fonts.
PdfEditorColors
public class PdfEditorColors(
@ColorInt public var accent: Int? = null,
@ColorInt public var onAccent: Int? = null,
@ColorInt public var canvasBackground: Int? = null,
@ColorInt public var toolbarBackground: Int? = null,
@ColorInt public var toolbarForeground: Int? = null,
@ColorInt public var secondaryForeground: Int? = null,
@ColorInt public var panelBackground: Int? = null,
@ColorInt public var destructive: Int? = null,
)The editor's colours, for PdfEditorConfiguration.colors / PdfEditorConfiguration.colorsDark. ARGB; null keeps the editor's own. Alpha is ignored except where a colour is naturally translucent (the canvas is opaque).
accent
@ColorInt public var accent: Int? = nullButtons, the armed tool, Done, switches, links, the current page — anything that says "this one".
onAccent
@ColorInt public var onAccent: Int? = nullText and glyphs drawn ON the accent (Done's check, a selected chip's label). Default white.
canvasBackground
@ColorInt public var canvasBackground: Int? = nullBehind and around the pages.
toolbarBackground
@ColorInt public var toolbarBackground: Int? = nullThe header, the mode toolbar, the property bars and the floating pills.
toolbarForeground
@ColorInt public var toolbarForeground: Int? = nullIcons and labels on those bars, and the primary text in panels and menus.
secondaryForeground
@ColorInt public var secondaryForeground: Int? = nullCaptions, hints, placeholders, inactive labels. Default: toolbarForeground at reduced strength.
panelBackground
@ColorInt public var panelBackground: Int? = nullSheets, dialogs and menus. Default: toolbarBackground, or the editor's own.
destructive
@ColorInt public var destructive: Int? = nullDelete and other destructive actions.
copy
public fun copy(): PdfEditorColors = PdfEditorColors(accent, onAccent, canvasBackground, toolbarBackground, toolbarForeground, secondaryForeground, panelBackground, destructive)A copy, so the editor never sees the host mutate the object it passed.
PdfEditorStamp
public class PdfEditorStamp(
public val text: String,
@ColorInt public val color: Int,
)A rubber stamp for PdfEditorConfiguration.stamps: its text and its ink.
text
public val text: Stringcolor
@ColorInt public val color: IntisDate
public val isDate: Boolean get() = text == DATEA stamp that reads the date it's placed, e.g. "OCT 5, 2026".
PdfEditorStamp.Companion
public companion objectdate
@JvmStatic public fun date(@ColorInt color: Int): PdfEditorStamp = PdfEditorStamp(DATE, color)Today's date, formatted for the device's locale when the stamp is placed.
PdfEditorSignatureMethod
public enum class PdfEditorSignatureMethodThe signature pad's tabs, for PdfEditorConfiguration.signatureMethods.
DRAW
DRAWTYPE
TYPEIMAGE
IMAGEE_SIGN
E_SIGNPdfEditorCustomAction
public class PdfEditorCustomAction(
public val id: String,
public val title: String,
@DrawableRes public val icon: Int? = null,
public val handler: PdfEditorActionHandler,
)A button of the host's own, in a mode's toolbar or the ⋮ menu.
id
public val id: StringUnique among your custom actions; PdfEditorConfiguration.toolOrder / menuOrder refer to it by this.
title
public val title: Stringicon
@DrawableRes public val icon: Int? = nullA drawable, drawn as a tinted template. Null shows a generic glyph in the toolbar and none in the menu.
handler
public val handler: PdfEditorActionHandlerCalled on the main thread, after any edit in progress was committed.
PdfEditorActionHandler
public fun interface PdfEditorActionHandlerWhat a custom action runs. A single-method interface, so Java passes a lambda.
onAction
public fun onAction(context: PdfEditorActionContext)PdfEditorPdfCallback
public fun interface PdfEditorPdfCallbackReceives the document's bytes, or null if the export failed.
onResult
public fun onResult(pdf: ByteArray?)PdfEditorActionContext
public class PdfEditorActionContextWhat a custom action's handler can see of the document.
pageIndex
public val pageIndex: IntThe page on screen, 0-based, and the page count.
pageCount
public val pageCount: IntcurrentPdf
public fun currentPdf(callback: PdfEditorPdfCallback): Unit = exporter(callback)The document as it stands, every edit included, as PDF bytes — delivered to callback on the main thread (the export runs on the render thread). Nothing is saved and onSave is not called; this is a copy.
PdfEditorToolbarItem
public sealed interface PdfEditorToolbarItemAn entry in PdfEditorConfiguration.toolOrder: a built-in tool, or one of your custom tools by id.
PdfEditorToolbarItem.Tool
public data class Tool(val tool: PdfEditorTool) : PdfEditorToolbarItemPdfEditorToolbarItem.Custom
public data class Custom(val id: String) : PdfEditorToolbarItemPdfEditorMenuEntry
public sealed interface PdfEditorMenuEntryAn entry in PdfEditorConfiguration.menuOrder: a built-in ⋮ item, or one of your custom items by id.
PdfEditorMenuEntry.Item
public data class Item(val item: PdfEditorMenuItem) : PdfEditorMenuEntryPdfEditorMenuEntry.Custom
public data class Custom(val id: String) : PdfEditorMenuEntryPdfEditorHeaderButton
public enum class PdfEditorHeaderButtonThe header's buttons.
BACK
BACKPAGES
PAGESMORE
MOREDONE
DONEPdfEditorAction
public enum class PdfEditorActionA sub-tool: a control that appears once something is selected — in the property bar that replaces the mode toolbar, in the floating menu over the selection — or on a page in the page panel. Customise them with PdfEditorConfiguration.actionTitles, actionIcons, hiddenActions and actionOrder.
MULTI_SELECT
MULTI_SELECTMulti: add to / remove from a multi-layer selection.
EDIT_TEXT
EDIT_TEXTEdit a text layer's words (bar and menu).
TEXT_COLOR
TEXT_COLORA text layer's colour well.
FONT
FONTThe font picker.
TEXT_STYLE
TEXT_STYLEBold · Italic · Underline · Strikethrough (one group; its title is the caption under it).
FONT_SIZE
FONT_SIZEThe font-size button.
OPACITY
OPACITYThe opacity stepper.
STROKE_COLOR
STROKE_COLORA shape's outline colour well.
FILL_COLOR
FILL_COLORA shape's or path's fill colour well.
STROKE_WIDTH
STROKE_WIDTHA shape's outline width stepper.
EDIT_NOTE
EDIT_NOTEEdit a sticky note (bar and menu).
NOTE_COLOR
NOTE_COLORA sticky note's card colour well.
RESIGN
RESIGNDraw a placed signature again (bar and menu).
REPLACE_IMAGE
REPLACE_IMAGEReplace an image (bar and menu).
CROP
CROPCrop an image or signature.
PLAY_SOUND
PLAY_SOUNDPlay / pause / replay a sound note.
LINK
LINKLink a layer to a URL or page.
CUT
CUTCOPY
COPYDUPLICATE
DUPLICATEDuplicate a layer or form field (context menu).
DELETE
DELETEDelete a layer or form field (bar and menu).
FORM_FILL
FORM_FILLA form field's menu: fill it in ("Edit Text", "Toggle" or "Choose…", by the field's kind).
FORM_OPTIONS
FORM_OPTIONSA list or dropdown field's Options.
FORM_RADIO_GROUP
FORM_RADIO_GROUPA radio button's Group.
FORM_COLORS
FORM_COLORSA form field's Color submenu (fill, border, text).
FORM_BORDER_WIDTH
FORM_BORDER_WIDTHA form field's Border Width submenu.
PASTE
PASTEPaste, on the empty page's menu.
ROTATE_PAGE_LEFT
ROTATE_PAGE_LEFTThe page panel's actions on a page.
ROTATE_PAGE_RIGHT
ROTATE_PAGE_RIGHTDUPLICATE_PAGE
DUPLICATE_PAGEINSERT_BLANK_PAGE
INSERT_BLANK_PAGEDELETE_PAGE
DELETE_PAGEPdfEditorMenuItem
public enum class PdfEditorMenuItemThe ⋮ (More) menu's items.
SEARCH
SEARCHMANAGE_PAGES
MANAGE_PAGESSHARE_PDF
SHARE_PDFPRINT
PRINTFLATTEN_AND_SHARE
FLATTEN_AND_SHAREFLATTEN_DOCUMENT
FLATTEN_DOCUMENTAndroid only: bake the form into the page content of the document itself.
RESET_FORM
RESET_FORMRESET_TO_ORIGINAL
RESET_TO_ORIGINALPdfEditorColorScheme
public enum class PdfEditorColorSchemeThe editor's colour scheme.
SYSTEM
SYSTEMLIGHT
LIGHTDARK
DARKPdfEditorHandleShape
public enum class PdfEditorHandleShapeThe shape of the selection handles.
ROUNDED_SQUARE
ROUNDED_SQUARECIRCLE
CIRCLESQUARE
SQUAREPdfEditorMarkupStyle
public class PdfEditorMarkupStyle(
@ColorInt public val color: Int,
public val opacity: Float = 1f,
)A text-markup tool's first-use style. color is ARGB (its alpha is ignored); opacity is clamped to 0.1…1.
color
@ColorInt public val color: Intopacity
public val opacity: Float = 1fPdfEditorInkStyle
public class PdfEditorInkStyle(
@ColorInt public val color: Int,
public val width: Float = 5f,
public val opacity: Float = 1f,
)width is clamped to 1…30 points, opacity to 0.1…1.
color
@ColorInt public val color: Intwidth
public val width: Float = 5fopacity
public val opacity: Float = 1fPdfEditorToolDefaults
public class PdfEditorToolDefaultsThe defaults are the editor's own.
highlight
public var highlight: PdfEditorMarkupStyle = PdfEditorMarkupStyle(
WARM_YELLOW,
opacity = 0.5f,
)A see-through wash, so the text reads through it.
underline
public var underline: PdfEditorMarkupStyle = PdfEditorMarkupStyle(WARM_YELLOW)strikeout
public var strikeout: PdfEditorMarkupStyle = PdfEditorMarkupStyle(WARM_YELLOW)squiggly
public var squiggly: PdfEditorMarkupStyle = PdfEditorMarkupStyle(WARM_YELLOW)ink
public var ink: PdfEditorInkStyle = PdfEditorInkStyle(0xFF000000.toInt())Signing
PdfCmsSigner
public fun interface PdfCmsSignerProduces a detached PKCS#7/CMS (DER) over a 32-byte SHA-256 digest, or null to abort the signing.
The engine NEVER sees a private key: it builds the /ByteRange, hashes the covered bytes, and asks for a signature over that digest. Which is what makes a remote signer, a smart card or an HSM possible — the key never has to be on the device at all.
signDigest
public fun signDigest(digest: ByteArray): ByteArray?PdfEditorSigning
public object PdfEditorSigningSign PDFs WITHOUT the editor.
Signing was reachable only by opening a document in the editor, switching mode and driving a sheet — so a host that wanted to seal a batch of finished documents, or to sign one on a server-ish background path, had no API at all and the capability may as well not have existed. Nothing here needs a window, a GL context or an open editor: it is bytes in, bytes out.
The signature covers the bytes you pass. If a document is open in an editor, save it first and sign what you get back — signing a stale copy produces a valid signature over the wrong document.
hasDeviceIdentity
public val hasDeviceIdentity: Boolean get() = DigitalId.existing() != nullTrue when this device already holds the SDK's self-signed identity (see createDeviceIdentity).
deviceIdentityName
public val deviceIdentityName: String? get() = DigitalId.existing()?.signerNameThe common name on the device identity, or null when there is none.
createDeviceIdentity
public fun createDeviceIdentity(
name: String,
organization: String = "",
email: String = "",
): Boolean =Create (or REPLACE) the device's self-signed identity in the AndroidKeyStore.
Signatures already made with it stay verifiable — they carry their certificate.
signWithDeviceIdentity
public fun signWithDeviceIdentity(
pdfBytes: ByteArray,
signerName: String,
reason: String = "I approve this document",
location: String = "",
email: String = "",
organization: String = "",
placement: PdfSignaturePlacement = PdfSignaturePlacement.INVISIBLE,
pageIndex: Int = 0,
pageWidthPt: Float = 0f,
pageHeightPt: Float = 0f,
onFailure: ((String) -> Unit)? = null,
): ByteArray?Sign with the device identity, creating one if this device has none.
Returns the signed PDF, or null with the reason in onFailure. BLOCKING and pure byte work — call it off the main thread.
sign
public fun sign(
pdfBytes: ByteArray,
signerName: String,
reason: String = "I approve this document",
location: String = "",
contact: String = "",
placement: PdfSignaturePlacement = PdfSignaturePlacement.INVISIBLE,
pageIndex: Int = 0,
pageWidthPt: Float = 0f,
pageHeightPt: Float = 0f,
signer: PdfCmsSigner,
onFailure: ((String) -> Unit)? = null,
): ByteArray?Sign with YOUR OWN signer — an HSM, a smart card, a remote signing service.
signer receives the SHA-256 digest of the covered bytes and returns a detached CMS. Blocking; call it off the main thread. A visible placement needs the page's size in points, which the engine cannot infer from bytes alone; pass 0 for both to fall back to an invisible signature rather than drawing a box at a guessed size.
verify
public fun verify(pdfBytes: ByteArray): List<PdfSignatureReport>What the signatures in a document amount to: who signed, when, and whether the bytes still match.
MATHEMATICAL verification only — the digest, the byte range, the key in the embedded certificate. It does NOT evaluate whether that certificate is trusted, so a self-signed signature and one from a public CA are reported the same way.
PdfSignatureReport
public data class PdfSignatureReport(
public val signerName: String,
public val reason: String,
public val signedAt: String,
public val intact: Boolean,
public val coversWholeFile: Boolean,
public val detail: String,
)One signature's verification result. See PdfEditorSigning.verify.
signerName
public val signerName: Stringreason
public val reason: StringsignedAt
public val signedAt: Stringintact
public val intact: BooleanThe signed bytes still hash to what the signature says.
coversWholeFile
public val coversWholeFile: BooleanThe signature's /ByteRange covers the WHOLE file — false means something was appended after it.
detail
public val detail: StringDocument API
PdfDocumentBridgeException
public class PdfDocumentBridgeException(
public val code: String,
message: String,
) : Exception(message)Why a bridged document call failed.
PdfRect
public data class PdfRect(
val x: Float,
val y: Float,
val width: Float,
val height: Float,
)A rectangle in page points, top-left origin.
PdfLayer
public data class PdfLayer(
val page: Int,
val id: Int,
val kind: Kind,
val frame: PdfRect,
val rotation: Float,
val opacity: Float,
val zIndex: Int,
val link: String?,
val text: String?,
val fontName: String?,
val fontSize: Float?,
val isBold: Boolean,
val isItalic: Boolean,
val isUnderlined: Boolean,
val isStruckThrough: Boolean,
val isFontEmbedded: Boolean,
val isSymbolic: Boolean,
val textColor: Int?,
val highlightColor: Int?,
val pixelWidth: Int?,
val pixelHeight: Int?,
val note: String?,
val noteColor: Int?,
val noteTextColor: Int?,
val shape: Shape?,
val fillColor: Int?,
val strokeColor: Int?,
val strokeWidth: Float?,
)One layer of a page, as data. Read again after a change — a layer's properties are a snapshot.
PdfLayer.Kind
public enum class KindTEXT
TEXTIMAGE
IMAGENOTE
NOTESIGNATURE
SIGNATUREDRAWING
DRAWINGSOUND
SOUNDSHAPE
SHAPEVECTOR
VECTORPdfLayer.Shape
public enum class ShapeRECTANGLE
RECTANGLEELLIPSE
ELLIPSELINE
LINEARROW
ARROWPdfSearchMatch
public data class PdfSearchMatch(
val page: Int,
val rects: List<PdfRect>,
)PdfFormField
public data class PdfFormField(
val name: String,
val kind: Kind,
val page: Int,
val frame: PdfRect,
val value: String,
val isChecked: Boolean?,
val exportValue: String?,
val options: List<String>,
val isReadOnly: Boolean,
)A form field of the document.
PdfFormField.Kind
public enum class KindTEXT
TEXTCHECKBOX
CHECKBOXRADIO
RADIOCOMBOBOX
COMBOBOXLISTBOX
LISTBOXBUTTON
BUTTONSIGNATURE
SIGNATUREUNKNOWN
UNKNOWNPdfMetadataKey
public enum class PdfMetadataKey(internal val key: String)TITLE
TITLE("Title")AUTHOR
AUTHOR("Author")SUBJECT
SUBJECT("Subject")KEYWORDS
KEYWORDS("Keywords")CREATOR
CREATOR("Creator")PRODUCER
PRODUCER("Producer")PdfFontFamily
public enum class PdfFontFamilyThe built-in families every PDF reader has.
SANS
SANSSERIF
SERIFMONO
MONOPdfZOrder
public enum class PdfZOrderTO_BACK
TO_BACKBACKWARD
BACKWARDFORWARD
FORWARDTO_FRONT
TO_FRONTPdfMarkupKind
public enum class PdfMarkupKindHIGHLIGHT
HIGHLIGHTSTRIKEOUT
STRIKEOUTSQUIGGLY
SQUIGGLYPdfImageKind
public enum class PdfImageKindWhat an image layer is to the editor: a signature, a hand drawing and a stamp are images it knows by kind.
PHOTO
PHOTONOTE
NOTESIGNATURE
SIGNATUREDRAWING
DRAWINGPdfFormFieldKind
public enum class PdfFormFieldKindTEXT
TEXTCHECKBOX
CHECKBOXRADIO
RADIOLIST_BOX
LIST_BOXDROPDOWN
DROPDOWNPdfTextResult
public enum class PdfTextResultHow a text replacement went.
REPLACED
REPLACEDReplaced, and it fits where the old text was.
OVERFLOW
OVERFLOWReplaced, but taller than the old text (it may run into what is below it).
PdfDocumentException
public sealed class PdfDocumentException(message: String) : Exception(message)Why a document call failed.
PdfDocumentException.CannotOpen
public class CannotOpen : PdfDocumentException("cannot open the PDF")The data is not a PDF this engine can open (or the password is wrong).
PdfDocumentException.NotFound
public class NotFound : PdfDocumentException("not found")No layer, page or field by that address (it may have been deleted — read the layers again).
PdfDocumentException.UnsupportedGlyphs
public class UnsupportedGlyphs : PdfDocumentException("no font can draw this text")No font can draw some of the characters; NOTHING was changed. Give the editor a font that can.
PdfDocumentException.Failed
public class Failed(what: String) : PdfDocumentException(what)The engine refused the change (wrong kind of layer, bad value, …).
PdfDocumentEditor
public class PdfDocumentEditorconstructor
public constructor(
bytes: ByteArray,
password: String? = null,
) : this(open(bytes, password), null)Open a PDF headless (no UI), with the system's fonts for every script.
constructor
public constructor(
file: File,
password: String? = null,
) : this(file.readBytes(), password)Open a PDF file headless (no UI).
pageCount
public val pageCount: Int get() = op(0)pageSize
public fun pageSize(page: Int): Pair<Float, Float>The page's size in points (as displayed, i.e. after its rotation).
save
public fun save(): ByteArrayThe edited PDF.
metadata
public fun metadata(key: PdfMetadataKey): String = str(4, null, key.key)setMetadata
public fun setMetadata(key: PdfMetadataKey, value: String)Written into the file save produces.
text
public fun text(page: Int): String = readThe page's plain text.
search
public fun search(
query: String,
caseSensitive: Boolean = false,
): List<PdfSearchMatch>Every match of query in the document.
renderPage
public fun renderPage(page: Int, width: Int, height: Int): Bitmap?The page drawn into a width×height pixel bitmap (a thumbnail, a preview, a server-side render).
canUndo
public val canUndo: Boolean get() = live?.canUndo ?: (op(30) == 1)canRedo
public val canRedo: Boolean get() = live?.canRedo ?: (op(31) == 1)undo
public fun undo(): Boolean = live?.undo() ?: (op(28) == 1)Undo the last change, the user's or this API's. A layer that comes back gets a NEW id — read the layers again.
redo
public fun redo(): Boolean = live?.redo() ?: (op(29) == 1)insertBlankPage
public fun insertBlankPage(
index: Int,
width: Float = 0f,
height: Float = 0f,
)Insert a blank page at index (a zero size takes the neighbouring page's).
deletePage
public fun deletePage(index: Int)movePage
public fun movePage(from: Int, to: Int)duplicatePage
public fun duplicatePage(index: Int)rotatePage
public fun rotatePage(index: Int, clockwise: Boolean = true)importPages
public fun importPages(
bytes: ByteArray,
password: String? = null,
pages: List<Int>? = null,
index: Int? = null,
)Copy pages (all when null) of another PDF into this one at index (null = the end). This starts the undo history afresh, as a flatten does, and layer ids must be read again.
extractPages
public fun extractPages(pages: List<Int>): ByteArraypages of this document as a new PDF.
layers
public fun layers(page: Int): List<PdfLayer>Every layer of the page, in reading order (top to bottom, then left to right) for a page read the first time.
textBlocks
public fun textBlocks(page: Int): List<PdfLayer> = layers(page).filterlayer
public fun layer(layer: PdfLayer): PdfLayer =The layer as it is now.
image
public fun image(layer: PdfLayer): Bitmap? =The picture of an image layer, at its own pixel size.
sound
public fun sound(layer: PdfLayer): ByteArray? =The audio of a sound layer.
setText
public fun setText(
layer: PdfLayer,
text: String,
shrinkToFit: Boolean = false,
): PdfTextResultReplace a text layer's text, keeping its font, size, colour and position. A paragraph re-wraps at its own width; a single line may grow to the page margin. shrinkToFit lowers the size (to half at most) until the text is no taller than before. Any script works: the system's fonts fill in what the layer's font lacks.
setFontSize
public fun setFontSize(
layer: PdfLayer,
points: Float,
): Unit = change(layer, "font size", 3, f = floats(points))setFont
public fun setFont(
layer: PdfLayer,
family: PdfFontFamily,
bold: Boolean = false,
italic: Boolean = false,
): Unit =setFont
public fun setFont(
layer: PdfLayer,
data: ByteArray,
name: String,
): Unit = change(layer, "font", 5, s = name, d = data)Embed a font of your own (TTF/OTF bytes) and set the layer in it.
setTextStyle
public fun setTextStyle(
layer: PdfLayer,
bold: Boolean? = null,
italic: Boolean? = null,
): Unit =Bold / italic of the current family; null leaves that one as it is.
setUnderline
public fun setUnderline(
layer: PdfLayer,
on: Boolean,
): Unit = change(layer, "underline", 7, i = intArrayOf(0, b(on)))setStrikethrough
public fun setStrikethrough(
layer: PdfLayer,
on: Boolean,
): Unit = change(layer, "strikethrough", 7, i = intArrayOf(1, b(on)))setFillColor
public fun setFillColor(
layer: PdfLayer,
color: Int,
): Unit = change(layer, "colour", 8, i = intArrayOf(0, rgba(color)))Text colour, or a shape's fill (ARGB).
setStrokeColor
public fun setStrokeColor(
layer: PdfLayer,
color: Int,
): Unit = change(layer, "stroke colour", 8, i = intArrayOf(1, rgba(color)))setStrokeWidth
public fun setStrokeWidth(
layer: PdfLayer,
points: Float,
): Unit = change(layer, "stroke width", 9, f = floats(points))setOpacity
public fun setOpacity(
layer: PdfLayer,
opacity: Float,
): Unit = change(layer, "opacity", 10, f = floats(opacity))setFrame
public fun setFrame(layer: PdfLayer, frame: PdfRect): Unit =Move and resize (text scales uniformly).
setRotation
public fun setRotation(
layer: PdfLayer,
degrees: Float,
): Unit = change(layer, "rotation", 12, f = floats(degrees))Degrees, clockwise as seen.
setZOrder
public fun setZOrder(
layer: PdfLayer,
order: PdfZOrder,
): Unit = change(layer, "z-order", 13, i = intArrayOf(order.ordinal))setLink
public fun setLink(
layer: PdfLayer,
url: String?,
): Unit = change(layer, "link", 14, s = url)null removes the link.
setSound
public fun setSound(
layer: PdfLayer,
audio: ByteArray,
name: String,
): Unit = change(layer, "sound", 15, s = name, d = audio)replaceImage
public fun replaceImage(layer: PdfLayer, image: Bitmap)Swap an image layer's picture, keeping its frame and kind.
setMarkup
public fun setMarkup(
layer: PdfLayer,
kind: PdfMarkupKind,
color: Int,
): Unit =Mark a whole text layer up.
removeMarkup
public fun removeMarkup(layer: PdfLayer): Unit = change(layer, "markup", 17, i = intArrayOf(0, 0))Remove a text layer's highlight / strikeout / squiggly.
delete
public fun delete(layer: PdfLayer): Unit = change(layer, "delete", 18)duplicate
public fun duplicate(
layer: PdfLayer,
dx: Float = 12f,
dy: Float = 12f,
): PdfLayer =A copy offset by dx, dy points.
copy
public fun copy(
layer: PdfLayer,
toPage: Int,
x: Float,
y: Float,
): PdfLayerA copy on another page, its top-left at (x, y) there.
addText
public fun addText(
text: String,
page: Int,
x: Float,
y: Float,
fontSize: Float = 14f,
color: Int = 0xFF000000.toInt(),
family: PdfFontFamily = PdfFontFamily.SANS,
): PdfLayer = created(page)A text layer with its top-left at (x, y). color is ARGB.
addImage
public fun addImage(
image: Bitmap,
page: Int,
frame: PdfRect,
kind: PdfImageKind = PdfImageKind.PHOTO,
note: String? = null,
): PdfLayerAn image layer filling frame. A signature, a hand drawing or a stamp is an image of that kind.
addShape
public fun addShape(
shape: PdfLayer.Shape,
page: Int,
x0: Float,
y0: Float,
x1: Float,
y1: Float,
fill: Int = 0,
stroke: Int = 0xFF000000.toInt(),
strokeWidth: Float = 2f,
): PdfLayer = created(page)A rectangle or ellipse filling the rect from start to end, or a line / arrow from start to end (ARGB).
markupText
public fun markupText(
page: Int,
x0: Float,
y0: Float,
x1: Float,
y1: Float,
kind: PdfMarkupKind = PdfMarkupKind.HIGHLIGHT,
color: Int = 0xFFFFE44D.toInt(),
)Mark up the text between two points of the page, as a drag with the tool would.
formFields
public fun formFields(): List<PdfFormField>setFormValue
public fun setFormValue(value: String, field: String)Fill a field: its text, an option's label, "true"/"false" for a check box, or the export value of the radio button to turn on.
fillForm
public fun fillForm(values: Map<String, String>)Fill several fields at once.
addFormField
public fun addFormField(
kind: PdfFormFieldKind,
page: Int,
frame: PdfRect,
name: String? = null,
options: List<String> = emptyList(),
): StringA new field; returns its name (name, or one the editor made up). Radios that share a name are one set.
deleteFormField
public fun deleteFormField(name: String)Remove every widget called name (a whole radio set).
resetForm
public fun resetForm()flattenForm
public fun flattenForm()Bake the fields into the pages (their values stay, they stop being editable).
PdfDocumentListener
public fun interface PdfDocumentListenerCalled with the open document once it is on screen (see PdfEditorView.onDocumentReady).
onDocumentReady
public fun onDocumentReady(document: PdfDocumentEditor)SDK, licensing and callbacks
PdfEditorSdk
public object PdfEditorSdkThe SDK's PUBLIC surface — the only types a host application is meant to name.
Everything else in com.pdfsdk.editor is internal. That is a deliberate line, not tidiness: the module's own model types (EditorMode, InsertTool, EditorToolAction, the controller, the engine) carry Compose icons, colours, core integers and JNI handles, and every one of them is expected to move as the editor grows. Anything a host can name is anything it can be broken by.
The line is enforced by explicitApi() plus internal — not by documentation — so publishing a new type by accident fails the build rather than becoming a promise the SDK did not intend to make.
VERSION
public const val VERSION: String = "2.4.1"The SDK's own version, independent of the host's versionName.
Worth having for the reason recorded in the iOS notes: a crash report shows the HOST's version, so with nothing else to go on a bug had to be identified from symbolicated line numbers. A host that logs this alongside its own build stamps the answer into the report instead.
ONE version across every platform SDK, which is why this jumped 1.0.0 → 1.13.0 rather than counting up from its own first release. Keep this equal to PDFEditorSDK.version (iOS) and the web package's version; the published Maven coordinate is derived from this constant, never typed twice.
isSupportedDevice
public val isSupportedDevice: Boolean get() = PdfEditorEngine.isAvailableWhether the native engine loaded — false when the AAR shipped without a slice for this ABI, or the .so was stripped by an over-eager packaging rule.
A host does not have to check this: PdfEditorScreen renders its own "unsupported device" state rather than throwing. It is exposed so a host CAN check first and route around the editor entirely (hide the Edit button, fall back to its own viewer) instead of presenting a dead end.
setCjkFallbackFont
public fun setCjkFallbackFont(fontData: ByteArray?)A pan-CJK font the engine falls back to when a document names a CJK face it does not embed and the device has no renderable one either. Pass the raw TTF/OTF bytes; pass null to clear.
Bundling one is the host's call because it is megabytes of APK. Without it, such a document still opens — the glyphs are simply missing, exactly as they were before this was set.
setLicenseKey
public fun setLicenseKey(key: String?): PdfEditorLicenseSet (or with null clear) this app's license key, once, at startup — Application.onCreate is the place. Returns the resulting verdict.
The engine checks the key against the package this app is INSTALLED as (read from where the package manager put the SDK's native library, not from anything the app declares), so a key only unlocks the apps it names. WITHOUT A VALID KEY THE EDITOR IS LOCKED: PdfEditorScreen shows "not licensed" with the reason instead of the document, and nothing opens, saves or signs. license says which, and why.
class App : Application() {
override fun onCreate() {
super.onCreate()
PdfEditorSdk.setLicenseKey(BuildConfig.PDFSDK_LICENSE_KEY)
}
}ONLINE keys (issued with a license server) are confirmed with the vendor's server so the vendor can suspend and resume a license by hand: the SDK restores the last confirmation saved on this device here, asks the server in the background, and asks again when the app comes back to the foreground. On a first launch the verdict may be PdfEditorLicense.Status.VERIFICATION_REQUIRED until the server answers (an editor opened meanwhile waits).
refreshLicense
public fun refreshLicense(): PdfEditorLicenseOnline keys: ask the license server now and return the verdict afterwards (the SDK also does it at launch and when the app returns to the foreground). Blocks for up to 20 seconds — call it off the main thread. Offline keys return at once.
addLicenseListener
public fun addLicenseListener(listener: (PdfEditorLicense) -> Unit)Called (on any thread) whenever the verdict changes — after setLicenseKey and after an online confirmation.
removeLicenseListener
public fun removeLicenseListener(listener: (PdfEditorLicense) -> Unit)license
public val license: PdfEditorLicenseThe license verdict the SDK is running under.
chromeScale
public var chromeScale: FloatMultiplier for the size of the editor's own chrome — toolbars, pills, handles. 0 (the default) means "derive it from the window", which gives a phone 1.0 and a tablet 1.35.
Set this only to override that derivation; it is clamped to 0.5..3.0. It does NOT scale the document.
PdfEditorLicense
public data class PdfEditorLicense(
val status: Status,
val isLicensed: Boolean,
val reason: String,
val licensee: String,
val licenseId: String,
val plan: String,
val expires: String?,
val updatesUntil: String?,
val platform: String,
val identity: String,
val isOnline: Boolean = false,
val paymentDue: Boolean = false,
val confirmedUntilMillis: Long = 0L,
val message: String = "",
)The license verdict — see PdfEditorSdk.setLicenseKey.
@property isLicensed true when the editor may open documents (Status.VALID or Status.DEVELOPMENT). @property reason one sentence explaining status; log it. @property expires YYYY-MM-DD, or null for a key that does not expire. @property updatesUntil YYYY-MM-DD: the last SDK release date the key covers, or null for every release. @property identity the package name the SDK checked the key against. @property isOnline an online key (confirmed with the vendor's license server). @property paymentDue online keys: the vendor marked the payment overdue. It still works. @property confirmedUntilMillis online keys: until when the current confirmation lets the app work offline (0 = none). @property message online keys: the vendor's note to the developer.
PdfEditorLicense.Status
public enum class StatusVALID
VALIDThe key covers this app.
DEVELOPMENT
DEVELOPMENTA valid key on a development host (only the web SDK uses this).
UNLICENSED
UNLICENSEDNo key has been set. Locked.
INVALID
INVALIDMalformed, altered, or not issued by the vendor. Locked.
EXPIRED
EXPIREDPast its expiry date. Locked.
WRONG_APP
WRONG_APPDoes not name this app's package. Locked.
WRONG_PLATFORM
WRONG_PLATFORMNames no Android apps. Locked.
VERSION_NOT_COVERED
VERSION_NOT_COVEREDThis SDK release is newer than the key's "updates until" date. Locked.
UNKNOWN_SIGNING_KEY
UNKNOWN_SIGNING_KEYIssued under a signing key this SDK release does not know — update the SDK. Locked.
SUSPENDED
SUSPENDEDAn online key the vendor has suspended. Locked until they resume it.
VERIFICATION_REQUIRED
VERIFICATION_REQUIREDAn online key not confirmed with the license server yet, or whose confirmation ran out. Locked.
PdfEditorFont.Companion
public companion objectfromFile
@JvmStatic public fun fromFile(file: java.io.File): PdfEditorFont =A font file on disk.
fromResource
@JvmStatic public fun fromResource(resId: Int): PdfEditorFont =A font in your app's resources — R.font.brand (a single font file, not a font-family XML) or R.raw.….
fromAsset
@JvmStatic public fun fromAsset(path: String): PdfEditorFont =A font file in your app's assets, e.g. "fonts/Brand-Regular.ttf".
fromBytes
@JvmStatic public fun fromBytes(bytes: ByteArray): PdfEditorFont =Font bytes you already hold (downloaded, decrypted, generated).
PdfBytesListener
public fun interface PdfBytesListenerReceives PDF bytes — the saved document, the shared copy, the flattened copy, the signed copy.
onPdfBytes
public fun onPdfBytes(bytes: ByteArray)PdfEditorCloseListener
public fun interface PdfEditorCloseListenerCalled when the user leaves the editor (back, or the close button). Done does NOT call it: Done hands the document to PdfEditorView.onSave and the editor stays open, so a host that wants Done to exit closes it there.
onClosed
public fun onClosed()UnsavedChangesListener
public fun interface UnsavedChangesListenerCalled whenever the document's dirty flag flips, so a host can guard its OWN back navigation.
onUnsavedChangesChanged
public fun onUnsavedChangesChanged(hasUnsavedChanges: Boolean)Android
A complete editor as a Jetpack Compose screen, PdfEditorScreen, or as a classic View, PdfEditorView. Hand it a file path, get the edited bytes back.
Flutter
The pdf_editor plugin opens the native PDF-SDK editor full screen and hands back the edited file. It's a thin binding over the iOS and Android SDKs, so your Flutter app gets exactly the same editor, on both platforms.