PdfRenderWorker class abstract

Records a PDF page's interpreter callbacks into a portable command buffer OFF the UI thread, so the dominant render cost - the content-stream parse and interpreter walk - stops blocking frames while scrolling.

A worker owns a private copy of the document, opened from the same bytes on its own isolate (native), and answers record with the page's replayable PdfRenderCommand list, already deserialized from the wire format. The caller turns that into a ui.Picture with PdfPageRenderer.pictureFromCommands - a cheap replay. Image XObjects are serialized into the buffer, and the worker decodes them off-thread too (the premultiplied pixels ride on each command), so the main thread runs only the engine codec, never the pure-Dart inflate/colour-convert. Images that need the platform JPEG codec ship un-decoded and decode locally.

The worker's document is a fixed snapshot of the bytes it was started with. It is therefore only correct for a document whose pages don't change under it: the read-only reader, or an editor between edits. Callers driving an editing session must dispose and restart the worker when the document's bytes change (or simply not use one).

Implementers

Constructors

PdfRenderWorker()
const

Properties

concurrentRecordCapacity int
Maximum number of page records this backend can execute concurrently.
no setter
hashCode int
The hash code for this object.
no setterinherited
isActive bool
Whether this worker actually offloads. False for the null fallback, so callers can skip the round-trip and render locally without asking.
no setter
lastRenderTrace PdfRenderTrace?
The unified PdfRenderTrace for the most recently completed job, or null when no job has finished or this backend does not collect timings.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
supportsPageSurfaces bool
Whether this backend can bind a browser-owned zero-copy page surface.
no setter
supportsRevisionUpdate bool
Whether this backend can absorb an updateRevision in place instead of being torn down and restarted on every edit. The native isolate backend (and the wrappers around it) do; the null fallback and the web backend do not yet, so their host restarts the worker on a revision change as before.
no setter

Methods

binStrips(int pageIndex, {required bool annotations, required List<double> pageToDevice, required int deviceWidth, required int deviceHeight, required double pixelRatio, bool slugGlyphs = false, int priority = 0}) Future<StripPlan?>
Bins page pageIndex's sparse strips off-thread for the exact device geometry a strip-routed zoom settle is about to rasterize, returning a StripPlan the caller feeds to StripPdfDevice(precomputed:) (via PdfRetainedScene.rasterizeStrips(stripPlan:)), or null when the page can't be binned off-thread - the platform has no worker, the worker failed/was disposed/was cancelled, or the page declines - and the caller bins locally.
buildRegionIndex(int pageIndex, {required bool annotations, required int maxCommands, required bool buildGrid, int priority = 0}) Future<PdfRegionReplayIndex?>
Builds page pageIndex's region-replay spatial index off-thread and ships it back reconstructed, or null when the page can't be offloaded (this platform has no worker, the worker failed/declined, or the page's content can't round-trip through the command codec).
cancel(int pageIndex, {int priority = 0}) → void
Drops any QUEUED (not yet started) record request for pageIndex at priority, completing its future with null - as if the page had declined to a local render. A cheap no-op when nothing matches.
cancelBinStrips(int pageIndex, {int priority = 0}) → void
Drops any QUEUED (not yet started) binStrips request for pageIndex at priority, completing its future with null - and, on the native isolate backend, also preempts a matching IN-FLIGHT bin cooperatively so the worker abandons the stale geometry mid-walk (its future resolves null too). Superseded settles and overtaken speculative bins call this so the worker bins the geometry the user is actually looking at instead of a stale one; the abandoning caller must not fall back to a local bin for the superseded settle (PdfPageView's generation guard takes care of that). Unlike cancel, the in-flight preemption is safe here because strip plans are never shared between callers (the caching wrapper passes bins straight through).
createPageSurface(Object surface, {int? pageIndex}) PdfPageSurfaceSession?
Transfers an opaque browser canvas to this worker and binds it for the lifetime of the returned session. Native and unsupported backends return null. pageIndex lets a pool bind a base canvas and its deep-zoom region to the same worker, reusing that worker's transcript and image samples. See PdfPageSurfaceSession for the correctness-gated fallback.
dispose() → void
Tears the worker down (kills the isolate, fails pending requests with null). Idempotent.
extractText(int pageIndex, {int priority = 0}) Future<PdfPageText?>
Extracts pageIndex's text off the UI isolate for search and hover (#396). PdfTextExtractor.extract is pure Dart, so a heavy page's extraction (a full content walk) freezes a frame when it runs on the UI thread; a worker moves it off. priority shares the queue ordering with record.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
record(int pageIndex, {bool annotations = true, int priority = 0, double? imagePixelRatio, bool decodeImages = true, int? commandLimit, PdfRect? imageDecodeRegion, PdfPartialRecordSink? onPartial}) Future<List<PdfRenderCommand>?>
Records page pageIndex off-thread and returns its replayable command buffer (image XObjects decoded off-thread and attached), or null when the page can't be offloaded - it draws an inline image (BI .. ID .. EI, which can name a page-resource colour space the stream can't reach), the worker failed or was disposed, or this platform has no worker - and the caller must render the page locally.
recordStripDetail(int pageIndex, {required bool annotations, required List<double> pageToDevice, required int deviceWidth, required int deviceHeight, required double pixelRatio, required PdfRect imageDecodeRegion, int priority = 0}) Future<PdfStripDetail?>
Records a region-detail command buffer and bins that exact buffer for a strip-routed deep-zoom patch in one worker job.
releaseCachedPage(int pageIndex) → void
Releases completed reusable command records for pageIndex.
toString() String
A string representation of this object.
inherited
updateRevision(int baseLength, Uint8List appendedBytes, int newLength, Set<int>? changedPages) → void
Feeds one append-only editor revision into the worker's already-open document instead of disposing and restarting it, then invalidates the worker's cached renders for the changedPages only.

Operators

operator ==(Object other) bool
The equality operator.
inherited

Static Methods

disposePrewarm() → void
Terminates any prewarmed-but-unadopted workers (prewarm).
prewarm({int? count}) → void
Warms the platform render worker ahead of a document, so its startup cost overlaps whatever the user is doing (choosing or loading a file) instead of blocking the first render. On the web this fetches, compiles, and boots the ~1 MB worker script now (~1.45 s on a phone, #450); a later start adopts the pre-booted worker and only hands off the document (a few tens of ms). No-op on native (isolate spawn is cheap) and where no worker is configured.
start(Uint8List bytes) PdfRenderWorker
Starts the platform's worker over bytes (the document image the page indices passed to record refer to). Native: a long-lived background isolate that opens its own PdfDocument. Web: a Web Worker over the script at pdfRenderWorkerScriptUrl when one is configured (by default the bundled package asset, else a null worker). Platforms without either: a null worker whose record always defers to local rendering.
startUncached(Uint8List bytes) PdfRenderWorker
The raw platform worker, NOT wrapped in PdfCachingRenderWorker. Test- only: for exercising the inner queue/cancel/priority contract, which the cache is designed to short-circuit (a cached page never re-enters the queue). Production code uses start. (No @visibleForTesting annotation because this library stays Flutter-free so the web worker can compile via dart compile js without pulling in Flutter.)