Skip to content

PDF-SDK 2.4.1 is out.See what’s new

PDF-SDK
Skip to Content
Docs

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

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? = try

Run 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(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 PdfEditorMode

Which 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

VIEWER

Read-only. No toolbar, no selection, no undo pill — just the document.

EDIT

EDIT

Content editing: select, move, restyle and retype what is already on the page.

FORMS

FORMS

AcroForm authoring: place and configure text fields, check boxes, radios, lists and dropdowns.

ANNOTATE

ANNOTATE

Text markup: highlight, underline, strikethrough and squiggly over existing text.

FILL_AND_SIGN

FILL_AND_SIGN

Fill & Sign: signatures, stamps and free text, for a form the user is completing rather than building.

INSERT

INSERT

Insert: pages, images, signatures, notes and text boxes.

DRAW

DRAW

Freehand 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? = null

The 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?)? = null

Asked for every key strings doesn't have; return null to fall through.

layoutDirection

public val layoutDirection: PdfEditorLayoutDirection = PdfEditorLayoutDirection.AUTOMATIC

PdfEditorLayoutDirection

public enum class PdfEditorLayoutDirection

AUTOMATIC

AUTOMATIC

LEFT_TO_RIGHT

LEFT_TO_RIGHT

RIGHT_TO_LEFT

RIGHT_TO_LEFT

PdfSignaturePlacement

public enum class PdfSignaturePlacement

Where a visible signature is drawn. INVISIBLE seals the document without marking the page.

INVISIBLE

INVISIBLE

BOTTOM_LEFT

BOTTOM_LEFT

BOTTOM_RIGHT

BOTTOM_RIGHT

TOP_LEFT

TOP_LEFT

TOP_RIGHT

TOP_RIGHT

PdfEditorConfiguration

public class PdfEditorConfiguration

What 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.SYSTEM

Light, 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_ZOOM

The 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_ZOOM

The largest page zoom. Clamped to 1…3. minZoom = 1f, maxZoom = 1f turns pinch-zoom off.

haptics

public var haptics: Boolean = true

Haptic feedback on taps and snaps. Default on.

showsUsageHints

public var showsUsageHints: Boolean = true

Default on.

interfaceFontFamily

public var interfaceFontFamily: androidx.compose.ui.text.font.FontFamily? = null

The 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 = true

The 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 = true

showsDeviceFonts

public var showsDeviceFonts: Boolean = true

allowsFontImport

public var allowsFontImport: Boolean = true

newTextFont

public var newTextFont: PdfEditorFont? = null

A 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? = null

The 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? = null

handleFillColor

@ColorInt public var handleFillColor: Int? = null

The handles' (and the rotation knob's) fill. Null = white.

handleShape

public var handleShape: PdfEditorHandleShape = PdfEditorHandleShape.ROUNDED_SQUARE

handleScale

public var handleScale: Float = 1f

Handle 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.5f

The selection box's and the handles' outline, in dp: 1…3 (clamped).

rotateIcon

@DrawableRes public var rotateIcon: Int? = null

The 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? = null

The 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? = null

colors

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 = true

The 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_RIGHT

Where the e-Sign tab's Placement picker starts (the user can still change it). Default BOTTOM_RIGHT.

showsUndoRedo

public var showsUndoRedo: Boolean = true

The floating pills along the bottom: undo / redo, the page navigator, and zoom.

showsPageNavigator

public var showsPageNavigator: Boolean = true

showsZoomControls

public var showsZoomControls: Boolean = true

toolTitles

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 object

SUPPORTED_MIN_ZOOM

public const val SUPPORTED_MIN_ZOOM: Float = ZOOM_MIN

The widest zoom range the editor supports.

SUPPORTED_MAX_ZOOM

public const val SUPPORTED_MAX_ZOOM: Float = ZOOM_MAX

fromOptions

@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 PdfEditorFont

A 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? = null

Buttons, the armed tool, Done, switches, links, the current page — anything that says "this one".

onAccent

@ColorInt public var onAccent: Int? = null

Text and glyphs drawn ON the accent (Done's check, a selected chip's label). Default white.

canvasBackground

@ColorInt public var canvasBackground: Int? = null

Behind and around the pages.

toolbarBackground

@ColorInt public var toolbarBackground: Int? = null

The header, the mode toolbar, the property bars and the floating pills.

toolbarForeground

@ColorInt public var toolbarForeground: Int? = null

Icons and labels on those bars, and the primary text in panels and menus.

secondaryForeground

@ColorInt public var secondaryForeground: Int? = null

Captions, hints, placeholders, inactive labels. Default: toolbarForeground at reduced strength.

panelBackground

@ColorInt public var panelBackground: Int? = null

Sheets, dialogs and menus. Default: toolbarBackground, or the editor's own.

destructive

@ColorInt public var destructive: Int? = null

Delete 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: String

color

@ColorInt public val color: Int

isDate

public val isDate: Boolean get() = text == DATE

A stamp that reads the date it's placed, e.g. "OCT 5, 2026".

PdfEditorStamp.Companion

public companion object

date

@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 PdfEditorSignatureMethod

The signature pad's tabs, for PdfEditorConfiguration.signatureMethods.

DRAW

DRAW

TYPE

TYPE

IMAGE

IMAGE

E_SIGN

E_SIGN

PdfEditorCustomAction

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: String

Unique among your custom actions; PdfEditorConfiguration.toolOrder / menuOrder refer to it by this.

title

public val title: String

icon

@DrawableRes public val icon: Int? = null

A drawable, drawn as a tinted template. Null shows a generic glyph in the toolbar and none in the menu.

handler

public val handler: PdfEditorActionHandler

Called on the main thread, after any edit in progress was committed.

PdfEditorActionHandler

public fun interface PdfEditorActionHandler

What a custom action runs. A single-method interface, so Java passes a lambda.

onAction

public fun onAction(context: PdfEditorActionContext)

PdfEditorPdfCallback

public fun interface PdfEditorPdfCallback

Receives the document's bytes, or null if the export failed.

onResult

public fun onResult(pdf: ByteArray?)

PdfEditorActionContext

public class PdfEditorActionContext

What a custom action's handler can see of the document.

pageIndex

public val pageIndex: Int

The page on screen, 0-based, and the page count.

pageCount

public val pageCount: Int

currentPdf

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 PdfEditorToolbarItem

An 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) : PdfEditorToolbarItem

PdfEditorToolbarItem.Custom

public data class Custom(val id: String) : PdfEditorToolbarItem

PdfEditorMenuEntry

public sealed interface PdfEditorMenuEntry

An 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) : PdfEditorMenuEntry

PdfEditorMenuEntry.Custom

public data class Custom(val id: String) : PdfEditorMenuEntry

PdfEditorHeaderButton

public enum class PdfEditorHeaderButton

The header's buttons.

BACK

BACK

PAGES

PAGES

MORE

MORE

DONE

DONE

PdfEditorAction

public enum class PdfEditorAction

A 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_SELECT

Multi: add to / remove from a multi-layer selection.

EDIT_TEXT

EDIT_TEXT

Edit a text layer's words (bar and menu).

TEXT_COLOR

TEXT_COLOR

A text layer's colour well.

FONT

FONT

The font picker.

TEXT_STYLE

TEXT_STYLE

Bold · Italic · Underline · Strikethrough (one group; its title is the caption under it).

FONT_SIZE

FONT_SIZE

The font-size button.

OPACITY

OPACITY

The opacity stepper.

STROKE_COLOR

STROKE_COLOR

A shape's outline colour well.

FILL_COLOR

FILL_COLOR

A shape's or path's fill colour well.

STROKE_WIDTH

STROKE_WIDTH

A shape's outline width stepper.

EDIT_NOTE

EDIT_NOTE

Edit a sticky note (bar and menu).

NOTE_COLOR

NOTE_COLOR

A sticky note's card colour well.

RESIGN

RESIGN

Draw a placed signature again (bar and menu).

REPLACE_IMAGE

REPLACE_IMAGE

Replace an image (bar and menu).

CROP

CROP

Crop an image or signature.

PLAY_SOUND

PLAY_SOUND

Play / pause / replay a sound note.

LINK

Link a layer to a URL or page.

CUT

CUT

COPY

COPY

DUPLICATE

DUPLICATE

Duplicate a layer or form field (context menu).

DELETE

DELETE

Delete a layer or form field (bar and menu).

FORM_FILL

FORM_FILL

A form field's menu: fill it in ("Edit Text", "Toggle" or "Choose…", by the field's kind).

FORM_OPTIONS

FORM_OPTIONS

A list or dropdown field's Options.

FORM_RADIO_GROUP

FORM_RADIO_GROUP

A radio button's Group.

FORM_COLORS

FORM_COLORS

A form field's Color submenu (fill, border, text).

FORM_BORDER_WIDTH

FORM_BORDER_WIDTH

A form field's Border Width submenu.

PASTE

PASTE

Paste, on the empty page's menu.

ROTATE_PAGE_LEFT

ROTATE_PAGE_LEFT

The page panel's actions on a page.

ROTATE_PAGE_RIGHT

ROTATE_PAGE_RIGHT

DUPLICATE_PAGE

DUPLICATE_PAGE

INSERT_BLANK_PAGE

INSERT_BLANK_PAGE

DELETE_PAGE

DELETE_PAGE

PdfEditorMenuItem

public enum class PdfEditorMenuItem

The ⋮ (More) menu's items.

SEARCH

SEARCH

MANAGE_PAGES

MANAGE_PAGES

SHARE_PDF

SHARE_PDF

PRINT

PRINT

FLATTEN_AND_SHARE

FLATTEN_AND_SHARE

FLATTEN_DOCUMENT

FLATTEN_DOCUMENT

Android only: bake the form into the page content of the document itself.

RESET_FORM

RESET_FORM

RESET_TO_ORIGINAL

RESET_TO_ORIGINAL

PdfEditorColorScheme

public enum class PdfEditorColorScheme

The editor's colour scheme.

SYSTEM

SYSTEM

LIGHT

LIGHT

DARK

DARK

PdfEditorHandleShape

public enum class PdfEditorHandleShape

The shape of the selection handles.

ROUNDED_SQUARE

ROUNDED_SQUARE

CIRCLE

CIRCLE

SQUARE

SQUARE

PdfEditorMarkupStyle

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: Int

opacity

public val opacity: Float = 1f

PdfEditorInkStyle

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: Int

width

public val width: Float = 5f

opacity

public val opacity: Float = 1f

PdfEditorToolDefaults

public class PdfEditorToolDefaults

The 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 PdfCmsSigner

Produces 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 PdfEditorSigning

Sign 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() != null

True when this device already holds the SDK's self-signed identity (see createDeviceIdentity).

deviceIdentityName

public val deviceIdentityName: String? get() = DigitalId.existing()?.signerName

The 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: String

reason

public val reason: String

signedAt

public val signedAt: String

intact

public val intact: Boolean

The signed bytes still hash to what the signature says.

coversWholeFile

public val coversWholeFile: Boolean

The signature's /ByteRange covers the WHOLE file — false means something was appended after it.

detail

public val detail: String

Document 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 Kind

TEXT

TEXT

IMAGE

IMAGE

NOTE

NOTE

SIGNATURE

SIGNATURE

DRAWING

DRAWING

SOUND

SOUND

SHAPE

SHAPE

VECTOR

VECTOR

PdfLayer.Shape

public enum class Shape

RECTANGLE

RECTANGLE

ELLIPSE

ELLIPSE

LINE

LINE

ARROW

ARROW

PdfSearchMatch

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 Kind

TEXT

TEXT

CHECKBOX

CHECKBOX

RADIO

RADIO

COMBOBOX

COMBOBOX

LISTBOX

LISTBOX

BUTTON

BUTTON

SIGNATURE

SIGNATURE

UNKNOWN

UNKNOWN

PdfMetadataKey

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 PdfFontFamily

The built-in families every PDF reader has.

SANS

SANS

SERIF

SERIF

MONO

MONO

PdfZOrder

public enum class PdfZOrder

TO_BACK

TO_BACK

BACKWARD

BACKWARD

FORWARD

FORWARD

TO_FRONT

TO_FRONT

PdfMarkupKind

public enum class PdfMarkupKind

HIGHLIGHT

HIGHLIGHT

STRIKEOUT

STRIKEOUT

SQUIGGLY

SQUIGGLY

PdfImageKind

public enum class PdfImageKind

What an image layer is to the editor: a signature, a hand drawing and a stamp are images it knows by kind.

PHOTO

PHOTO

NOTE

NOTE

SIGNATURE

SIGNATURE

DRAWING

DRAWING

PdfFormFieldKind

public enum class PdfFormFieldKind

TEXT

TEXT

CHECKBOX

CHECKBOX

RADIO

RADIO

LIST_BOX

LIST_BOX

DROPDOWN

DROPDOWN

PdfTextResult

public enum class PdfTextResult

How a text replacement went.

REPLACED

REPLACED

Replaced, and it fits where the old text was.

OVERFLOW

OVERFLOW

Replaced, 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 PdfDocumentEditor

constructor

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(): ByteArray

The 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 = read

The 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>): ByteArray

pages 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).filter

layer

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,
): PdfTextResult

Replace 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))
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,
): PdfLayer

A 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,
): PdfLayer

An 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(),
): String

A 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 PdfDocumentListener

Called 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 PdfEditorSdk

The 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.isAvailable

Whether 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?): PdfEditorLicense

Set (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(): PdfEditorLicense

Online 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: PdfEditorLicense

The license verdict the SDK is running under.

chromeScale

public var chromeScale: Float

Multiplier 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 Status

VALID

VALID

The key covers this app.

DEVELOPMENT

DEVELOPMENT

A valid key on a development host (only the web SDK uses this).

UNLICENSED

UNLICENSED

No key has been set. Locked.

INVALID

INVALID

Malformed, altered, or not issued by the vendor. Locked.

EXPIRED

EXPIRED

Past its expiry date. Locked.

WRONG_APP

WRONG_APP

Does not name this app's package. Locked.

WRONG_PLATFORM

WRONG_PLATFORM

Names no Android apps. Locked.

VERSION_NOT_COVERED

VERSION_NOT_COVERED

This SDK release is newer than the key's "updates until" date. Locked.

UNKNOWN_SIGNING_KEY

UNKNOWN_SIGNING_KEY

Issued under a signing key this SDK release does not know — update the SDK. Locked.

SUSPENDED

SUSPENDED

An online key the vendor has suspended. Locked until they resume it.

VERIFICATION_REQUIRED

VERIFICATION_REQUIRED

An online key not confirmed with the license server yet, or whose confirmation ran out. Locked.

PdfEditorFont.Companion

public companion object

fromFile

@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 PdfBytesListener

Receives PDF bytes — the saved document, the shared copy, the flattened copy, the signed copy.

onPdfBytes

public fun onPdfBytes(bytes: ByteArray)

PdfEditorCloseListener

public fun interface PdfEditorCloseListener

Called 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 UnsavedChangesListener

Called whenever the document's dirty flag flips, so a host can guard its OWN back navigation.

onUnsavedChangesChanged

public fun onUnsavedChangesChanged(hasUnsavedChanges: Boolean)