fromCommands static method

Future<PdfRetainedScene> fromCommands(
  1. PdfPage page,
  2. List<PdfRenderCommand> commands, {
  3. PdfPageRenderPlan plan = const PdfPageRenderPlan(),
  4. bool includeImages = true,
  5. bool allowOverprintRerecord = false,
  6. bool retainDecodedPixels = false,
  7. bool? retainLocallyDecodedPixels,
  8. PdfSceneBuildTiming? timing,
  9. double? maxImagePixelRatio,
})

Builds a scene from an already-recorded commands buffer (e.g. one a PdfRenderWorker shipped back), decoding its images once. The buffer must have been recorded for page under plan. Set includeImages to false for a deliberate vector-only progressive buffer; image draws then stay transparent until a complete scene replaces it. allowOverprintRerecord marks a complete, unfiltered worker transcript as reconstructible for an optional exact overprint retry.

timing, when non-null, receives the duration of the decode pass - the perf log's way of splitting the render 'build' phase into image decode vs the canvas-call construction that follows. Null (the default) measures nothing.

maxImagePixelRatio caps each image decode to display resolution (decodeImages). This is the path that pays for a JPEG the worker shipped un-decoded (it cannot run the platform codec); the cap keeps that UI-thread decode at display size instead of the image's full native resolution. retainDecodedPixels preserves pixels already carried by a worker; retainLocallyDecodedPixels separately controls portable decoding done in this isolate and defaults to the same value.

Implementation

static Future<PdfRetainedScene> fromCommands(
  PdfPage page,
  List<PdfRenderCommand> commands, {
  PdfPageRenderPlan plan = const PdfPageRenderPlan(),
  bool includeImages = true,
  bool allowOverprintRerecord = false,
  bool retainDecodedPixels = false,
  bool? retainLocallyDecodedPixels,
  PdfSceneBuildTiming? timing,
  double? maxImagePixelRatio,
}) async {
  final keepLocalPixels = retainLocallyDecodedPixels ?? retainDecodedPixels;
  Map<Object, ui.Image> images = const <Object, ui.Image>{};
  final requests = <PdfImageRequest>[];
  if (includeImages) {
    PdfPageRenderer.collectImageRequests(commands, requests,
        distinctCells: true);
    // The clock exists only when a caller asked for the split; an ordinary
    // render never pays for it.
    final clock = timing == null ? null : (Stopwatch()..start());
    images = await decodeImages(page.document.cos, requests,
        cache: PdfImageCache.instance,
        maxImagePixelRatio: maxImagePixelRatio,
        imageDecodeHeadroom: 1,
        retainDecodedPixels: keepLocalPixels);
    if (!retainDecodedPixels && !keepLocalPixels) {
      _releaseDecodedImagePixels(requests, images);
    }
    if (clock != null) {
      timing!.decodeMs = clock.elapsedMicroseconds / 1000.0;
    }
  }
  final retainedRequests = !retainDecodedPixels && !keepLocalPixels
      ? null
      : <PdfImageRequest>[
          for (final request in requests)
            if (request.decoded != null &&
                images.containsKey(pdfImageKey(request)))
              request,
        ];
  return PdfRetainedScene._(
    page,
    plan,
    commands,
    images,
    retainedDecodedRequests: retainedRequests,
    imageDecodingAttempted: includeImages,
    recordingOptions: allowOverprintRerecord && includeImages
        ? (
            maxImagePixelRatio: maxImagePixelRatio,
            imageDecodeHeadroom: 1,
          )
        : null,
  );
}