Package-level declarations

Types

Link copied to clipboard

KiteCanvas backed by a Compose Multiplatform DrawScope.

Link copied to clipboard
expect object ImageDecoder

Bitmaps for the Compose canvas. decodeRaw wraps pixels that KitePDF's core decoded with ImageKodec. decode reads an encoded file with the decoder the host platform provides: Skia on the JVM, iOS, macOS and the web, and BitmapFactory on Android. KitePDF does not call decode for page images: an image that the shared decoders refuse draws as a placeholder on every canvas (#184).

Link copied to clipboard

Wraps the page's canvas to filter ink, inspect glyphs or insert drawing calls during the page paint pass. Return a KiteCanvas delegating unchanged calls to the supplied canvas. It already includes the optional reader theme, so custom colours pass through that theme too; paper and viewer overlays remain outside the decorator.

Link copied to clipboard
@Immutable
class KiteChoiceStrings(val noOptions: String = "No options available", val noMatches: String = "No matching options", val rejected: String = "Selection was not accepted", val emptyOption: String = "Empty value")

The messages of a PDF choice control (ISO 32000-1, 12.7.4.4). Provide translated words with LocalKiteChoiceStrings; option labels themselves come from the document's /Opt entries.

Link copied to clipboard
@Immutable
sealed interface KiteDocLayout

How KiteDocView lays its pages out and how the user moves between them.

Link copied to clipboard
@Immutable
data class KiteDocViewColors(val pageBackground: Color = Color.White, val viewportBackground: Color = Color.Transparent, val theme: ReaderTheme? = null, val searchHighlight: Color = Color(0x66FFEB3B), val selectionHighlight: Color = Color(0x664285F4), val selectionHandle: Color = Color(0xFF4285F4), val selectionHandlePainter: KiteSelectionHandlePainter? = null)

Colours used by KiteDocView.

Link copied to clipboard
@Stable
class KiteDocViewState(val document: KiteDocument, initialPage: Int = 0)

Observable state + control surface of a KiteDocView.

Link copied to clipboard
@Immutable
data class KiteExternalLinks(val schemes: Set<String> = setOf("http", "https", "mailto"), val askFirst: Boolean = true)

What KiteDocView does with a link to an address outside the document, such as a web page or a mail address, when onLinkTap does not take it (#519).

Link copied to clipboard
@Immutable
data class KiteHighlight(val hit: KiteSearchHit, val color: Color? = null, val edgeMarker: Boolean = false, val edgeMarkerColor: Color? = null, val edgeMarkerSide: KiteMarkerSide = KiteMarkerSide.End, val id: String? = null)

One entry of KiteDocViewState.highlights: where to paint (hit) plus how to paint it.

Link copied to clipboard
sealed class KiteLinkAction

A link that the reader tapped, handed to KiteDocView's onLinkTap before the viewer acts on it. Every format gives the same facts, so most hosts need no when:

Link copied to clipboard

Which page margin an edge marker is painted in.

Link copied to clipboard

How a KiteDocLayout.Paged pager or a KiteDocLayout.Continuous strip fits each page into the viewport.

Link copied to clipboard
data class KitePageHit(val pageIndex: Int, val x: Double, val y: Double, val location: KiteLocation? = null)

The page under a viewport point, and a point on that page.

Link copied to clipboard
@Stable
interface KitePageOverlayScope

What the pageOverlay of KiteDocView draws in: one page, in the page's own frame. The frame moves and scales with the page, so an element placed on a rectangle of the page stays on that rectangle at any zoom, and grows with the page (#30).

Link copied to clipboard
@Stable
class KitePageRasterizer(density: Density, layoutDirection: LayoutDirection, textMeasurer: TextMeasurer, maxBitmapPixels: Long)

Imperative page → ImageBitmap pipeline. This is the raster engine behind KiteDocView; it is public so apps with custom viewers (own pagers, thumbnail grids, PNG export jobs) don't have to re-implement the CTM/flip/hairline math themselves.

Link copied to clipboard

Where the viewer's raster of one page stands, as KiteDocViewState.pageRenderState reports it. A page that failed keeps the last bitmap it had, and KiteDocViewState.retryPage renders it again.

Link copied to clipboard
@Immutable
sealed interface KiteRenderSpec

How KiteDocView turns pages into pixels. Pick a variant; each carries only the knobs that actually apply to it, so there are no settings that silently do nothing. Defaults to Rasterized via KiteRenderSpec.Default.

Link copied to clipboard
@Immutable
data class KiteScrollPosition(val location: KiteLocation, val offsetPx: Int = 0)

A continuous viewport anchor that a host can persist between reading sessions. location names the leading visible page, and offsetPx counts unzoomed layout pixels scrolled beyond that page's leading edge along the scroll axis. It works for vertical and horizontal continuous layouts, including right-to-left layout direction. It does not save zoom or cross-axis pan.

Link copied to clipboard

Which end of the selection a handle marks, in reading order.

Link copied to clipboard

Draws one selection boundary marker ("thumb") for KiteDocView.

Link copied to clipboard

Default look of KiteSelectionMenu's built-in chrome.

Link copied to clipboard
class KiteSelectionMenuItem(val label: String, val icon: @Composable () -> Unit? = null, val clearsSelection: Boolean = true, val onClick: (KiteTextSelection) -> Unit)

One action in a KiteSelectionMenu: a label, an optional leading icon slot, and what to do with the selected text.

Link copied to clipboard
data class KiteTextSelection(val pageIndex: Int, val start: Int, val end: Int, val text: String, val quads: List<KiteRectangle>, val location: KiteLocation? = null)

A finalized or in-progress text selection on one page (cross-page selection is out of scope). start/end are INCLUSIVE flattened char indices into the page's io.github.yuroyami.kitepdf.core.KiteStructuredText reading order; text is the range as a reader copies it (io.github.yuroyami.kitepdf.core.KiteStructuredText.copyText): \n\n between blocks, and a wrapped paragraph of a book as one line; quads are display-space, one per line touched.

Link copied to clipboard
@Immutable
class KiteViewerStrings(val page: (number: Int, count: Int?) -> String = { number, count -> if (count == null) "Page $number" else "Page $number of $count" }, val previousPage: String = "Previous page", val nextPage: String = "Next page", val highlightColor: (number: Int, count: Int) -> String = { number, count -> "Highlight colour $number of $count" }, val formField: String = "Form field", val link: String = "Link", val openLinkQuestion: String = "Open this link?", val openLink: String = "Open", val cancel: String = "Cancel", val markupErrors: (first: KiteXmlError, count: Int) -> String = { first, count -> "This chapter is not well-formed XML. Line ${first.line}: ${first.message}." + if (count > 1) " ${count - 1} more errors follow." else "" })

The words that KiteDocView and its widgets give a screen reader. The defaults are English; provide a translated set through LocalKiteViewerStrings:

Link copied to clipboard
@Immutable
data class KiteZoomSpec(val pinchEnabled: Boolean = true, val doubleTapEnabled: Boolean = true, val panEnabled: Boolean = true, val minZoom: Float = 1.0f, val maxZoom: Float = 8.0f, val doubleTapZoom: Float = 2.5f, val resetZoomOnPageChange: Boolean = true)

Zoom & pan behaviour for KiteDocView.

Link copied to clipboard
typealias PageHit = KitePageHit
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Properties

Link copied to clipboard
val LocalKiteChoiceStrings: ProvidableCompositionLocal<KiteChoiceStrings>

The words of PDF choice controls below this composition.

Link copied to clipboard
val LocalKiteViewerStrings: ProvidableCompositionLocal<KiteViewerStrings>

The KiteViewerStrings of the viewer and the widgets below it.

Functions

Link copied to clipboard
expect fun ImageBitmap.encodeToPng(): ByteArray?

Encode this ImageBitmap to PNG bytes. Write the result to a file, share it or upload it. PNG is lossless, so the bytes keep every pixel of the bitmap.

Link copied to clipboard
@Composable
fun EpubView(document: EpubDocument, modifier: Modifier = Modifier, page: Int? = null, background: Color = Color.White, theme: ReaderTheme? = null, pageSpacing: Dp = 8.dp, onPageRendered: (pageIndex: Int, image: ImageBitmap) -> Unit? = null, onTap: (Offset) -> Unit? = null, onLinkTap: (PdfAction) -> Boolean? = null)
Link copied to clipboard
@Composable
fun KiteDocView(document: KiteDocument, modifier: Modifier = Modifier, page: Int? = null, background: Color = Color.White, theme: ReaderTheme? = null, pageSpacing: Dp = 8.dp, selectionEnabled: Boolean = true, onPageRendered: (pageIndex: Int, image: ImageBitmap) -> Unit? = null, onTap: (Offset) -> Unit? = null, onLinkTap: (KiteLinkAction) -> Boolean? = null)

Convenience entry point: remembers its own state internally. Takes any KiteDocument, so a PdfDocument and an io.github.yuroyami.kitepdf.epub.EpubDocument both go here.

@Composable
fun KiteDocView(state: KiteDocViewState, modifier: Modifier = Modifier, layout: KiteDocLayout = KiteDocLayout.Default, zoomSpec: KiteZoomSpec = KiteZoomSpec(), renderSpec: KiteRenderSpec = KiteRenderSpec.Default, colors: KiteDocViewColors = KiteDocViewColors(), pageSpacing: Dp = 8.dp, userScrollEnabled: Boolean = true, selectionEnabled: Boolean = true, onPageRendered: (pageIndex: Int, image: ImageBitmap) -> Unit? = null, pagePlaceholder: @Composable (pageIndex: Int) -> Unit? = null, chapterPlaceholder: @Composable (chapter: Int) -> Unit? = null, overlay: @Composable BoxScope.(KiteDocViewState) -> Unit? = null, pageOverlay: @Composable KitePageOverlayScope.() -> Unit? = null, onTap: (Offset) -> Unit? = null, onLinkTap: (KiteLinkAction) -> Boolean? = null, scripts: PdfScriptHandler? = null, onHighlightTap: (KiteHighlight) -> Boolean? = null, epubScripts: EpubScriptHandler? = null, externalLinks: KiteExternalLinks? = KiteExternalLinks(), showMarkupErrors: Boolean = true)

THE KitePDF viewer composable. It draws a KiteDocument, so a PDF and an EPUB go through the same code path, the same gestures and the same widgets.

Link copied to clipboard
@Composable
fun KiteNavigationControls(state: KiteDocViewState, modifier: Modifier = Modifier, contentColor: Color = Color.White, containerColor: Color = Color(0xB3222222), textStyle: TextStyle = TextStyle.Default)

Previous / "x of y" / next pill. The buttons turn off at the ends, and on a fixed page (KiteDocLayout.SinglePage), which navigation does not turn.

Link copied to clipboard
@Composable
fun KiteOutlinePanel(state: KiteDocViewState, modifier: Modifier = Modifier, outline: List<KiteOutlineItem> = state.document.outline, contentPadding: PaddingValues = PaddingValues(8.dp), textStyle: TextStyle = TextStyle(fontSize = 14.sp), textColor: Color = Color(0xFF202124), disabledTextColor: Color = Color(0xFF9AA0A6), currentPageColor: Color = Color(0xFF4A90D9), indent: Dp = 16.dp, onNavigate: (KiteOutlineItem) -> Unit? = null)

A navigation panel over the document's outline (PDF bookmarks / EPUB table of contents): an indented, clickable column of KiteOutlineItems. Clicking an entry scrolls to its target (and calls onNavigate); on a book still paginating this lays out that one chapter rather than the whole book; entries without one (unresolvable destinations, grouping labels) render dimmed and unclickable. Plain foundation styling, like every widget here.

Link copied to clipboard
@Composable
fun KitePageIndicator(state: KiteDocViewState, modifier: Modifier = Modifier, textStyle: TextStyle = TextStyle.Default, format: (currentPage: Int, pageCount: Int) -> String = { c, t -> "${c + 1} / $t" })

"current / total" page readout. Recomposes as the user scrolls or swipes.

Link copied to clipboard
@Composable
fun BoxScope.KiteSelectionMenu(state: KiteDocViewState, items: List<KiteSelectionMenuItem>, modifier: Modifier = Modifier, highlightColors: List<Color> = emptyList(), onHighlightColorPicked: (KiteTextSelection, Color) -> Unit? = null, clearSelectionOnColorPick: Boolean = true, alignment: Alignment? = null, showWhileSelecting: Boolean = false, containerColor: Color = KiteSelectionMenuDefaults.ContainerColor, contentColor: Color = KiteSelectionMenuDefaults.ContentColor, container: @Composable (selection: KiteTextSelection, content: @Composable () -> Unit) -> Unit? = null, itemContent: @Composable (item: KiteSelectionMenuItem, selection: KiteTextSelection) -> Unit? = null, colorSwatch: @Composable (color: Color, onPick: () -> Unit) -> Unit? = null)

The selection context menu: place it in KiteDocView's overlay slot and it appears whenever text is selected, listing items and, when highlightColors is non-empty, a wrapping row of colour swatches.

Link copied to clipboard
@Composable
fun KiteThumbnailStrip(state: KiteDocViewState, modifier: Modifier = Modifier, thumbnailHeight: Dp = 72.dp, spacing: Dp = 8.dp, contentPadding: PaddingValues = PaddingValues(8.dp), selectedBorderColor: Color = Color(0xFF4A90D9), pageBackground: Color = Color.White)

Horizontal strip of tappable page thumbnails; the current page is outlined. Tapping a thumbnail animates the KiteDocView sharing this state to that page.

Link copied to clipboard
@Composable
fun PdfNavigationControls(state: KiteDocViewState, modifier: Modifier = Modifier, contentColor: Color = Color.White, containerColor: Color = Color(0xB3222222), textStyle: TextStyle = TextStyle.Default)
Link copied to clipboard
@Composable
fun PdfOutlinePanel(state: KiteDocViewState, modifier: Modifier = Modifier, outline: List<KiteOutlineItem> = state.document.outline, contentPadding: PaddingValues = PaddingValues(8.dp), textStyle: TextStyle = TextStyle(fontSize = 14.sp), textColor: Color = Color(0xFF202124), disabledTextColor: Color = Color(0xFF9AA0A6), currentPageColor: Color = Color(0xFF4A90D9), indent: Dp = 16.dp, onNavigate: (KiteOutlineItem) -> Unit? = null)
Link copied to clipboard
@Composable
fun PdfPageIndicator(state: KiteDocViewState, modifier: Modifier = Modifier, textStyle: TextStyle = TextStyle.Default, format: (currentPage: Int, pageCount: Int) -> String = { c, t -> "${c + 1} / $t" })
Link copied to clipboard
@Composable
fun BoxScope.PdfSelectionMenu(state: KiteDocViewState, items: List<KiteSelectionMenuItem>, modifier: Modifier = Modifier, highlightColors: List<Color> = emptyList(), onHighlightColorPicked: (KiteTextSelection, Color) -> Unit? = null, clearSelectionOnColorPick: Boolean = true, alignment: Alignment = Alignment.TopCenter, showWhileSelecting: Boolean = false, containerColor: Color = KiteSelectionMenuDefaults.ContainerColor, contentColor: Color = KiteSelectionMenuDefaults.ContentColor, container: @Composable (selection: KiteTextSelection, content: @Composable () -> Unit) -> Unit? = null, itemContent: @Composable (item: KiteSelectionMenuItem, selection: KiteTextSelection) -> Unit? = null, colorSwatch: @Composable (color: Color, onPick: () -> Unit) -> Unit? = null)
Link copied to clipboard
@Composable
fun PdfThumbnailStrip(state: KiteDocViewState, modifier: Modifier = Modifier, thumbnailHeight: Dp = 72.dp, spacing: Dp = 8.dp, contentPadding: PaddingValues = PaddingValues(8.dp), selectedBorderColor: Color = Color(0xFF4A90D9), pageBackground: Color = Color.White)
Link copied to clipboard
@Composable
fun PdfView(document: PdfDocument, modifier: Modifier = Modifier, page: Int? = null, background: Color = Color.White, pageSpacing: Dp = 8.dp, selectionEnabled: Boolean = true, onPageRendered: (pageIndex: Int, image: ImageBitmap) -> Unit? = null, onTap: (Offset) -> Unit? = null, onLinkTap: (PdfAction) -> Boolean? = null)
@Composable
fun PdfView(state: KiteDocViewState, modifier: Modifier = Modifier, layout: KiteDocLayout = KiteDocLayout.Default, zoomSpec: KiteZoomSpec = KiteZoomSpec(), renderSpec: KiteRenderSpec = KiteRenderSpec.Default, colors: KiteDocViewColors = KiteDocViewColors(), pageSpacing: Dp = 8.dp, userScrollEnabled: Boolean = true, selectionEnabled: Boolean = true, onPageRendered: (pageIndex: Int, image: ImageBitmap) -> Unit? = null, pagePlaceholder: @Composable (pageIndex: Int) -> Unit? = null, overlay: @Composable BoxScope.(KiteDocViewState) -> Unit? = null, onTap: (Offset) -> Unit? = null, onLinkTap: (PdfAction) -> Boolean? = null)
Link copied to clipboard
@Composable
fun rememberEpubViewState(document: EpubDocument, initialPage: Int = 0): KiteDocViewState
Link copied to clipboard

Remembers a state reopened at a page and continuous scroll offset.

Remembers a KiteDocViewState opened at bookmark, a position saved from an earlier reading session.

@Composable
fun rememberKiteDocViewState(document: KiteDocument, initialPage: Int = 0): KiteDocViewState

Remembers a KiteDocViewState for document. Hoist it to drive a KiteDocView from anywhere: navigation buttons in your top bar, a zoom slider, a HUD overlay. The state object is the single point of control.

Link copied to clipboard

KitePageRasterizer wired to the composition's density, layout direction and font resolver.

@Composable
fun rememberKitePageRasterizer(maxBitmapPixels: Long): KitePageRasterizer

rememberKitePageRasterizer with an explicit per-bitmap allocation ceiling.

Link copied to clipboard
Link copied to clipboard
@Composable
fun rememberPdfViewState(document: PdfDocument, initialPage: Int = 0): KiteDocViewState