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.
| Property | Type | Notes |
|---|---|---|
source | PdfSource? | What to open. Ignored when controller is set. |
controller | FidelityController? | An external document. Not disposed by the widget. |
camera | CameraSystem? | An external camera, to drive zoom from outside. |
config | FidelityConfig | Tunables. Ignored when controller is set. |
initialPage | int | 0-based. Default 0. |
backgroundColor | Color | The surround behind the page. |
loadingBuilder | WidgetBuilder? | Shown while opening. |
errorBuilder | Widget Function(BuildContext, Object)? | Receives the typed error. |
onDocumentReady | void Function(FidelityController)? | Fires once the document opens. |
minZoom / maxZoom | double | Only 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.
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, {...}); | Member | Type | Notes |
|---|---|---|
showPage(int) | void | Synchronous — the document is already resident. |
currentPage | int | 0-based; -1 before the first page. |
pageCount | int | Images are always 1. |
info | PdfDocumentInfo | Page sizes in points, known at open. |
format | DocumentFormat | Sniffed from the bytes. |
thumbnails | PdfThumbnailer | Created on first use. |
pageWorldBounds | Rect | Pass to camera.fitTo(). |
maxUsefulZoom | double? | Where the source runs out of detail. null for PDFs. |
estimateMemory(int) | FidelityMemoryEstimate | Pass the source byte length. |
tileStore / pyramid | TileStore? / TilePyramid? | For a hand-built TileLayer. |
dispose() | void | Tears 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.
| Field | Default | What it costs |
|---|---|---|
workers | 3 | Parallelism and the memory multiplier: each worker holds a private copy of the file. Budget workers × fileSize. Clamped 1–8. |
pageCacheSize | 2 | Parsed pages held open per worker. A parsed CAD page is enormous; this multiplies by workers. |
previewSize | 1600 | Longest 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. |
prefetchRing | 1 | Rings 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. |
maxCachedTiles | 256 | Decoded tiles for the current page, tileSize² × 4 each (~1 MB). |
tileSize | 512 | Bigger = fewer, larger renders and fewer draw calls. |
thumbnailSize | 160 | Longest thumbnail edge, in pixels. |
thumbnailCacheBytes | 32 MB | Byte budget for the thumbnail LRU. |
maxMagnification | 4.0 | How 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. |
wasmUrl | null | Self-hosted pdfium.wasm. |
workerUrl | null | Self-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
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
| Member | Notes |
|---|---|
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.
| Member | Notes |
|---|---|
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. |
maxZoom | Settable — the sensible ceiling belongs to the document, which the camera cannot know at construction. |
rasterDpr | You must set this when not using FidelityPdfView. Forget it and every tile renders at 1× on a 2× display. |
viewportSize | Written by TileLayer during paint. |
isZoomingActively | Inferred 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.
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
maxUsefulScale — null for vector sources,
1.0 for raster.
Error types
| Reason | Means |
|---|---|
blobWorkerBlocked | The one that happens. A CSP refuses blob: workers. Self-host via workerUrl. |
pdfiumInitFailed | The worker started but pdfium did not. Bounded by a 30s timeout. |
imageDecodeFailed | The image could not be decoded. |
noWorkers | No Worker constructor. |
noWebAssembly / wasmBlocked | Reported for completeness. Unreachable in practice — Flutter web renders via CanvasKit/skwasm, which are themselves WebAssembly, so the app cannot boot without it. |