Package-level declarations

Types

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
class DrawOrderPart(val glyphs: List<TextGlyph>, val text: String, val offset: Double, val rightToLeft: Boolean = false)

Glyphs of a piece that a text engine draws as one string, offset advance units from the piece's start. rightToLeft when its letters run right to left, so that text holds them in logical order inside a right-to-left override.

Link copied to clipboard
data class ExtGState(val fillAlpha: Double? = null, val strokeAlpha: Double? = null, val blendMode: KiteBlendMode? = null, val softMask: SoftMask? = null, val lineWidth: Double? = null, val lineCap: Int? = null, val lineJoin: Int? = null, val miterLimit: Double? = null, val dashArray: List<Double>? = null, val dashPhase: Double = 0.0, val renderingIntent: KiteRenderingIntent? = null, val blackPointCompensation: Boolean? = null, val overprintStroke: Boolean? = null, val overprintFill: Boolean? = null, val overprintMode: Int? = null)

Parsed Extended Graphics State (ISO 32000-1 §8.4.5).

Link copied to clipboard
data class GradientStops(val offsets: DoubleArray, val colors: Array<RgbColor>)

Parallel offset/colour arrays describing a sampled gradient.

Link copied to clipboard
class GraphicsStack(initial: GraphicsState = GraphicsState(), maxDepth: Int = 4096)

Mutable stack façade. Holds the current state plus a save stack for q/Q.

Link copied to clipboard
data class GraphicsState(val ctm: KiteMatrix = KiteMatrix.IDENTITY, val strokeColor: RgbColor = RgbColor.BLACK, val fillColor: RgbColor = RgbColor.BLACK, val lineWidth: Double = 1.0, val text: TextState = TextState(), val fillColorSpace: KiteColorSpace = KiteColorSpace.DeviceGray, val strokeColorSpace: KiteColorSpace = KiteColorSpace.DeviceGray, val fillAlpha: Double = 1.0, val strokeAlpha: Double = 1.0, val blendMode: KiteBlendMode = KiteBlendMode.Normal, val softMask: SoftMask? = null, val softMaskCtm: KiteMatrix? = null, val fillPattern: KitePattern? = null, val strokePattern: KitePattern? = null, val dashArray: List<Double>? = null, val dashPhase: Double = 0.0, val lineCap: Int = 0, val lineJoin: Int = 0, val miterLimit: Double = 10.0, val renderingIntent: KiteRenderingIntent = KiteRenderingIntent.RelativeColorimetric, val blackPointCompensation: Boolean = true, val fillComponents: DoubleArray? = null, val strokeComponents: DoubleArray? = null, val overprintStroke: Boolean = false, val overprintFill: Boolean = false, val overprintMode: Int = 0)

Graphics state (ISO 32000-1 §8.4).

Link copied to clipboard
class HostTextPart(val glyphs: List<TextGlyph>, val text: String, val x: Double, val width: Double, val shaped: Boolean, val rightToLeft: Boolean = false)

A part of a run of host text as a canvas draws it. x is where its first glyph starts and width is the width the document gives its glyphs, both in the units of the scales hostTextParts took. A shaped part draws text as one string that the text engine shapes, fitted to width. Any other part draws each of its glyphs alone, at its own advance, as MuPDF places a base-14 font. rightToLeft as in DrawOrderPart.

Link copied to clipboard

The part of an ICC profile a document reader actually needs: how the colours of a grey, RGB or CMYK profile map to sRGB.

Link copied to clipboard
Link copied to clipboard
class KiteBitmapCache<T : Any>(budgetBytes: Long = DEFAULT_BUDGET_BYTES)

Platform bitmaps that a canvas built from images, so that an image drawn many times on a page, such as a tiled background or a row of icons, converts once (#117). A viewer can keep one cache across draws without retaining decoded source images (#371).

Link copied to clipboard

PDF blend modes (ISO 32000-1 §11.3.5).

Link copied to clipboard
interface KiteCanvas

High-level drawing target. Implement this to add a new render backend; use PdfPage.renderTo to drive an existing one.

Link copied to clipboard
sealed class KiteColorSpace

Colour-space resolution + sample-to-RGB conversion (ISO 32000-1 §8.6).

Link copied to clipboard
sealed class KiteFunction

A PDF function (ISO 32000-1 §7.10). Functions map an n-component input to an m-component output, used by shadings, transparency groups, tint transforms and halftone calculations.

Link copied to clipboard

How a gradient continues past its ends: the spreadMethod of an SVG gradient (SVG 1.1, 13.2.2 and 13.2.3) and the SpreadMethod of an XPS gradient brush. A PDF shading has no such attribute: its /Extend flags can only pad.

Link copied to clipboard

One image a document handler produced, ready for a KiteCanvas: the samples plus everything needed to read them (colour space, bit depth, /Decode, masks). PDF fills it from a /XObject /Image resource entry (ISO 32000-1 §8.9.5); EPUB fills it from a decoded PNG, JPEG or GIF.

Link copied to clipboard

The identity of immutable image content, without retaining its pixels or its document.

Link copied to clipboard

How a canvas samples an image that it draws. ISO 32000-1, 8.9.5.3 leaves image interpolation to the reader, so every canvas follows imageSampling and draws the same pixels (#122, #123).

Link copied to clipboard

The transfer function of a soft mask as a table of 256 levels (ISO 32000-1, 11.6.5.2, Table 144, /TR). The table maps each value of the mask group, its alpha or its luminosity, to the mask value that gates the content. Both run from 0 to 255.

Link copied to clipboard
data class KiteMatrix(val a: Double, val b: Double, val c: Double, val d: Double, val e: Double, val f: Double)

2D affine transformation matrix as PDF uses it (ISO 32000-1 §8.3.4).

Link copied to clipboard
data class KitePath(val segments: List<KitePath.Segment>)

A geometric path accumulated by m/l/c/v/y/h/re operators before being painted by S/f/B/n.

Link copied to clipboard
sealed class KitePattern

Parsed /Pattern resource entry (ISO 32000-1 §8.7).

Link copied to clipboard
class KiteRaster(val width: Int, val height: Int, val pixels: IntArray)

Pixels that a KiteRasterStep reads and writes: width by height pixels, row by row from the top, each one an sRGB colour with straight alpha packed as 0xAARRGGBB. That is the layout of BufferedImage.TYPE_INT_ARGB on the JVM and of Bitmap.getPixels on Android, so those canvases hand their pixels over without a conversion.

Link copied to clipboard
class KiteRasterCanvas(val width: Int, val height: Int, hostOutlines: (text: String, fontSpec: FontSpec) -> KitePath?? = null) : KiteCanvas

A KiteCanvas that paints into width by height pixels in plain Kotlin, the same on every target. Device space is the pixels: x runs right, y runs down, and (0, 0) is the top left corner of the top left pixel. Edges are anti-aliased.

Link copied to clipboard
interface KiteRasterScope

What KiteCanvas.rasterStep hands its step: a box of device pixels, and the canvas's own drawing into rasters of that box. A canvas that works at a lower resolution than the device, to stay within its memory budget, gives smaller rasters and says so through toPixels.

Link copied to clipboard
fun interface KiteRasterStep

One step on the pixels of a box, which KiteCanvas.rasterStep runs.

Link copied to clipboard

How a colour in an ICC-based colour space converts to the screen (ISO 32000-1, 8.6.5.8). Only a profile with a lookup table per intent converts differently for each one, and RelativeColorimetric is the default. The order is the ICC order, from 0 to 3.

Link copied to clipboard
sealed class KiteShading

A PDF shading (ISO 32000-1 §8.7.4). Shadings define smooth color transitions used as fills via the sh content-stream operator or via a shading pattern referenced by SCN/scn.

Link copied to clipboard

How a canvas strokes a path under a matrix. ISO 32000-1, 8.4.3.2 measures the line width and the dash lengths in user space, so the pen is a circle there. A matrix that scales x and y differently, or skews, turns the circle into an ellipse on the device, and one device width cannot draw it (#108). strokePen picks the space to stroke in.

Link copied to clipboard
typealias Matrix = KiteMatrix
Link copied to clipboard

Backend that ignores everything, useful for benchmarks and content-stream sanity tests.

Link copied to clipboard

What a ReaderTheme does to the images of a page (#458).

Link copied to clipboard
class ReaderTheme(val background: RgbColor, val mapColor: (RgbColor) -> RgbColor, val images: ReaderImages)

A reading theme: a page background plus a mapColor transform applied to every text / vector / border / CSS-background colour a page paints. Images and gradients pass through untouched, so photos never invert. withImages lets the theme recolour the images that are line art too.

Link copied to clipboard

Records every device call, useful for tests + verifying operator dispatch.

Link copied to clipboard
Link copied to clipboard
data class RgbColor(val r: Double, val g: Double, val b: Double)

Simple RGB colour in 0,1³. Greyscale collapses to all-equal channels.

Link copied to clipboard
sealed class SoftMask

Soft mask source (ISO 32000-1 §11.6.5). Either explicitly disabled (None) or a MaskGroup containing a Form XObject whose rendered luminosity or alpha channel becomes the per-pixel mask.

Link copied to clipboard
data class TextState(val font: PdfFont? = null, val fontSize: Double = 12.0, val textMatrix: KiteMatrix = KiteMatrix.IDENTITY, val lineMatrix: KiteMatrix = KiteMatrix.IDENTITY, val charSpacing: Double = 0.0, val wordSpacing: Double = 0.0, val horizontalScaling: Double = 100.0, val leading: Double = 0.0, val rise: Double = 0.0, val renderingMode: Int = 0)

Per-BT/ET block text state, reset at BT and mutated by text operators.

Properties

Link copied to clipboard

Default allocation ceiling shared by every rasterizing surface in KitePDF: 40 MP already expands to 160 MiB of RGBA, so refuse more before allocating.

Link copied to clipboard
const val MAX_SPREAD_PERIODS: Int = 32

The most periods that spreadOver builds. Canvases sample a gradient at 256 stops, 8 per period.

Functions

Link copied to clipboard

Merge the non-null fields of ext into this state. Spec semantics for gs <name>: only entries present in the ExtGState override; everything else passes through.

Link copied to clipboard

piece, which is in the order it draws, left to right, as the strings a text engine draws in that order (#486). A text engine runs the bidi algorithm, so it would reverse right-to-left letters the layout already reversed. A piece without them stays one part, as it was. Otherwise it is cut where the strong direction changes, and a right-to-left part goes back to logical order inside a right-to-left override, so the engine joins Arabic letters with their logical neighbours and lays them out right to left, which is the order they came in. A left-to-right part beside it takes a left-to-right override, so that its digits and punctuation stay put.

Link copied to clipboard

These pixels as a JPEG file of quality from 1 to 100. JPEG has no alpha, so each pixel is first drawn over black, as a browser does for toDataURL('image/jpeg').

Link copied to clipboard

These pixels as a PNG file, with their alpha.

Link copied to clipboard

ctm, which maps an image's unit square to device pixels, with the image edges moved outwards onto whole pixels. The image then covers every pixel it touches, and two images that meet leave no seam between them. A canvas that draws into pixels applies it just before it draws an image, image mask or image clip.

Link copied to clipboard
fun hostTextParts(glyphs: List<TextGlyph>, advanceScale: Double, adjustScale: Double): List<HostTextPart>

glyphs as the parts a canvas without a layout of its own draws them in (#588): the pieces of spacedPieces, each cut into the drawOrderParts. A part of more than one glyph is shaped when a character of it changes shape or place with its neighbours, as Arabic letters join and an Indic vowel sign moves, so that the text engine sees them together. Advances move the pen by advanceScale each, and the spacing a glyph adds after it by adjustScale.

Link copied to clipboard
fun imageSampling(width: Int, height: Int, ctm: KiteMatrix, interpolate: Boolean): KiteImageSampling

The sampling for an image of width by height pixels drawn under ctm, which maps the image's unit square to device pixels. The rules follow MuPDF:

Link copied to clipboard

True when a character of text may draw differently beside its neighbours than alone: a mark, a joiner or another format character, a right-to-left letter, or a letter of a script that joins, reorders or builds clusters, such as Arabic, Devanagari or Thai. False for Latin, Greek, Cyrillic and Armenian letters, punctuation, symbols, CJK ideographs, kana and Hangul syllables.

Link copied to clipboard
fun KiteCanvas.paintComplexShading(shading: KiteShading, ctm: KiteMatrix, clipPath: KitePath?, alpha: Double = 1.0, blendMode: KiteBlendMode = KiteBlendMode.Normal): Boolean

Renders the complex shading types, so every backend supports them identically with no code of its own:

Link copied to clipboard

Sample a KiteShading.Axial or KiteShading.Radial at evenly-spaced stops between domain[0] and domain[1]. Returns parallel t and RGB arrays the backend uses to build a gradient brush. The default of 256 matches MuPDF, so a function with many narrow bands keeps them all (#153).

Link copied to clipboard
fun shrinkArgb(width: Int, height: Int, shrinkX: Int, shrinkY: Int, readRows: (pixels: IntArray, y: Int, rows: Int) -> Unit): ByteArray

A bitmap of width by height straight (not premultiplied) ARGB pixels, averaged down like shrinkRgba into straight RGBA bytes. readRows fills its array with the rows rows that start at row y, shrinkY rows at a time, so a large decoded bitmap is never copied whole.

Link copied to clipboard
fun shrinkRgba(rgba: ByteArray, width: Int, height: Int, shrinkX: Int, shrinkY: Int): ByteArray

rgba, straight RGBA of width by height pixels, averaged down by shrinkX columns and shrinkY rows into each output pixel. A block at the right or bottom edge averages the pixels it has. Colours are weighted by their alpha, so a transparent pixel does not darken its neighbours. The result is ceil(width / shrinkX) by ceil(height / shrinkY) pixels.

Link copied to clipboard

glyphs cut into pieces that each shape as one unit. A glyph that the document spaces after, by character or word spacing, ends its piece, and a spaced blank glyph is a piece of its own. A run without spacing stays one piece, which keeps its ligatures and combining marks.

Link copied to clipboard

This axial or radial shading continued past its ends by spread, over a region whose bounds in shading space are region. The result is an ordinary shading that every canvas paints: its geometry grows to cover the region, and a stitching function (ISO 32000-1, 7.10.4) repeats or mirrors the colours once per period.

Link copied to clipboard
fun KitePath.strokeOutline(lineWidth: Double, lineCap: Int = 0, lineJoin: Int = 0, miterLimit: Double = 10.0, dashArray: List<Double>? = null, dashPhase: Double = 0.0, tolerance: Double = 0.1): KitePath

The area that stroking this path paints, as a path to fill with the nonzero rule. The pen is round in path space, so the outline filled under a non-uniform matrix gives the elliptical pen that ISO 32000-1, 8.5.3.2 describes.

Link copied to clipboard
fun strokePen(ctm: KiteMatrix, lineWidth: Double, hairlinePx: Double = 1.0): KiteStrokePen

The pen for a stroke lineWidth user units wide under ctm.

Link copied to clipboard

These pixels as an image that a canvas draws, smoothed when it is scaled.

Link copied to clipboard

Assemble a Kind.RAW image's already-decoded samples into a flat RGBA8888 buffer (R,G,B,A per pixel, row-major, no padding) that a platform backend can wrap in a bitmap.

Link copied to clipboard

The straight RGBA bitmap a canvas draws with sampling, of KiteImageSampling.rasterWidth by KiteImageSampling.rasterHeight pixels. Power-of-two averaging keeps decoding and colour conversion bounded; a filter widened to cover each destination pixel handles the remaining reduction (#626). ISO 32000-1, 8.9.5.3 leaves the interpolation filter to the reader.

Link copied to clipboard
fun KiteImageData.toShrunkRgbaBytes(shrinkX: Int, shrinkY: Int): ByteArray?

toRgbaBytes, averaged down by shrinkX columns and shrinkY rows as shrinkRgba does. The image converts a band of rows at a time, so a large scan drawn small never becomes one full-size RGBA array, and the pixel limit applies to the smaller output (#381).

Link copied to clipboard
fun twoCircleParameter(x: Double, y: Double, x0: Double, y0: Double, r0: Double, x1: Double, y1: Double, r1: Double): Double?

The parameter s of a gradient between the circles (x0, y0, r0) and (x1, y1, r1) at the point (x, y), all in shading space, for a canvas whose platform has no such gradient: Android before API 31 (#413, #591). It is the largest s whose circle, centred at c0 + s (c1 - c0) with a radius r0 + s (r1 - r0) of at least 0, passes through the point, as a platform gradient picks it (ISO 32000-1, 8.7.4.5.4). Null when no such circle passes through the point.

Link copied to clipboard

This state with colours converting through intent, with or without black point compensation. The current colours convert again from their components, so a colour set before ri follows it, as it does in MuPDF (#201).