Reference

API reference

Everything exported from package:fidelity_pdf/fidelity_pdf.dart.

FidelityPdfView

The drop-in viewer: opens a source, renders it, handles pan and zoom. Give it a source to own the document, or a controller to keep ownership yourself.

PropertyTypeNotes
sourcePdfSource?What to open. Ignored when controller is set.
controllerFidelityController?An external document. Not disposed by the widget.
cameraCameraSystem?An external camera, to drive zoom from outside.
configFidelityConfigTunables. Ignored when controller is set.
initialPageint0-based. Default 0.
backgroundColorColorThe surround behind the page.
loadingBuilderWidgetBuilder?Shown while opening.
errorBuilderWidget Function(BuildContext, Object)?Receives the typed error.
onDocumentReadyvoid Function(FidelityController)?Fires once the document opens.
minZoom / maxZoomdoubleOnly used for a camera the widget creates.

Never wrap this in InteractiveViewer or Transform.scale. Those scale the rendered output, so the camera still believes zoom == 1, picks the lowest detail level, and lets Flutter upscale it — a blurry stretched bitmap. Zoom must be reported to the engine, never applied to it. Drive CameraSystem from your gestures instead.

FidelityController

One open document: owns the engine, the page in view, and the thumbnails.

open.dart
static Future<FidelityController> open(
  PdfSource source, {
  required CameraSystem camera,
  FidelityConfig config = const FidelityConfig(),
  Offset origin = Offset.zero,
});

// For bytes already in hand:
static Future<FidelityController> openBytes(Uint8List bytes, {...});
MemberTypeNotes
showPage(int)voidSynchronous — the document is already resident.
currentPageint0-based; -1 before the first page.
pageCountintImages are always 1.
infoPdfDocumentInfoPage sizes in points, known at open.
formatDocumentFormatSniffed from the bytes.
thumbnailsPdfThumbnailerCreated on first use.
pageWorldBoundsRectPass to camera.fitTo().
maxUsefulZoomdouble?Where the source runs out of detail. null for PDFs.
estimateMemory(int)FidelityMemoryEstimatePass the source byte length.
tileStore / pyramidTileStore? / TilePyramid?For a hand-built TileLayer.
dispose()voidTears down the engine and every worker.

It is a ChangeNotifier: it notifies on page changes so a page rail can follow along.

FidelityConfig

Immutable value type — safe to compare and to gate rebuilds on.

FieldDefaultWhat it costs
workers3Parallelism and the memory multiplier: each worker holds a private copy of the file. Budget workers × fileSize. Clamped 1–8.
pageCacheSize2Parsed pages held open per worker. A parsed CAD page is enormous; this multiplies by workers.
previewSize1600Longest edge of the whole-page preview — one render, which is why the page never pops in tile by tile. Pinned and never evicted, outside maxCachedTiles (~9.8 MB). 0 disables.
prefetchRing1Rings of off-screen tiles rendered ahead at background priority, so a pan lands on decoded tiles. Ring 1 ≈ 2.5× the visible tiles. 0 disables.
maxCachedTiles256Decoded tiles for the current page, tileSize² × 4 each (~1 MB).
tileSize512Bigger = fewer, larger renders and fewer draw calls.
thumbnailSize160Longest thumbnail edge, in pixels.
thumbnailCacheBytes32 MBByte budget for the thumbnail LRU.
maxMagnification4.0How far past native resolution the camera may zoom. Images only — a PDF is vector and unbounded. 1.0 forbids magnifying; double.infinity removes the limit.
wasmUrlnullSelf-hosted pdfium.wasm.
workerUrlnullSelf-hosted worker. Needed under a CSP refusing blob: workers.

FidelityConfig.lowMemory is a ready-made preset: 2 workers, one page each, a 64-tile cache.

FidelityMemoryEstimate

documentCopies, tileCache, pagePreview, thumbnailCache, total — all bytes.

total is a floor, not a budget: parsed pages are excluded, because pdfium's cost for an open page depends entirely on its content and cannot be predicted from the file size. It is usually the largest term, and it scales with workers × pageCacheSize.

PdfSource

sources.dart
PdfSource.url(String url, {Map<String, String>? headers, bool cache = true})
PdfSource.asset(String assetPath, {String? name})
PdfSource.bytes(Uint8List bytes, {String? name})

Throws PdfSourceException when the bytes cannot be fetched.

Document cache

PdfSource.url caches to disk by default (the Cache API on web) and reuses it on the next open. readCachedDocument(url), writeCachedDocument(url, bytes), evictCachedDocument(url) and clearDocumentCache() are exported for direct use. None of them throw.

It saves the download, not the memory. The bytes still enter each worker's wasm heap to be rendered, so a cached 100 MB file still costs workers × 100 MB once open.

DocumentFormat

pdf, png, jpeg, bmp, gif, webp, unknown, plus isImage. DocumentFormat.sniff(bytes) identifies by magic number. JPG and JPEG are one format.

PdfThumbnailer

MemberNotes
cached(int page)Non-blocking read. Safe from build. Never starts a render.
thumbnail(int page)Future<ui.Image?>. Concurrent callers share one render.
request(int page)Warm the cache without awaiting.

A ChangeNotifier; fires as each thumbnail lands. Renders go in at PdfEngine.backgroundPriority.

PdfThumbnail

The widget: handles request, cache, repaint and disposal. Takes thumbnailer, page, fit, placeholder.

CameraSystem

A (position, zoom) camera in page points. Translate and uniform scale only — rotation and non-uniform scale cannot be represented.

MemberNotes
zoomAt(Offset focal, double factor)Pinch/scroll anchor. Also marks zoom as active.
panByScreenDelta(Offset)Drag.
fitTo(Rect world)Defers until the viewport is known, so it is safe before first paint.
screenToWorld(Offset)Screen pixels → page points.
maxZoomSettable — the sensible ceiling belongs to the document, which the camera cannot know at construction.
rasterDprYou must set this when not using FidelityPdfView. Forget it and every tile renders at 1× on a 2× display.
viewportSizeWritten by TileLayer during paint.
isZoomingActivelyInferred from zoomAt(); the store defers rendering while true.

PdfEngine

The platform seam. Two implementations ship: a Web Worker pool running pdfium-wasm, and ImageEngine using createImageBitmap. Both satisfy the same contract, which is why the pyramid, store, camera and painter are identical for PDFs and images.

engine.dart
abstract class PdfEngine {
  int get concurrency;
  Future<PdfDocumentInfo> open(Uint8List bytes);
  Future<RenderedTile?> renderTile(
    int page, double l, double t, double r, double b, double scale, {
    int priority = tilePriority,
  });
  void dispose();

  static const int tilePriority = 0;       // what the user is looking at
  static const int backgroundPriority = 10; // thumbnails, prefetch
}

PdfDocumentInfo carries pageSizes and maxUsefulScalenull for vector sources, 1.0 for raster.

Error types

ReasonMeans
blobWorkerBlockedThe one that happens. A CSP refuses blob: workers. Self-host via workerUrl.
pdfiumInitFailedThe worker started but pdfium did not. Bounded by a 30s timeout.
imageDecodeFailedThe image could not be decoded.
noWorkersNo Worker constructor.
noWebAssembly / wasmBlockedReported for completeness. Unreachable in practice — Flutter web renders via CanvasKit/skwasm, which are themselves WebAssembly, so the app cannot boot without it.