Skip to content
/ pdfmp Public

PDF Viewer for Compose Multiplatform and Kotlin Multiplatform

License

Notifications You must be signed in to change notification settings

dshatz/pdfmp

Repository files navigation

PDF Viewer library for Kotlin Multiplatform and Compose Multiplatform.

This library wraps libpdfium (the Chromium PDF engine). The pre-compiled pdfium files are taken from here and bundled into this library.

Supported targets

  • Android
  • JVM Desktop
    • Linux x64, ARM64
    • Windows X64
    • MacOS X64, ARM64
  • iOS
    • x64 (simulator)
    • arm64
    • arm64Simulator

Usage

Add the dependency

Maven Central Version

implementation("com.dshatz.pdfmp:pdfmp-compose:1.0.9")
pdfmp = { module = "com.dshatz.pdfmp:pdfmp-compose", version = "1.0.9" }

Load the pdf

From bytes

  val pdf = PdfSource.PdfBytes(byteArray)

From path

val pdf = PdfSource.PdfPath(Path("~/Download/sample.pdf")

From Compose Resources

You can use this helper.

val bytes: PdfBytes? by asyncPdfResource { 
    Res.readBytes("files/doc.pdf")
}

Display the document.

To create a PdfState, you need only an instance of PdfSource.

Additionally, you can pass some optional parameters:

  • pageRange: IntRange - range of pages to include. Zero-indexed, inclusive range.
  • pageSpacing: Dp - spacing between pages, in DP.
@Composable
fun ShowDoc(state: PdfState) {
    val state = rememberPdfState(pdf, pageSpacing = 100.dp)
    PdfView(state, Modifier.fillMaxSize())
}

Observing document state

Use val displayState by state.displayState to get the document state.

sealed class DisplayState {
    data object Initializing: DisplayState()
    data object Active: DisplayState()
    data class Error(val error: Throwable): DisplayState()
}

You can use this to display a loading indicator or an error dialog.

Controlling the document view

You can read and change various view parameters.

val layoutInfo by state.layoutInfo()
// It will be null if the document did not load yet.
layoutInfo?.apply {
    // Below is some of the available state

    val visiblePages: State<List<VisiblePageInfo>>
    val mostVisiblePage: State<VisiblePageInfo?>
    val totalPages: State<Int>
    val pageRange: State<IntRange>
    val documentHeight: State<Float>

    // Scroll related
    var offsetY: Float
    fun scrollTo(pageIdx: Int)
    suspend fun animateScrollTo(pageIdx: Int)

    // Zoom related
    val zoom: State<Float>
    fun setZoom(newZoom: Float)
    suspend fun animateSetZoom(newZoom: Float)
}

Features

Feature Supported Notes
Loading from bytes
Loading from path May not work on Android, depending on permissions and path. Please report.
Loading from compose resources Does not work directly because native code does not have access to it. See above for how to do it.
Zooming and scrolling Loading the high-res image is debounced by 100ms. On desktop, horizontal scrolling can only be done with Shift+Vertical scroll.
Filtering pages Pass page range to rememberPdfState

About

PDF Viewer for Compose Multiplatform and Kotlin Multiplatform

Topics

Resources

License

Stars

Watchers

Forks

Languages