LCOV - code coverage report
Current view: top level - src/document - isolate_messages.dart Coverage Total Hit
Test: lcov.info Lines: 100.0 % 67 67
Test Date: 2026-08-24 04:28:45 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2026 The Authors.
       2              : //
       3              : // Licensed under the Apache License, Version 2.0 (the "License");
       4              : // you may not use this file except in compliance with the License.
       5              : // You may obtain a copy of the License at
       6              : //
       7              : //     https://www.apache.org/licenses/LICENSE-2.0
       8              : //
       9              : // Unless required by applicable law or agreed to in writing, software
      10              : // distributed under the License is distributed on an "AS IS" BASIS,
      11              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12              : // See the License for the specific language governing permissions and
      13              : // limitations under the License.
      14              : 
      15              : // Typed message protocol for the PdfiumIsolate.
      16              : //
      17              : // All communication with the PDFium isolate uses this sealed class hierarchy.
      18              : // Each message carries a [SendPort] for the response so that concurrent
      19              : // requests can be tracked and matched independently.
      20              : //
      21              : // Future plans (text extraction, annotations, rendering) extend this protocol
      22              : // by adding new [PdfiumCommand] subtypes without coupling their public APIs
      23              : // to this file.
      24              : 
      25              : import 'dart:isolate';
      26              : import 'dart:typed_data';
      27              : 
      28              : import 'pdf_types.dart';
      29              : import '../rendering/pdf_page_size.dart';
      30              : 
      31              : /// Base class for all commands sent to the [PdfiumIsolate].
      32              : ///
      33              : /// Each command carries a [replyPort] — the [SendPort] on which the isolate
      34              : /// sends the [PdfiumResponse] for this specific request.
      35              : sealed class PdfiumCommand {
      36              :   /// Creates a command with the given [replyPort].
      37           11 :   const PdfiumCommand(this.replyPort);
      38              : 
      39              :   /// The port on which the isolate must send the response for this command.
      40              :   final SendPort replyPort;
      41              : }
      42              : 
      43              : /// Initialise the PDFium library within the isolate.
      44              : ///
      45              : /// This is the first message sent after the isolate starts. The isolate
      46              : /// responds with a [PdfiumInitResponse] carrying the [SendPort] for
      47              : /// subsequent commands.
      48              : class PdfiumInitCommand extends PdfiumCommand {
      49              :   /// Creates an init command.
      50           10 :   const PdfiumInitCommand(super.replyPort, this.dylibPath);
      51              : 
      52              :   /// The filesystem path to the PDFium dynamic library, or `null` to let
      53              :   /// the isolate auto-detect the library via [_openLibrary].
      54              :   ///
      55              :   /// Pass a non-null path to override auto-detection (e.g. for the legacy
      56              :   /// `third_party/pdfium_bin/` developer layout populated by
      57              :   /// `make fetch_pdfium`). Pass `null` when the native-assets hook has staged
      58              :   /// the library (pub.dev users, CI without `make fetch_pdfium`) or when
      59              :   /// loading from the process image (iOS static link).
      60              :   final String? dylibPath;
      61              : }
      62              : 
      63              : /// Load a PDF document from raw bytes.
      64              : ///
      65              : /// The isolate calls `FPDF_LoadMemDocument64()` and returns a document token
      66              : /// (an opaque integer handle) that the caller uses in subsequent commands.
      67              : class PdfiumLoadDocumentCommand extends PdfiumCommand {
      68              :   /// Creates a load-document command.
      69           10 :   const PdfiumLoadDocumentCommand(super.replyPort, this.bytes);
      70              : 
      71              :   /// The raw PDF bytes to load.
      72              :   final Uint8List bytes;
      73              : }
      74              : 
      75              : /// Read the Info dictionary metadata for an open document.
      76              : ///
      77              : /// The isolate reads all eight standard Info dictionary fields using
      78              : /// `FPDF_GetMetaText()` and returns a [PdfiumGetMetadataResponse].
      79              : class PdfiumGetMetadataCommand extends PdfiumCommand {
      80              :   /// Creates a get-metadata command for the document identified by [token].
      81            2 :   const PdfiumGetMetadataCommand(super.replyPort, this.token);
      82              : 
      83              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
      84              :   final int token;
      85              : }
      86              : 
      87              : /// Read document-level properties (version and file identifiers).
      88              : ///
      89              : /// The isolate calls `FPDF_GetFileVersion()` and `FPDF_GetFileIdentifier()`
      90              : /// in a single round-trip and returns a [PdfiumGetDocumentInfoResponse].
      91              : class PdfiumGetDocumentInfoCommand extends PdfiumCommand {
      92              :   /// Creates a get-document-info command for the document identified by [token].
      93            2 :   const PdfiumGetDocumentInfoCommand(super.replyPort, this.token);
      94              : 
      95              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
      96              :   final int token;
      97              : }
      98              : 
      99              : /// Close a previously loaded document and release its native handle.
     100              : ///
     101              : /// The isolate calls `FPDF_CloseDocument()` and responds with a
     102              : /// [PdfiumCloseDocumentResponse].
     103              : class PdfiumCloseDocumentCommand extends PdfiumCommand {
     104              :   /// Creates a close-document command for the document identified by [token].
     105           10 :   const PdfiumCloseDocumentCommand(super.replyPort, this.token);
     106              : 
     107              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     108              :   final int token;
     109              : }
     110              : 
     111              : /// Get the total number of pages in an open document.
     112              : ///
     113              : /// The isolate calls `FPDF_GetPageCount()` and responds with a
     114              : /// [PdfiumGetPageCountResponse].
     115              : class PdfiumGetPageCountCommand extends PdfiumCommand {
     116              :   /// Creates a get-page-count command for the document identified by [token].
     117            7 :   const PdfiumGetPageCountCommand(super.replyPort, this.token);
     118              : 
     119              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     120              :   final int token;
     121              : }
     122              : 
     123              : /// Extract plain text from a single page of an open document.
     124              : ///
     125              : /// The isolate loads the page, loads the text page, extracts all text, then
     126              : /// closes both handles in a single round-trip. The response is a
     127              : /// [PdfiumExtractPageTextResponse] carrying the result.
     128              : ///
     129              : /// [PdfiumExtractPageTextResponse.hasTextLayer] is true whenever PDFium
     130              : /// extracts at least one character from the page — the only reliable signal
     131              : /// that a text layer exists.
     132              : class PdfiumExtractPageTextCommand extends PdfiumCommand {
     133              :   /// Creates an extract-page-text command.
     134            2 :   const PdfiumExtractPageTextCommand(
     135              :     super.replyPort,
     136              :     this.token,
     137              :     this.pageIndex,
     138              :   );
     139              : 
     140              :   /// The opaque document token.
     141              :   final int token;
     142              : 
     143              :   /// Zero-based index of the page to extract text from.
     144              :   final int pageIndex;
     145              : }
     146              : 
     147              : /// Get the intrinsic size of a single page of an open document.
     148              : ///
     149              : /// The isolate calls `FPDF_GetPageWidthF()` and `FPDF_GetPageHeightF()` and
     150              : /// returns a [PdfiumGetPageSizeResponse] containing a [PdfPageSize].
     151              : class PdfiumGetPageSizeCommand extends PdfiumCommand {
     152              :   /// Creates a get-page-size command.
     153            3 :   const PdfiumGetPageSizeCommand(super.replyPort, this.token, this.pageIndex);
     154              : 
     155              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     156              :   final int token;
     157              : 
     158              :   /// Zero-based index of the page whose size is requested.
     159              :   final int pageIndex;
     160              : }
     161              : 
     162              : /// Render a single page of an open document to a BGRA pixel buffer.
     163              : ///
     164              : /// The isolate allocates a bitmap of [pixelWidth] × [pixelHeight] pixels,
     165              : /// fills it with [backgroundColor] (in `0xAARRGGBB` format), calls
     166              : /// `FPDF_RenderPageBitmap()` with the given [renderFlags], copies the
     167              : /// resulting BGRA bytes into a [Uint8List], then destroys the bitmap handle
     168              : /// and closes the page handle.
     169              : ///
     170              : /// Render flags are the raw PDFium integer flags (e.g. `FPDF_ANNOT`,
     171              : /// `FPDF_LCD_TEXT`). The public [PdfDocument.renderPage] method converts
     172              : /// [PdfRenderOptions] fields to these flags before dispatching this command.
     173              : class PdfiumRenderPageCommand extends PdfiumCommand {
     174              :   /// Creates a render-page command.
     175            3 :   const PdfiumRenderPageCommand(
     176              :     super.replyPort,
     177              :     this.token,
     178              :     this.pageIndex,
     179              :     this.pixelWidth,
     180              :     this.pixelHeight,
     181              :     this.renderFlags,
     182              :     this.backgroundColor,
     183              :   );
     184              : 
     185              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     186              :   final int token;
     187              : 
     188              :   /// Zero-based index of the page to render.
     189              :   final int pageIndex;
     190              : 
     191              :   /// Width of the output bitmap in pixels.
     192              :   final int pixelWidth;
     193              : 
     194              :   /// Height of the output bitmap in pixels.
     195              :   final int pixelHeight;
     196              : 
     197              :   /// PDFium render flags (e.g. `FPDF_ANNOT`, `FPDF_LCD_TEXT`).
     198              :   final int renderFlags;
     199              : 
     200              :   /// Background colour in `0xAARRGGBB` format, used to fill the bitmap before
     201              :   /// rendering. Opaque white is `0xFFFFFFFF`.
     202              :   final int backgroundColor;
     203              : }
     204              : 
     205              : /// Retrieve the complete bookmark/outline tree for an open document.
     206              : ///
     207              : /// The isolate walks the bookmark tree using `FPDFBookmark_GetFirstChild`,
     208              : /// `FPDFBookmark_GetNextSibling`, and `FPDFBookmark_GetAction` / destination
     209              : /// resolution, building a `List<PdfTocEntry>` in a single recursive pass.
     210              : ///
     211              : /// Documents without any bookmarks produce an empty list — not an error.
     212              : ///
     213              : /// The recursive [PdfTocEntry] tree is deep-copied across the isolate
     214              : /// boundary by Dart's message-passing mechanism (Dart serialises arbitrary
     215              : /// Dart objects by value when they are sent across isolate boundaries). This
     216              : /// is acceptable for the bounded sizes of typical PDF bookmark trees (hundreds
     217              : /// to low thousands of entries at most).
     218              : class PdfiumGetTocCommand extends PdfiumCommand {
     219              :   /// Creates a get-TOC command for the document identified by [token].
     220            1 :   const PdfiumGetTocCommand(super.replyPort, this.token);
     221              : 
     222              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     223              :   final int token;
     224              : }
     225              : 
     226              : /// Extract all annotations from a single page of an open document.
     227              : ///
     228              : /// The isolate opens the page, iterates all annotations via
     229              : /// `FPDFPage_GetAnnotCount()` / `FPDFPage_GetAnnot()`, extracts all fields,
     230              : /// closes each annotation handle and the page handle, then sends a
     231              : /// [PdfiumExtractPageAnnotationsResponse].
     232              : ///
     233              : /// Pages with no annotations produce a response with an empty [annotations]
     234              : /// list — not an error.
     235              : class PdfiumExtractPageAnnotationsCommand extends PdfiumCommand {
     236              :   /// Creates an extract-page-annotations command.
     237            2 :   const PdfiumExtractPageAnnotationsCommand(
     238              :     super.replyPort,
     239              :     this.token,
     240              :     this.pageIndex,
     241              :   );
     242              : 
     243              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     244              :   final int token;
     245              : 
     246              :   /// Zero-based index of the page whose annotations are to be extracted.
     247              :   final int pageIndex;
     248              : }
     249              : 
     250              : /// Extract all image objects from a single page of an open document.
     251              : ///
     252              : /// The isolate opens the page, iterates all page objects via
     253              : /// `FPDFPage_CountObjects()` / `FPDFPage_GetObject()`, filters for objects
     254              : /// of type `FPDF_PAGEOBJ_IMAGE`, extracts metadata and (optionally) renders
     255              : /// the bitmap for each, then closes the page handle and sends a
     256              : /// [PdfiumExtractPageImagesResponse].
     257              : ///
     258              : /// Pages with no image objects produce a response with an empty [images] list
     259              : /// — not an error.
     260              : ///
     261              : /// When [includeBitmap] is `false` (the default), the bitmap is not rendered;
     262              : /// [PdfImage.bgra], [PdfImage.bitmapWidth], and [PdfImage.bitmapHeight] will
     263              : /// be `null` in every [PdfImage] in the response.
     264              : class PdfiumExtractPageImagesCommand extends PdfiumCommand {
     265              :   /// Creates an extract-page-images command.
     266            1 :   const PdfiumExtractPageImagesCommand(
     267              :     super.replyPort,
     268              :     this.token,
     269              :     this.pageIndex, {
     270              :     this.includeBitmap = false,
     271              :   });
     272              : 
     273              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     274              :   final int token;
     275              : 
     276              :   /// Zero-based index of the page whose images are to be extracted.
     277              :   final int pageIndex;
     278              : 
     279              :   /// When true, the rendered BGRA bitmap is fetched for each image object.
     280              :   ///
     281              :   /// Setting this to `true` calls `FPDFImageObj_GetRenderedBitmap` for every
     282              :   /// image on the page, which is significantly more expensive than metadata-
     283              :   /// only extraction. For selective on-demand bitmap fetches, prefer sending
     284              :   /// individual [PdfiumRenderImageCommand] requests.
     285              :   final bool includeBitmap;
     286              : }
     287              : 
     288              : /// Search for text on a single page of an open document.
     289              : ///
     290              : /// The isolate loads the page's text layer via `FPDFText_LoadPage`, then
     291              : /// calls `FPDFText_FindStart` with the provided [query] (encoded as UTF-16LE)
     292              : /// and [flags] bitmask. It iterates `FPDFText_FindNext` to collect all
     293              : /// matches, calling `FPDFText_GetSchResultIndex`, `FPDFText_GetSchCount`,
     294              : /// `FPDFText_CountRects`, and `FPDFText_GetRect` for each. All handles are
     295              : /// closed in a `try/finally` block. The response is a
     296              : /// [PdfiumSearchPageResponse].
     297              : ///
     298              : /// The [flags] field is a PDFium bitmask built from [PdfSearchFlag] values:
     299              : /// - `0x01` = `FPDF_MATCHCASE`
     300              : /// - `0x02` = `FPDF_MATCHWHOLEWORD`
     301              : /// - `0x04` = `FPDF_CONSECUTIVE`
     302              : ///
     303              : /// An empty [query] string must be rejected by the caller before dispatching
     304              : /// this command; the isolate does not guard against it.
     305              : ///
     306              : /// Pages with no text layer produce a response with an empty matches list —
     307              : /// not an error.
     308              : class PdfiumSearchPageCommand extends PdfiumCommand {
     309              :   /// Creates a search-page command.
     310            1 :   const PdfiumSearchPageCommand(
     311              :     super.replyPort,
     312              :     this.token,
     313              :     this.pageIndex,
     314              :     this.query,
     315              :     this.flags,
     316              :   );
     317              : 
     318              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     319              :   final int token;
     320              : 
     321              :   /// Zero-based index of the page to search.
     322              :   final int pageIndex;
     323              : 
     324              :   /// The search query string (must be non-empty; the caller is responsible for
     325              :   /// guarding against empty queries).
     326              :   final String query;
     327              : 
     328              :   /// PDFium search flags bitmask (`FPDF_MATCHCASE | FPDF_MATCHWHOLEWORD |
     329              :   /// FPDF_CONSECUTIVE`).
     330              :   final int flags;
     331              : }
     332              : 
     333              : /// Fetch the rendered BGRA bitmap for a single image object on a page.
     334              : ///
     335              : /// The isolate opens the page, retrieves the object at [objectIndex] via
     336              : /// `FPDFPage_GetObject`, verifies that its type is `FPDF_PAGEOBJ_IMAGE`,
     337              : /// calls `FPDFImageObj_GetRenderedBitmap`, copies the BGRA bytes, destroys
     338              : /// the bitmap handle, and closes the page handle. Sends a
     339              : /// [PdfiumRenderImageResponse].
     340              : ///
     341              : /// The response carries `bitmap: null` when the object at [objectIndex] is
     342              : /// not an image object, or when `FPDFImageObj_GetRenderedBitmap` returns null
     343              : /// (e.g. a mask-only object).
     344              : ///
     345              : /// The caller is responsible for range-checking [objectIndex] before
     346              : /// dispatching this command. If the object index is out of range for the page,
     347              : /// `FPDFPage_GetObject` returns null, and the response will carry
     348              : /// `bitmap: null`.
     349              : class PdfiumRenderImageCommand extends PdfiumCommand {
     350              :   /// Creates a render-image command.
     351            1 :   const PdfiumRenderImageCommand(
     352              :     super.replyPort,
     353              :     this.token,
     354              :     this.pageIndex,
     355              :     this.objectIndex,
     356              :   );
     357              : 
     358              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     359              :   final int token;
     360              : 
     361              :   /// Zero-based index of the page containing the image.
     362              :   final int pageIndex;
     363              : 
     364              :   /// Zero-based index of the page object to render (as returned by
     365              :   /// `FPDFPage_GetObject`). Must be an image-type object.
     366              :   final int objectIndex;
     367              : }
     368              : 
     369              : /// Retrieve the embedded thumbnail bitmap for a single page of an open document.
     370              : ///
     371              : /// The isolate opens the page via `FPDF_LoadPage`, calls
     372              : /// `FPDFPage_GetThumbnailAsBitmap`, and—if a bitmap is returned—reads its
     373              : /// pixel data into a [Uint8List] in BGRA format before destroying both the
     374              : /// bitmap and page handles. Sends a [PdfiumGetPageThumbnailResponse].
     375              : ///
     376              : /// When the page has no embedded thumbnail, `FPDFPage_GetThumbnailAsBitmap`
     377              : /// returns `nullptr`. The isolate treats this as a success with a `null` pixel
     378              : /// buffer (not an error), so the caller can decide whether to fall back to
     379              : /// rendering.
     380              : ///
     381              : /// The [token] is the opaque document token from a prior
     382              : /// [PdfiumLoadDocumentCommand]. The [pageIndex] is zero-based.
     383              : class PdfiumGetPageThumbnailCommand extends PdfiumCommand {
     384              :   /// Creates a get-page-thumbnail command.
     385            1 :   const PdfiumGetPageThumbnailCommand(
     386              :     super.replyPort,
     387              :     this.token,
     388              :     this.pageIndex,
     389              :   );
     390              : 
     391              :   /// The opaque document token returned by a prior [PdfiumLoadDocumentCommand].
     392              :   final int token;
     393              : 
     394              :   /// Zero-based index of the page whose embedded thumbnail is requested.
     395              :   final int pageIndex;
     396              : }
     397              : 
     398              : // ---------------------------------------------------------------------------
     399              : // Responses
     400              : // ---------------------------------------------------------------------------
     401              : 
     402              : /// Base class for all responses sent from the [PdfiumIsolate].
     403              : sealed class PdfiumResponse {
     404              :   /// Creates a response.
     405           19 :   const PdfiumResponse();
     406              : }
     407              : 
     408              : /// Sent when a command handler throws an unexpected Dart exception.
     409              : ///
     410              : /// This response is a diagnostic fallback — it means a bug exists in the
     411              : /// isolate handler code. The [error] and [stack] fields contain the exception
     412              : /// details so they surface in the main isolate's [StateError] rather than
     413              : /// disappearing into the spawned isolate's stderr.
     414              : class PdfiumHandlerErrorResponse extends PdfiumResponse {
     415              :   /// Creates a handler error response.
     416            1 :   const PdfiumHandlerErrorResponse(this.error, this.stack);
     417              : 
     418              :   /// A human-readable description of the exception.
     419              :   final String error;
     420              : 
     421              :   /// The stack trace at the point of the exception.
     422              :   final String stack;
     423              : }
     424              : 
     425              : /// Sent by the isolate after it has started and initialised PDFium.
     426              : ///
     427              : /// The [commandPort] is used for all subsequent commands.
     428              : class PdfiumInitResponse extends PdfiumResponse {
     429              :   /// Creates an init response.
     430           10 :   const PdfiumInitResponse(this.commandPort);
     431              : 
     432              :   /// The [SendPort] on which the isolate accepts subsequent [PdfiumCommand]s.
     433              :   final SendPort commandPort;
     434              : }
     435              : 
     436              : /// Sent by the isolate when PDFium library initialisation fails.
     437              : ///
     438              : /// This occurs when the dynamic library cannot be loaded (e.g. the path is
     439              : /// wrong or the binary is missing). The [message] field contains the
     440              : /// underlying error description.
     441              : class PdfiumInitFailedResponse extends PdfiumResponse {
     442              :   /// Creates a failure response with the given error [message].
     443            2 :   const PdfiumInitFailedResponse(this.message);
     444              : 
     445              :   /// A human-readable description of why initialisation failed.
     446              :   final String message;
     447              : }
     448              : 
     449              : /// Sent when a [PdfiumLoadDocumentCommand] succeeds.
     450              : class PdfiumLoadDocumentResponse extends PdfiumResponse {
     451              :   /// Creates a successful load response with the given document [token].
     452           10 :   const PdfiumLoadDocumentResponse.success(this.token) : error = null;
     453              : 
     454              :   /// Creates a failed load response with the given [error].
     455            1 :   const PdfiumLoadDocumentResponse.failure(this.error) : token = null;
     456              : 
     457              :   /// The opaque document token, or `null` on failure.
     458              :   final int? token;
     459              : 
     460              :   /// The error that occurred, or `null` on success.
     461              :   final PdfError? error;
     462              : 
     463              :   /// Whether the document was loaded successfully.
     464           20 :   bool get isSuccess => token != null;
     465              : }
     466              : 
     467              : /// Sent when a [PdfiumGetMetadataCommand] completes.
     468              : class PdfiumGetMetadataResponse extends PdfiumResponse {
     469              :   /// Creates a successful metadata response.
     470            2 :   const PdfiumGetMetadataResponse.success(this.metadata) : error = null;
     471              : 
     472              :   /// Creates a failed metadata response.
     473            1 :   const PdfiumGetMetadataResponse.failure(this.error) : metadata = null;
     474              : 
     475              :   /// The extracted metadata, or `null` on failure.
     476              :   final PdfMetadata? metadata;
     477              : 
     478              :   /// The error that occurred, or `null` on success.
     479              :   final PdfError? error;
     480              : }
     481              : 
     482              : /// Sent when a [PdfiumGetDocumentInfoCommand] completes.
     483              : class PdfiumGetDocumentInfoResponse extends PdfiumResponse {
     484              :   /// Creates a successful document-info response.
     485            2 :   const PdfiumGetDocumentInfoResponse.success(this.info) : error = null;
     486              : 
     487              :   /// Creates a failed document-info response.
     488            1 :   const PdfiumGetDocumentInfoResponse.failure(this.error) : info = null;
     489              : 
     490              :   /// The document info, or `null` on failure.
     491              :   final PdfDocumentInfo? info;
     492              : 
     493              :   /// The error that occurred, or `null` on success.
     494              :   final PdfError? error;
     495              : }
     496              : 
     497              : /// Sent when a [PdfiumCloseDocumentCommand] completes.
     498              : class PdfiumCloseDocumentResponse extends PdfiumResponse {
     499              :   /// Creates a close-document response.
     500           19 :   const PdfiumCloseDocumentResponse();
     501              : }
     502              : 
     503              : /// Sent when a [PdfiumGetPageCountCommand] completes.
     504              : class PdfiumGetPageCountResponse extends PdfiumResponse {
     505              :   /// Creates a successful page-count response.
     506            7 :   const PdfiumGetPageCountResponse.success(this.pageCount) : error = null;
     507              : 
     508              :   /// Creates a failed page-count response.
     509            1 :   const PdfiumGetPageCountResponse.failure(this.error) : pageCount = null;
     510              : 
     511              :   /// The total number of pages, or `null` on failure.
     512              :   final int? pageCount;
     513              : 
     514              :   /// The error that occurred, or `null` on success.
     515              :   final PdfError? error;
     516              : }
     517              : 
     518              : /// Sent when a [PdfiumExtractPageAnnotationsCommand] completes.
     519              : class PdfiumExtractPageAnnotationsResponse extends PdfiumResponse {
     520              :   /// Creates a successful annotation-extraction response.
     521            2 :   const PdfiumExtractPageAnnotationsResponse.success({
     522              :     required this.pageIndex,
     523              :     required List<PdfAnnotation> this._annotations,
     524              :   }) : error = null;
     525              : 
     526              :   /// Creates a failed annotation-extraction response.
     527            1 :   const PdfiumExtractPageAnnotationsResponse.failure(this.error, this.pageIndex)
     528              :     : _annotations = null;
     529              : 
     530              :   final List<PdfAnnotation>? _annotations;
     531              : 
     532              :   /// The zero-based page index this response corresponds to.
     533              :   final int pageIndex;
     534              : 
     535              :   /// The error that occurred, or `null` on success.
     536              :   final PdfError? error;
     537              : 
     538              :   /// Whether this response represents a successful extraction.
     539            4 :   bool get isSuccess => error == null;
     540              : 
     541              :   /// The list of extracted annotations. Only valid when [isSuccess] is true.
     542            4 :   List<PdfAnnotation> get annotations => _annotations!;
     543              : }
     544              : 
     545              : /// Sent when a [PdfiumGetPageSizeCommand] completes.
     546              : class PdfiumGetPageSizeResponse extends PdfiumResponse {
     547              :   /// Creates a successful page-size response.
     548            3 :   const PdfiumGetPageSizeResponse.success(this.pageSize) : error = null;
     549              : 
     550              :   /// Creates a failed page-size response.
     551            1 :   const PdfiumGetPageSizeResponse.failure(this.error) : pageSize = null;
     552              : 
     553              :   /// The page size, or `null` on failure.
     554              :   final PdfPageSize? pageSize;
     555              : 
     556              :   /// The error that occurred, or `null` on success.
     557              :   final PdfError? error;
     558              : 
     559              :   /// Whether the response represents a successful operation.
     560            6 :   bool get isSuccess => error == null;
     561              : }
     562              : 
     563              : /// Sent when a [PdfiumRenderPageCommand] completes.
     564              : class PdfiumRenderPageResponse extends PdfiumResponse {
     565              :   /// Creates a successful render response carrying the BGRA [_pixels] buffer
     566              :   /// and the actual rendered [pixelWidth] × [pixelHeight] dimensions.
     567            3 :   const PdfiumRenderPageResponse.success({
     568              :     required Uint8List this._pixels,
     569              :     required this.pixelWidth,
     570              :     required this.pixelHeight,
     571              :   }) : _errorMessage = null;
     572              : 
     573              :   /// Creates a failed render response with a descriptive [errorMessage].
     574            2 :   const PdfiumRenderPageResponse.failure(this._errorMessage)
     575              :     : _pixels = null,
     576              :       pixelWidth = 0,
     577              :       pixelHeight = 0;
     578              : 
     579              :   final Uint8List? _pixels;
     580              :   final String? _errorMessage;
     581              : 
     582              :   /// The width of the rendered bitmap in pixels. Only valid when [isSuccess].
     583              :   final int pixelWidth;
     584              : 
     585              :   /// The height of the rendered bitmap in pixels. Only valid when [isSuccess].
     586              :   final int pixelHeight;
     587              : 
     588              :   /// Whether the render succeeded.
     589            6 :   bool get isSuccess => _errorMessage == null;
     590              : 
     591              :   /// The BGRA pixel buffer. Only valid when [isSuccess] is `true`.
     592            6 :   Uint8List get pixels => _pixels!;
     593              : 
     594              :   /// The error message describing why rendering failed. Only valid when
     595              :   /// [isSuccess] is `false`.
     596            4 :   String get errorMessage => _errorMessage!;
     597              : }
     598              : 
     599              : /// Sent when a [PdfiumGetTocCommand] completes.
     600              : class PdfiumGetTocResponse extends PdfiumResponse {
     601              :   /// Creates a successful TOC response with the given [entries] tree.
     602            1 :   const PdfiumGetTocResponse.success(this.entries) : error = null;
     603              : 
     604              :   /// Creates a failed TOC response.
     605            1 :   const PdfiumGetTocResponse.failure(this.error) : entries = null;
     606              : 
     607              :   /// The root-level TOC entries, or `null` on failure.
     608              :   ///
     609              :   /// An empty list is a valid success — the document simply has no bookmarks.
     610              :   final List<PdfTocEntry>? entries;
     611              : 
     612              :   /// The error that occurred, or `null` on success.
     613              :   final PdfError? error;
     614              : 
     615              :   /// Whether this response represents a successful extraction.
     616            4 :   bool get isSuccess => error == null;
     617              : }
     618              : 
     619              : /// Sent when a [PdfiumExtractPageImagesCommand] completes.
     620              : class PdfiumExtractPageImagesResponse extends PdfiumResponse {
     621              :   /// Creates a successful image-extraction response.
     622            1 :   const PdfiumExtractPageImagesResponse.success({
     623              :     required this.pageIndex,
     624              :     required List<PdfImage> this._images,
     625              :   }) : error = null;
     626              : 
     627              :   /// Creates a failed image-extraction response.
     628            1 :   const PdfiumExtractPageImagesResponse.failure(this.error, this.pageIndex)
     629              :     : _images = null;
     630              : 
     631              :   final List<PdfImage>? _images;
     632              : 
     633              :   /// The zero-based page index this response corresponds to.
     634              :   final int pageIndex;
     635              : 
     636              :   /// The error that occurred, or `null` on success.
     637              :   final PdfError? error;
     638              : 
     639              :   /// Whether this response represents a successful extraction.
     640            4 :   bool get isSuccess => error == null;
     641              : 
     642              :   /// The list of extracted images. Only valid when [isSuccess] is true.
     643            2 :   List<PdfImage> get images => _images!;
     644              : }
     645              : 
     646              : /// Sent when a [PdfiumRenderImageCommand] completes.
     647              : class PdfiumRenderImageResponse extends PdfiumResponse {
     648              :   /// Creates a successful render response carrying the [bitmap].
     649              :   ///
     650              :   /// [bitmap] is `null` when the object at the requested index is not an
     651              :   /// image type or when `FPDFImageObj_GetRenderedBitmap` returned null.
     652           19 :   const PdfiumRenderImageResponse.success(this.bitmap) : error = null;
     653              : 
     654              :   /// Creates a failed render response.
     655            1 :   const PdfiumRenderImageResponse.failure(this.error) : bitmap = null;
     656              : 
     657              :   /// The rendered bitmap, or `null` if the object is not a renderable image.
     658              :   final PdfImageBitmap? bitmap;
     659              : 
     660              :   /// The error that occurred, or `null` on success.
     661              :   final PdfError? error;
     662              : 
     663              :   /// Whether this response represents a successful (non-error) operation.
     664              :   ///
     665              :   /// Note: a successful response may still carry a `null` [bitmap] when the
     666              :   /// object has no renderable bitmap (mask-only etc.). A `false` value here
     667              :   /// indicates a hard error such as an invalid document token.
     668            4 :   bool get isSuccess => error == null;
     669              : }
     670              : 
     671              : /// Sent when a [PdfiumSearchPageCommand] completes.
     672              : class PdfiumSearchPageResponse extends PdfiumResponse {
     673              :   /// Creates a successful search response with the [_matches] found on the page.
     674              :   ///
     675              :   /// An empty [_matches] list means no matches were found on this page — that
     676              :   /// is a normal, non-error result.
     677            1 :   const PdfiumSearchPageResponse.success({
     678              :     required this.pageIndex,
     679              :     required List<PdfSearchMatch> this._matches,
     680              :   }) : error = null;
     681              : 
     682              :   /// Creates a failed search response.
     683            1 :   const PdfiumSearchPageResponse.failure(this.error, this.pageIndex)
     684              :     : _matches = null;
     685              : 
     686              :   final List<PdfSearchMatch>? _matches;
     687              : 
     688              :   /// The zero-based page index this response corresponds to.
     689              :   final int pageIndex;
     690              : 
     691              :   /// The error that occurred, or `null` on success.
     692              :   final PdfError? error;
     693              : 
     694              :   /// Whether this response represents a successful search.
     695            4 :   bool get isSuccess => error == null;
     696              : 
     697              :   /// The list of matches found on this page. Only valid when [isSuccess] is
     698              :   /// `true`. May be empty when no matches were found.
     699            2 :   List<PdfSearchMatch> get matches => _matches!;
     700              : }
     701              : 
     702              : /// Sent when a [PdfiumGetPageThumbnailCommand] completes.
     703              : ///
     704              : /// On success, [bgra] is either:
     705              : /// - A non-null [Uint8List] containing the compact BGRA pixel bytes of the
     706              : ///   embedded thumbnail (`length == width * height * 4`, row-padding stripped).
     707              : /// - `null`, indicating the page has no embedded thumbnail — this is a normal
     708              : ///   result, not an error.
     709              : ///
     710              : /// On failure (e.g. invalid document token or `FPDF_LoadPage` returning null),
     711              : /// [isSuccess] is `false` and [errorMessage] describes the problem.
     712              : class PdfiumGetPageThumbnailResponse extends PdfiumResponse {
     713              :   /// Creates a successful response where the page has an embedded thumbnail.
     714              :   ///
     715              :   /// [_bgra] must have length `[width] * [height] * 4`. Pass `null` for [_bgra]
     716              :   /// (with [width] and [height] of 0) when the page has no embedded thumbnail.
     717           19 :   const PdfiumGetPageThumbnailResponse.success({
     718              :     required this._bgra,
     719              :     required this.width,
     720              :     required this.height,
     721              :   }) : _errorMessage = null;
     722              : 
     723              :   /// Creates a failed response with a descriptive [errorMessage].
     724            1 :   const PdfiumGetPageThumbnailResponse.failure(this._errorMessage)
     725              :     : _bgra = null,
     726              :       width = 0,
     727              :       height = 0;
     728              : 
     729              :   final Uint8List? _bgra;
     730              :   final String? _errorMessage;
     731              : 
     732              :   /// The pixel width of the embedded thumbnail. Zero when [bgra] is `null`.
     733              :   final int width;
     734              : 
     735              :   /// The pixel height of the embedded thumbnail. Zero when [bgra] is `null`.
     736              :   final int height;
     737              : 
     738              :   /// Whether the operation succeeded (even if no thumbnail was found).
     739            4 :   bool get isSuccess => _errorMessage == null;
     740              : 
     741              :   /// The BGRA pixel buffer of the embedded thumbnail, or `null` when:
     742              :   /// - The page has no embedded thumbnail (normal result).
     743              :   ///
     744              :   /// Only valid when [isSuccess] is `true`.
     745            4 :   Uint8List? get bgra => _bgra;
     746              : 
     747              :   /// The error message. Only valid when [isSuccess] is `false`.
     748            2 :   String get errorMessage => _errorMessage!;
     749              : }
     750              : 
     751              : /// Sent when a [PdfiumExtractPageTextCommand] completes.
     752              : class PdfiumExtractPageTextResponse extends PdfiumResponse {
     753              :   /// Creates a successful text-extraction response.
     754            2 :   const PdfiumExtractPageTextResponse.success({
     755              :     required this.pageIndex,
     756              :     required String this._text,
     757              :     required bool this._hasUnicodeErrors,
     758              :     required bool this._hasTextLayer,
     759              :   }) : error = null;
     760              : 
     761              :   /// Creates a failed text-extraction response.
     762            1 :   const PdfiumExtractPageTextResponse.failure(this.error, this.pageIndex)
     763              :     : _text = null,
     764              :       _hasUnicodeErrors = null,
     765              :       _hasTextLayer = null;
     766              : 
     767              :   final String? _text;
     768              :   final bool? _hasUnicodeErrors;
     769              :   final bool? _hasTextLayer;
     770              : 
     771              :   /// The zero-based page index this response corresponds to.
     772              :   final int pageIndex;
     773              : 
     774              :   /// The error that occurred, or `null` on success.
     775              :   final PdfError? error;
     776              : 
     777              :   /// Whether this response represents a successful extraction.
     778            6 :   bool get isSuccess => error == null;
     779              : 
     780              :   /// The extracted text. Only valid when [isSuccess] is true.
     781            4 :   String get text => _text!;
     782              : 
     783              :   /// Whether any characters had broken Unicode mappings. Only valid when
     784              :   /// [isSuccess] is true.
     785            4 :   bool get hasUnicodeErrors => _hasUnicodeErrors!;
     786              : 
     787              :   /// Whether this page has a meaningful text layer. Only valid when
     788              :   /// [isSuccess] is true.
     789            4 :   bool get hasTextLayer => _hasTextLayer!;
     790              : }
        

Generated by: LCOV version 2.0-1