StripPdfDevice class

PdfDevice that batches strip-rasterized paint into shader draws and routes everything else through an internal CanvasPdfDevice fallback.

Usage: construct per page, feed it a full interpreter walk, then await finish() before ending the picture recording; call dispose after endRecording() to release the atlas images.

Constructors

StripPdfDevice(Canvas canvas, {required PdfMatrix pageToDevice, required int deviceWidth, required int deviceHeight, required double pixelRatio, Map<Object, Image> images = const {}, StripPlan? precomputed, double slugMinGlyphPx = 4, bool? enableSlugGlyphs})
precomputed feeds the device a worker-binned StripPlan instead of binning locally: generator feeds are skipped entirely and each flush point consumes the plan batch tagged with its ordinal. The plan must have been binned for this exact geometry - usablePlan guards that (and the debug-delegate flags, which force local binning) - and finish verifies the flush-point count and full consumption before painting anything, throwing StripPlanMismatchError on desync so the caller can transparently re-run with local binning.
factory

Properties

binningEnabled bool
Whether strip-routed ops actually feed generator. False in precomputed-plan mode: routing and flush ordinals still advance, but no flatten/stroke-expansion/coverage work runs.
finalinherited
canvas Canvas
final
delegateAll bool
Debug routing predicates (see the class doc).
finalinherited
delegatedPaintCount int
Delegated paint ops routed through the fallback so far.
getter/setter pairinherited
delegateFills bool
finalinherited
delegateStrokes bool
finalinherited
delegateText bool
finalinherited
deviceHeight int
finalinherited
deviceWidth int
finalinherited
flushCount int
no setter
flushPointCount int
Flush points seen so far (every flush point counts, empty or not).
no setterinherited
generator → StripGenerator
finalinherited
hashCode int
The hash code for this object.
no setterinherited
images Map<Object, Image>
Pre-decoded images for the fallback device (same map as CanvasPdfDevice.images).
final
pageToDevice → PdfMatrix
Page space (PDF user space, y-up) -> device pixels (y-down), including /Rotate and pixelRatio.
finalinherited
pixelRatio double
The ratio baked into pageToDevice; binned strips are only valid at this ratio.
finalinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
slugFallbackOutlineRuns int
no setter
slugMinGlyphPx double
final
slugQuadCount int
Per-device Slug routing result, unlike the aggregate benchmark stats.
no setter
stripsActive bool
Whether paint ops may take the strip path right now: normal blend and not directly inside a knockout group (knockout elements composite with BlendMode.src, which batched srcOver quads can't express).
no setterinherited
usesPrecomputedPlan bool
Whether this device consumes a precomputed plan (after validation).
no setter

Methods

beginGroup(double alpha, {bool knockout = false}) → void
Brackets a transparency-group form (§11.6.6) whose composite result paints at alpha. Inside the group, alpha starts over at 1.0; the group then blends as one object. Non-compositing devices can treat the pair as a no-op - the group's content still arrives through the normal callbacks in between.
inherited
beginSoftMasked() → void
Starts capturing painted content that an ExtGState /SMask will mask. Visual devices open an offscreen layer; others can ignore the pair.
inherited
clipPath(PdfPath path, PdfFillRule rule) → void
Intersects the current clip with path.
inherited
delegateBeginGroup(double alpha, {required bool knockout}) → void
delegateBeginSoftMaskComposite({required bool luminosity, required PdfRect backdrop, required double backdropLuminance, required double transferScale, required double transferOffset}) → void
The two halves of the soft-mask composite. The base runs the mask group's drawMask() between them - through THIS device, so mask-group strips bin (and flush) identically on every subclass.
delegateBeginSoftMasked() → void
delegateClipPath(PdfPath path, PdfFillRule rule) → void
delegateDrawImage(PdfImageRequest request) → void
delegateDrawText(PdfTextRun run) → void
delegateEndGroup() → void
delegateFillMesh(PdfMesh mesh, double alpha) → void
delegateFillPath(PdfPath path, PdfColor color, PdfFillRule rule, double alpha) → void
Delegated paint ops (the base flushes before each).
delegateFillPathGradient(PdfPath path, PdfFillRule rule, PdfGradient gradient, double alpha) → void
delegateFinishSoftMaskComposite() → void
delegateRestore() → void
delegateSave() → void
Delegated state ops (no pixels; not flush points except clipPath and the group boundaries, which the base flushes before forwarding).
delegateSetBlendMode(PdfBlendMode mode) → void
delegateStrokePath(PdfPath path, PdfColor color, PdfStroke stroke, double alpha) → void
dispose() → void
Releases the decoded atlas images and vertex buffers. Call after the recording that finish painted into has ended (the picture keeps its own references).
drawImage(PdfImageRequest request) → void
inherited
drawText(PdfTextRun run) → void
emitBatch(int ordinal, StripBatchData? data) → void
Called at every flush point with the strips binned since the previous one (data null when nothing was binned, or when binningEnabled is off). ordinal is the flush point's 0-based index.
endGroup() → void
Composites the group opened by beginGroup.
inherited
endSoftMasked({required bool luminosity, required PdfRect backdrop, required void drawMask(), double backdropLuminance = 0, double transferScale = 1, double transferOffset = 0}) → void
Ends the capture opened by beginSoftMasked. drawMask paints the mask group's content through this same device; for luminosity masks the device converts the result's luminance to alpha over the backdrop box, then composites it into the captured content (dstIn). Areas the mask group doesn't paint take backdropLuminance (the luminance of the /BC backdrop colour, default black). The mask value is remapped through the /TR transfer function, linearised here as value * transferScale + transferOffset (identity by default). Devices that collect content from drawMask (e.g. image collectors) should invoke it even if they do no compositing.
inherited
fillMesh(PdfMesh mesh, double alpha) → void
Paints a Gouraud triangle mesh (mesh shadings, types 4–7). Vertices arrive in page space. Non-painting devices can ignore it; simple devices may fall back to PdfMesh.averageColor.
inherited
fillPath(PdfPath path, PdfColor color, PdfFillRule rule, double alpha) → void
inherited
fillPathGradient(PdfPath path, PdfFillRule rule, PdfGradient gradient, double alpha) → void
Fills with a gradient (axial/radial shading patterns and sh). Non-painting devices can ignore it; simple devices may fall back to fillPath with PdfGradient.averageColor.
inherited
finish() Future<void>
Decodes every batch's alpha atlas, then replays the tape onto canvas: fallback ops drive a real CanvasPdfDevice, strip batches draw as shader-carrying drawVertices under the device->page transform. Await before endRecording(); the device is unusable afterwards.
flushPending() → void
Runs one flush point: snapshots the generator's strips (when binning) and hands them to emitBatch with this point's ordinal. Call once more from the subclass's finish step so trailing strips land.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
restore() → void
Mirrors Q.
inherited
save() → void
Mirrors q. Saved state must include the clip.
inherited
setBlendMode(PdfBlendMode mode) → void
Sets the blend mode for subsequent painting (gs /BM). Non-compositing devices can ignore it.
inherited
strokePath(PdfPath path, PdfColor color, PdfStroke stroke, double alpha) → void
inherited
toString() String
A string representation of this object.
inherited

Operators

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

Static Properties

debugDelegateAll bool
Debug: route every paint through the fallback (no strips at all) to isolate tape/pipeline effects from strip rasterization quality.
getter/setter pair
debugDelegateFills bool
Debug: per-primitive fallback routing, for parity bisection.
getter/setter pair
debugDelegateStrokes bool
getter/setter pair
debugDelegateText bool
getter/setter pair
debugNoShader bool
Debug/benchmark: draw batches with a plain paint instead of the coverage shader (wrong output - quantifies the runtime-effect cost of software rasterization).
getter/setter pair
debugSlugMode double
Debug: slug shader diagnostic output mode (see pdf_slug.frag uDebug).
getter/setter pair
debugSlugParam double
Debug: mode parameter (uDebug.y - e.g. curve index for mode 3).
getter/setter pair
debugVerifyPrecomputed bool
Debug/test: with a precomputed plan, ALSO bin locally at every flush point and assert the plan's batch matches (ordinal presence, strip count, vertex arrays, atlas bytes) - the strongest form of the flush-ordinal parity invariant. Test-only; throws StateError on the first divergence.
getter/setter pair
slugGlyphs bool
Experimental Slug glyph rendering (B3): outline text draws as em-space quads evaluated by shaders/pdf_slug.frag against a per-flush curve atlas instead of strip binning; glyphs whose band lists overflow keep the strip path. Snapshotted per device at construction.
getter/setter pair
totalAtlasDecodeMicros int
Phase timing (microseconds), aggregated across devices: time awaiting alpha-atlas decodes vs replaying the tape (drawVertices + fallback ops). The interpret+strip-generation and toImage phases are timed by the renderer (see PdfPageRenderer profiling statics).
getter/setter pair
totalAtlasTexels int
getter/setter pair
totalDelegatedPaints int
getter/setter pair
totalFlushes int
getter/setter pair
totalPlanMismatches int
Precomputed plans rejected (stale geometry) or failing verification at finish - each one transparently fell back to local binning.
getter/setter pair
totalPlanPictures int
Pictures painted from a verified precomputed plan (no local binning).
getter/setter pair
totalReplayMicros int
getter/setter pair
totalRouteMicros int
Time spent synchronously routing the command list through the device (binning included when local; only routing + plan-batch upload when precomputed) - accumulated by PdfRetainedScene's strip replays. With totalReplayMicros this is the UI-thread-blocking share of a settle.
getter/setter pair
totalSlugAtlasTexels int
getter/setter pair
totalSlugFallbackOutlineRuns int
getter/setter pair
totalSlugQuads int
Slug-mode stats: glyph quads drawn and curve-atlas texels uploaded.
getter/setter pair
totalStripQuads int
getter/setter pair

Static Methods

resetStats() → void
usablePlan(StripPlan? plan, {required PdfMatrix pageToDevice, required int deviceWidth, required int deviceHeight, bool slugEnabled = false}) StripPlan?
Validates plan for a device about to be constructed with this geometry: null when no plan, when any debug-delegate flag forces local binning (the flags change ROUTING and the plan's producer ran without them), or - counted in totalPlanMismatches - when the plan was binned for different geometry (stale zoom/region). The matrix comparison is exact: the six coefficients round-trip bit-exactly through the worker.