@silurus/ooxml 0.63.0 → 0.64.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -238,10 +238,25 @@ export declare class DocxDocument {
238
238
  private _mode;
239
239
  private _worker;
240
240
  private _bridge;
241
+ private _imageCache;
242
+ /** One stable closure per instance: core's path-keyed SVG cache namespaces on
243
+ * this identity, so two open documents never swap a shared zip path (e.g.
244
+ * word/media/image1.svg). Reusing one reference also lets the SVG cache hit
245
+ * across page renders. */
246
+ private readonly _fetchImage;
241
247
  private constructor();
242
248
  static load(source: string | ArrayBuffer, opts?: LoadOptions): Promise<DocxDocument>;
243
249
  private _parse;
244
250
  destroy(): void;
251
+ /**
252
+ * Extract raw bytes for an embedded image by zip path (e.g.
253
+ * `word/media/image1.png`), wrapped in a Blob of the given MIME type. Routes
254
+ * through the persistent worker via the `extractImage` message (twin of
255
+ * pptx's `getImage`/`getMedia`); results are cached by path for the lifetime
256
+ * of this instance. The renderer's `fetchImage` option points here so images
257
+ * are decoded lazily rather than inlined as base64 at parse time.
258
+ */
259
+ getImage(imagePath: string, mimeType: string): Promise<Blob>;
245
260
  get pageCount(): number;
246
261
  /**
247
262
  * The raw parsed document model. Available only in `mode: 'main'`; in
@@ -484,7 +499,23 @@ export declare interface HeadersFooters {
484
499
  }
485
500
 
486
501
  export declare interface ImageRun {
487
- dataUrl: string;
502
+ /**
503
+ * Embedded zip path of the raster blip (e.g. `word/media/image1.png`) — the
504
+ * raster fallback (PNG/JPEG), or the SVG part itself when no raster blip is
505
+ * embedded. The renderer fetches the bytes lazily by path (see {@link
506
+ * DocxDocument.getImage}) instead of inlining base64.
507
+ */
508
+ imagePath: string;
509
+ /** MIME type of the blip at {@link ImageRun.imagePath} (e.g. `image/png`, or
510
+ * `image/svg+xml` for an svg-only picture). */
511
+ mimeType: string;
512
+ /**
513
+ * Vector original from the Microsoft `asvg:svgBlip` extension (MS-ODRAWXML) —
514
+ * the zip path of the `.svg` part. When present the renderer prefers it over
515
+ * {@link ImageRun.imagePath} (the raster fallback). Absent for a plain raster
516
+ * image. Its MIME is always `image/svg+xml` and is owned by the SVG decoder.
517
+ */
518
+ svgImagePath?: string;
488
519
  widthPt: number;
489
520
  heightPt: number;
490
521
  /** true = wp:anchor (absolute positioned), false/undefined = wp:inline (flows with text) */
@@ -1184,10 +1184,25 @@ declare class DocxDocument {
1184
1184
  private _mode;
1185
1185
  private _worker;
1186
1186
  private _bridge;
1187
+ private _imageCache;
1188
+ /** One stable closure per instance: core's path-keyed SVG cache namespaces on
1189
+ * this identity, so two open documents never swap a shared zip path (e.g.
1190
+ * word/media/image1.svg). Reusing one reference also lets the SVG cache hit
1191
+ * across page renders. */
1192
+ private readonly _fetchImage;
1187
1193
  private constructor();
1188
1194
  static load(source: string | ArrayBuffer, opts?: LoadOptions_4): Promise<DocxDocument>;
1189
1195
  private _parse;
1190
1196
  destroy(): void;
1197
+ /**
1198
+ * Extract raw bytes for an embedded image by zip path (e.g.
1199
+ * `word/media/image1.png`), wrapped in a Blob of the given MIME type. Routes
1200
+ * through the persistent worker via the `extractImage` message (twin of
1201
+ * pptx's `getImage`/`getMedia`); results are cached by path for the lifetime
1202
+ * of this instance. The renderer's `fetchImage` option points here so images
1203
+ * are decoded lazily rather than inlined as base64 at parse time.
1204
+ */
1205
+ getImage(imagePath: string, mimeType: string): Promise<Blob>;
1191
1206
  get pageCount(): number;
1192
1207
  /**
1193
1208
  * The raw parsed document model. Available only in `mode: 'main'`; in
@@ -1552,20 +1567,39 @@ declare interface ImageAnchor {
1552
1567
  * size. Authoritative when `editAs === "oneCell"`. 0 = unavailable. */
1553
1568
  nativeExtCx: number;
1554
1569
  nativeExtCy: number;
1555
- /** Data URL (data:image/png;base64,...) */
1556
- dataUrl: string;
1570
+ /** Zip path of the blip inside the package (e.g. `xl/media/image1.png`). The
1571
+ * blip's own `r:embed` raster fallback when an svgBlip extension is present;
1572
+ * otherwise the only source. Falls back to the SVG part itself when the
1573
+ * picture has no raster `r:embed`. Bytes are fetched lazily by path. */
1574
+ imagePath: string;
1575
+ /** MIME type of the blip at {@link ImageAnchor.imagePath} (e.g. `image/png`,
1576
+ * or `image/svg+xml` for the SVG-only fallback). */
1577
+ mimeType: string;
1578
+ /** Vector original from the Microsoft `asvg:svgBlip` extension (MS-ODRAWXML),
1579
+ * as a zip path. Preferred over `imagePath` (the raster fallback, or the SVG
1580
+ * itself when no raster blip is embedded). Absent when the picture carries no
1581
+ * svgBlip extension. Its MIME is always `image/svg+xml` and is owned by the
1582
+ * SVG decoder. */
1583
+ svgImagePath?: string;
1557
1584
  }
1558
1585
 
1559
1586
  /**
1560
1587
  * Image fill — ECMA-376 §20.1.8.14 (CT_BlipFillProperties). The embedded blip
1561
- * is resolved to a base64 data URL at parse time. Both fill-modes are modelled
1562
- * and mutually exclusive: `stretch` (§20.1.8.56) carries {@link ImageFill.fillRect};
1563
- * `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
1588
+ * is carried as a zip path + MIME; the renderer fetches the bytes on demand via
1589
+ * {@link RenderOptions.fetchImage} (no base64 inlined at parse time). Both
1590
+ * fill-modes are modelled and mutually exclusive: `stretch` (§20.1.8.56) carries
1591
+ * {@link ImageFill.fillRect}; `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
1564
1592
  */
1565
1593
  declare interface ImageFill {
1566
1594
  fillType: 'image';
1567
- /** `data:<mime>;base64,…` of the embedded blip. */
1568
- dataUrl: string;
1595
+ /**
1596
+ * Embedded zip path of the blip (e.g. "word/media/image1.png"), for the lazy
1597
+ * byte-on-demand pipeline. The renderer fetches the bytes via a path-keyed
1598
+ * loader ({@link RenderOptions.fetchImage}) instead of inlining base64.
1599
+ */
1600
+ imagePath: string;
1601
+ /** MIME type of the blip at {@link ImageFill.imagePath} (e.g. `image/png`). */
1602
+ mimeType: string;
1569
1603
  /**
1570
1604
  * `<a:stretch><a:fillRect>` insets. Absent → fills the whole box (or the
1571
1605
  * fill is tiled — see {@link ImageFill.tile}).
@@ -1581,7 +1615,23 @@ declare interface ImageFill {
1581
1615
  }
1582
1616
 
1583
1617
  declare interface ImageRun {
1584
- dataUrl: string;
1618
+ /**
1619
+ * Embedded zip path of the raster blip (e.g. `word/media/image1.png`) — the
1620
+ * raster fallback (PNG/JPEG), or the SVG part itself when no raster blip is
1621
+ * embedded. The renderer fetches the bytes lazily by path (see {@link
1622
+ * DocxDocument.getImage}) instead of inlining base64.
1623
+ */
1624
+ imagePath: string;
1625
+ /** MIME type of the blip at {@link ImageRun.imagePath} (e.g. `image/png`, or
1626
+ * `image/svg+xml` for an svg-only picture). */
1627
+ mimeType: string;
1628
+ /**
1629
+ * Vector original from the Microsoft `asvg:svgBlip` extension (MS-ODRAWXML) —
1630
+ * the zip path of the `.svg` part. When present the renderer prefers it over
1631
+ * {@link ImageRun.imagePath} (the raster fallback). Absent for a plain raster
1632
+ * image. Its MIME is always `image/svg+xml` and is owned by the SVG decoder.
1633
+ */
1634
+ svgImagePath?: string;
1585
1635
  widthPt: number;
1586
1636
  heightPt: number;
1587
1637
  /** true = wp:anchor (absolute positioned), false/undefined = wp:inline (flows with text) */
@@ -2165,18 +2215,35 @@ declare interface PictureElement {
2165
2215
  rotation: number;
2166
2216
  flipH: boolean;
2167
2217
  flipV: boolean;
2168
- /** Data URL, e.g. "data:image/png;base64,..." */
2169
- dataUrl: string;
2218
+ /**
2219
+ * Embedded zip path of the raster blip (e.g. "ppt/media/image1.png"). The
2220
+ * renderer fetches the bytes lazily by path (see {@link
2221
+ * PptxPresentation.getImage}) instead of inlining base64. When the picture is
2222
+ * a pure SVG with no raster blip this falls back to the SVG part's path and
2223
+ * {@link PictureElement.mimeType} is `image/svg+xml`.
2224
+ */
2225
+ imagePath: string;
2226
+ /** MIME type of the blip at {@link PictureElement.imagePath} (e.g. `image/png`). */
2227
+ mimeType: string;
2170
2228
  /**
2171
2229
  * Microsoft 2016 SVG extension (`<a:blip><a:extLst><a:ext
2172
2230
  * uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip r:embed>`). When
2173
- * PowerPoint embeds an SVG image, `dataUrl` above is only the PNG fallback it
2174
- * rasterizes for compatibility; this is the original vector image as a
2175
- * `data:image/svg+xml;base64,…` URL. The renderer prefers this and falls back
2176
- * to `dataUrl` if the SVG fails to decode. Omitted when the picture has no
2177
- * svgBlip extension (the common case).
2231
+ * PowerPoint embeds an SVG image, `imagePath` above is only the PNG fallback
2232
+ * it rasterizes for compatibility; this is the zip path of the original
2233
+ * vector `.svg` part. The renderer prefers this and falls back to the raster
2234
+ * if the SVG fails to decode. Omitted when the picture has no svgBlip
2235
+ * extension (the common case). Its MIME is always `image/svg+xml` and is
2236
+ * owned by the SVG decoder.
2237
+ */
2238
+ svgImagePath?: string;
2239
+ /**
2240
+ * Intrinsic pixel width of the raster blip, read from the PNG IHDR at parse
2241
+ * time. Omitted for non-PNG payloads. Used internally for the ink-fallback
2242
+ * (empty-stroke PNG centering).
2178
2243
  */
2179
- svgDataUrl?: string;
2244
+ intrinsicWidthPx?: number;
2245
+ /** Intrinsic pixel height of the raster blip (PNG IHDR). Omitted for non-PNG. */
2246
+ intrinsicHeightPx?: number;
2180
2247
  /**
2181
2248
  * Border line from `<p:pic><p:spPr><a:ln>` (ECMA-376 §20.1.2.2.24). A
2182
2249
  * `p:pic`'s spPr is `CT_ShapeProperties` (§19.3.1.37), so a picture carries
@@ -2336,6 +2403,12 @@ declare class PptxPresentation {
2336
2403
  private _presentation;
2337
2404
  private _meta;
2338
2405
  private _mediaCache;
2406
+ private _imageCache;
2407
+ /** One stable closure per instance: the decoded-bitmap and SVG caches key on
2408
+ * this identity to scope decodes per deck (so two open decks never swap
2409
+ * images for a shared zip path like ppt/media/image1.png). Reusing the same
2410
+ * reference across every render also lets those caches hit across slides. */
2411
+ private readonly _fetchImage;
2339
2412
  private _workerReady;
2340
2413
  private _workerReadyCallbacks;
2341
2414
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -2391,6 +2464,14 @@ declare class PptxPresentation {
2391
2464
  */
2392
2465
  getMedia(mediaPath: string): Promise<Blob>;
2393
2466
  private _findMimeTypeForPath;
2467
+ /**
2468
+ * Extract raw bytes for an embedded image by zip path (e.g.
2469
+ * "ppt/media/image1.png"), wrapped in a Blob of the given MIME type. Mirrors
2470
+ * {@link getMedia}; results are cached by path for the lifetime of this
2471
+ * instance. The renderer routes its `fetchImage` option here so images are
2472
+ * decoded lazily rather than inlined as base64 at parse time.
2473
+ */
2474
+ getImage(imagePath: string, mimeType: string): Promise<Blob>;
2394
2475
  /**
2395
2476
  * Render a slide and attach canvas-native playback controls for any
2396
2477
  * embedded audio/video. Returns a {@link PresentationHandle} that owns the
@@ -2572,6 +2653,13 @@ declare interface RenderOptions {
2572
2653
  * demand, keeping the parse output free of inlined base64.
2573
2654
  */
2574
2655
  fetchMedia?: (path: string) => Promise<Blob>;
2656
+ /**
2657
+ * Lazily resolve an embedded image (by zip path + MIME) to a Blob. Twin of
2658
+ * {@link RenderOptions.fetchMedia} for pictures and blip fills: the renderer
2659
+ * fetches raster/SVG bytes on demand and decodes them (`createImageBitmap` /
2660
+ * path-keyed `<img>`), so the parse output carries only paths, never base64.
2661
+ */
2662
+ fetchImage?: (path: string, mimeType: string) => Promise<Blob>;
2575
2663
  /**
2576
2664
  * When true, renderMedia draws only the poster frame — play/pause badges
2577
2665
  * and progress bars are left to the caller. Set by the pptx presentSlide
@@ -2645,8 +2733,15 @@ declare interface RenderViewportOptions {
2645
2733
  freezeCols?: number;
2646
2734
  /** Scale factor applied to all cell/header dimensions (default 1). */
2647
2735
  cellScale?: number;
2648
- /** Pre-decoded image sources keyed by their dataUrl (for ImageAnchor rendering). */
2736
+ /** Pre-decoded image sources keyed by their zip `imagePath` (for ImageAnchor
2737
+ * and group-leaf image rendering). */
2649
2738
  loadedImages?: Map<string, CanvasImageSource>;
2739
+ /** Fetch an embedded image's bytes by zip path, wrapped in a Blob of the given
2740
+ * MIME (twin of pptx/docx `fetchImage`). The orchestrator decodes these into
2741
+ * {@link loadedImages} before the synchronous draw. Supplied by
2742
+ * {@link XlsxWorkbook} (routing through the worker) or the render worker
2743
+ * (reading its retained buffer). Absent ⇒ no images are decoded. */
2744
+ fetchImage?: (path: string, mimeType: string) => Promise<Blob>;
2650
2745
  /** Called once per cell that contains text, with canvas-pixel position and cell address. */
2651
2746
  onTextRun?: (info: XlsxTextRunInfo) => void;
2652
2747
  /** Highlighted row range for selected row headers (1-indexed inclusive).
@@ -2893,12 +2988,22 @@ declare type ShapeGeom = {
2893
2988
  type: 'custom';
2894
2989
  paths: PathInfo[];
2895
2990
  }
2896
- /** Bitmap picture leaf inside a `<xdr:grpSp>`. `dataUrl` is a pre-encoded
2897
- * `data:<mime>;base64,…` produced by the Rust parser from the drawing's
2898
- * relationship target. */
2991
+ /** Bitmap (or vector) picture leaf inside a `<xdr:grpSp>`. `imagePath` is the
2992
+ * zip path of the drawing's relationship target the blip's raster `r:embed`
2993
+ * fallback, or the SVG itself when no raster is embedded — and `mimeType` its
2994
+ * MIME. Bytes are fetched lazily by path; nothing is inlined as base64. */
2899
2995
  | {
2900
2996
  type: 'image';
2901
- dataUrl: string;
2997
+ imagePath: string;
2998
+ /** MIME type of the blip at {@link imagePath} (e.g. `image/png`, or
2999
+ * `image/svg+xml` for the SVG-only fallback). */
3000
+ mimeType: string;
3001
+ /** Vector original from the Microsoft `asvg:svgBlip` extension
3002
+ * (MS-ODRAWXML), as a zip path. Prefer this over `imagePath` (the raster
3003
+ * fallback, or the SVG itself when no raster blip is embedded). Absent
3004
+ * when the picture carries no svgBlip extension. Its MIME is always
3005
+ * `image/svg+xml` and is owned by the SVG decoder. */
3006
+ svgImagePath?: string;
2902
3007
  };
2903
3008
 
2904
3009
  declare interface ShapeInfo {
@@ -3510,6 +3615,17 @@ declare interface TextRunData {
3510
3615
  * fill-only.
3511
3616
  */
3512
3617
  outline?: TextOutline;
3618
+ /**
3619
+ * Run-level text highlight / marker colour (`<a:rPr><a:highlight>`),
3620
+ * ECMA-376 §21.1.2.3.4. In DrawingML this is a full CT_Color (any
3621
+ * srgbClr / schemeClr / sysClr / prstClr + transforms), unlike
3622
+ * WordprocessingML's fixed 16-name highlight enum — so the parser already
3623
+ * resolves it through the theme/clrMap. The value is a hex string without
3624
+ * `#` (6-char opaque, or 8-char RRGGBBAA when an alpha transform applies);
3625
+ * the renderer paints a background rectangle behind the run's glyphs.
3626
+ * Absent means no highlight.
3627
+ */
3628
+ highlight?: string;
3513
3629
  }
3514
3630
 
3515
3631
  /**
@@ -3545,9 +3661,10 @@ declare interface ViewportRange {
3545
3661
  /** Serializable subset of RenderPageOptions (callbacks cannot cross the wire). */
3546
3662
  declare type WireRenderPageOptions = Omit<RenderPageOptions, 'onTextRun'>;
3547
3663
 
3548
- /** Serializable subset of RenderViewportOptions: drop the callback and the
3549
- * image cache (the worker owns its own). */
3550
- declare type WireRenderViewportOptions = Omit<RenderViewportOptions, 'onTextRun' | 'loadedImages'>;
3664
+ /** Serializable subset of RenderViewportOptions: drop the callback, the image
3665
+ * cache, and the `fetchImage` loader (all non-cloneable; the worker owns its
3666
+ * own cache and supplies its own in-worker fetchImage). */
3667
+ declare type WireRenderViewportOptions = Omit<RenderViewportOptions, 'onTextRun' | 'loadedImages' | 'fetchImage'>;
3551
3668
 
3552
3669
  declare interface Workbook {
3553
3670
  sheets: SheetMeta[];
@@ -4072,8 +4189,19 @@ declare class XlsxWorkbook {
4072
4189
  private bridge;
4073
4190
  private parsedWorkbook;
4074
4191
  private sheetCache;
4075
- /** Cache of decoded image bitmaps keyed by their data URL. Shared across sheets. */
4192
+ /** Cache of decoded image sources keyed by their zip `imagePath`. Shared
4193
+ * across sheets. */
4076
4194
  private imageCache;
4195
+ /** Cache of fetched image *bytes* (as Blobs) keyed by zip path, populated by
4196
+ * {@link XlsxWorkbook.getImage}. Twin of pptx/docx's per-instance
4197
+ * `_imageCache`; kept separate from {@link XlsxWorkbook.imageCache} (decoded
4198
+ * sources) so each layer dedupes independently. */
4199
+ private imageBlobCache;
4200
+ /** One stable closure per instance: core's path-keyed SVG cache namespaces on
4201
+ * this identity, so two open workbooks never swap a shared zip path (e.g.
4202
+ * xl/media/image1.svg). Reusing one reference also lets the SVG cache hit
4203
+ * across viewport renders. */
4204
+ private readonly _fetchImage;
4077
4205
  private rawData;
4078
4206
  private maxZipEntryBytes;
4079
4207
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -4091,6 +4219,19 @@ declare class XlsxWorkbook {
4091
4219
  * `null` for sheets that declare no tab color. */
4092
4220
  get tabColors(): (string | null)[];
4093
4221
  getWorksheet(sheetIndex: number): Promise<Worksheet>;
4222
+ /**
4223
+ * Fetch an embedded image's bytes by zip path (e.g. `xl/media/image1.png`),
4224
+ * wrapped in a Blob of the given MIME. The bytes are pulled through the
4225
+ * persistent worker via the `extractImage` message (twin of pptx/docx's
4226
+ * `getImage`/`getMedia`); results are cached by path for the lifetime of this
4227
+ * instance. The renderer's `fetchImage` option points here so image bytes are
4228
+ * extracted lazily rather than inlined as base64 at parse time.
4229
+ *
4230
+ * Routed through the worker even though the main thread also retains
4231
+ * `rawData`, to keep all WASM `extract_image` decoding on the worker (the
4232
+ * route-through-worker decision).
4233
+ */
4234
+ getImage(imagePath: string, mimeType: string): Promise<Blob>;
4094
4235
  /**
4095
4236
  * Resolve a `list`-type data-validation `formula1` (ECMA-376 §18.3.1.32) into
4096
4237
  * the set of allowed values to display, evaluated relative to `sheetIndex`
@@ -606,14 +606,21 @@ export declare interface GradientStop {
606
606
 
607
607
  /**
608
608
  * Image fill — ECMA-376 §20.1.8.14 (CT_BlipFillProperties). The embedded blip
609
- * is resolved to a base64 data URL at parse time. Both fill-modes are modelled
610
- * and mutually exclusive: `stretch` (§20.1.8.56) carries {@link ImageFill.fillRect};
611
- * `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
609
+ * is carried as a zip path + MIME; the renderer fetches the bytes on demand via
610
+ * {@link RenderOptions.fetchImage} (no base64 inlined at parse time). Both
611
+ * fill-modes are modelled and mutually exclusive: `stretch` (§20.1.8.56) carries
612
+ * {@link ImageFill.fillRect}; `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
612
613
  */
613
614
  export declare interface ImageFill {
614
615
  fillType: 'image';
615
- /** `data:<mime>;base64,…` of the embedded blip. */
616
- dataUrl: string;
616
+ /**
617
+ * Embedded zip path of the blip (e.g. "word/media/image1.png"), for the lazy
618
+ * byte-on-demand pipeline. The renderer fetches the bytes via a path-keyed
619
+ * loader ({@link RenderOptions.fetchImage}) instead of inlining base64.
620
+ */
621
+ imagePath: string;
622
+ /** MIME type of the blip at {@link ImageFill.imagePath} (e.g. `image/png`). */
623
+ mimeType: string;
617
624
  /**
618
625
  * `<a:stretch><a:fillRect>` insets. Absent → fills the whole box (or the
619
626
  * fill is tiled — see {@link ImageFill.tile}).
@@ -960,18 +967,35 @@ export declare interface PictureElement {
960
967
  rotation: number;
961
968
  flipH: boolean;
962
969
  flipV: boolean;
963
- /** Data URL, e.g. "data:image/png;base64,..." */
964
- dataUrl: string;
970
+ /**
971
+ * Embedded zip path of the raster blip (e.g. "ppt/media/image1.png"). The
972
+ * renderer fetches the bytes lazily by path (see {@link
973
+ * PptxPresentation.getImage}) instead of inlining base64. When the picture is
974
+ * a pure SVG with no raster blip this falls back to the SVG part's path and
975
+ * {@link PictureElement.mimeType} is `image/svg+xml`.
976
+ */
977
+ imagePath: string;
978
+ /** MIME type of the blip at {@link PictureElement.imagePath} (e.g. `image/png`). */
979
+ mimeType: string;
965
980
  /**
966
981
  * Microsoft 2016 SVG extension (`<a:blip><a:extLst><a:ext
967
982
  * uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip r:embed>`). When
968
- * PowerPoint embeds an SVG image, `dataUrl` above is only the PNG fallback it
969
- * rasterizes for compatibility; this is the original vector image as a
970
- * `data:image/svg+xml;base64,…` URL. The renderer prefers this and falls back
971
- * to `dataUrl` if the SVG fails to decode. Omitted when the picture has no
972
- * svgBlip extension (the common case).
983
+ * PowerPoint embeds an SVG image, `imagePath` above is only the PNG fallback
984
+ * it rasterizes for compatibility; this is the zip path of the original
985
+ * vector `.svg` part. The renderer prefers this and falls back to the raster
986
+ * if the SVG fails to decode. Omitted when the picture has no svgBlip
987
+ * extension (the common case). Its MIME is always `image/svg+xml` and is
988
+ * owned by the SVG decoder.
989
+ */
990
+ svgImagePath?: string;
991
+ /**
992
+ * Intrinsic pixel width of the raster blip, read from the PNG IHDR at parse
993
+ * time. Omitted for non-PNG payloads. Used internally for the ink-fallback
994
+ * (empty-stroke PNG centering).
973
995
  */
974
- svgDataUrl?: string;
996
+ intrinsicWidthPx?: number;
997
+ /** Intrinsic pixel height of the raster blip (PNG IHDR). Omitted for non-PNG. */
998
+ intrinsicHeightPx?: number;
975
999
  /**
976
1000
  * Border line from `<p:pic><p:spPr><a:ln>` (ECMA-376 §20.1.2.2.24). A
977
1001
  * `p:pic`'s spPr is `CT_ShapeProperties` (§19.3.1.37), so a picture carries
@@ -1071,6 +1095,12 @@ export declare class PptxPresentation {
1071
1095
  private _presentation;
1072
1096
  private _meta;
1073
1097
  private _mediaCache;
1098
+ private _imageCache;
1099
+ /** One stable closure per instance: the decoded-bitmap and SVG caches key on
1100
+ * this identity to scope decodes per deck (so two open decks never swap
1101
+ * images for a shared zip path like ppt/media/image1.png). Reusing the same
1102
+ * reference across every render also lets those caches hit across slides. */
1103
+ private readonly _fetchImage;
1074
1104
  private _workerReady;
1075
1105
  private _workerReadyCallbacks;
1076
1106
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -1126,6 +1156,14 @@ export declare class PptxPresentation {
1126
1156
  */
1127
1157
  getMedia(mediaPath: string): Promise<Blob>;
1128
1158
  private _findMimeTypeForPath;
1159
+ /**
1160
+ * Extract raw bytes for an embedded image by zip path (e.g.
1161
+ * "ppt/media/image1.png"), wrapped in a Blob of the given MIME type. Mirrors
1162
+ * {@link getMedia}; results are cached by path for the lifetime of this
1163
+ * instance. The renderer routes its `fetchImage` option here so images are
1164
+ * decoded lazily rather than inlined as base64 at parse time.
1165
+ */
1166
+ getImage(imagePath: string, mimeType: string): Promise<Blob>;
1129
1167
  /**
1130
1168
  * Render a slide and attach canvas-native playback controls for any
1131
1169
  * embedded audio/video. Returns a {@link PresentationHandle} that owns the
@@ -1307,6 +1345,13 @@ export declare interface RenderOptions {
1307
1345
  * demand, keeping the parse output free of inlined base64.
1308
1346
  */
1309
1347
  fetchMedia?: (path: string) => Promise<Blob>;
1348
+ /**
1349
+ * Lazily resolve an embedded image (by zip path + MIME) to a Blob. Twin of
1350
+ * {@link RenderOptions.fetchMedia} for pictures and blip fills: the renderer
1351
+ * fetches raster/SVG bytes on demand and decodes them (`createImageBitmap` /
1352
+ * path-keyed `<img>`), so the parse output carries only paths, never base64.
1353
+ */
1354
+ fetchImage?: (path: string, mimeType: string) => Promise<Blob>;
1310
1355
  /**
1311
1356
  * When true, renderMedia draws only the poster frame — play/pause badges
1312
1357
  * and progress bars are left to the caller. Set by the pptx presentSlide
@@ -1743,6 +1788,17 @@ export declare interface TextRunData {
1743
1788
  * fill-only.
1744
1789
  */
1745
1790
  outline?: TextOutline;
1791
+ /**
1792
+ * Run-level text highlight / marker colour (`<a:rPr><a:highlight>`),
1793
+ * ECMA-376 §21.1.2.3.4. In DrawingML this is a full CT_Color (any
1794
+ * srgbClr / schemeClr / sysClr / prstClr + transforms), unlike
1795
+ * WordprocessingML's fixed 16-name highlight enum — so the parser already
1796
+ * resolves it through the theme/clrMap. The value is a hex string without
1797
+ * `#` (6-char opaque, or 8-char RRGGBBAA when an alpha transform applies);
1798
+ * the renderer paints a background rectangle behind the run's glyphs.
1799
+ * Absent means no highlight.
1800
+ */
1801
+ highlight?: string;
1746
1802
  }
1747
1803
 
1748
1804
  /**
@@ -462,8 +462,20 @@ export declare interface ImageAnchor {
462
462
  * size. Authoritative when `editAs === "oneCell"`. 0 = unavailable. */
463
463
  nativeExtCx: number;
464
464
  nativeExtCy: number;
465
- /** Data URL (data:image/png;base64,...) */
466
- dataUrl: string;
465
+ /** Zip path of the blip inside the package (e.g. `xl/media/image1.png`). The
466
+ * blip's own `r:embed` raster fallback when an svgBlip extension is present;
467
+ * otherwise the only source. Falls back to the SVG part itself when the
468
+ * picture has no raster `r:embed`. Bytes are fetched lazily by path. */
469
+ imagePath: string;
470
+ /** MIME type of the blip at {@link ImageAnchor.imagePath} (e.g. `image/png`,
471
+ * or `image/svg+xml` for the SVG-only fallback). */
472
+ mimeType: string;
473
+ /** Vector original from the Microsoft `asvg:svgBlip` extension (MS-ODRAWXML),
474
+ * as a zip path. Preferred over `imagePath` (the raster fallback, or the SVG
475
+ * itself when no raster blip is embedded). Absent when the picture carries no
476
+ * svgBlip extension. Its MIME is always `image/svg+xml` and is owned by the
477
+ * SVG decoder. */
478
+ svgImagePath?: string;
467
479
  }
468
480
 
469
481
  export declare interface LegendManualLayout {
@@ -743,8 +755,15 @@ export declare interface RenderViewportOptions {
743
755
  freezeCols?: number;
744
756
  /** Scale factor applied to all cell/header dimensions (default 1). */
745
757
  cellScale?: number;
746
- /** Pre-decoded image sources keyed by their dataUrl (for ImageAnchor rendering). */
758
+ /** Pre-decoded image sources keyed by their zip `imagePath` (for ImageAnchor
759
+ * and group-leaf image rendering). */
747
760
  loadedImages?: Map<string, CanvasImageSource>;
761
+ /** Fetch an embedded image's bytes by zip path, wrapped in a Blob of the given
762
+ * MIME (twin of pptx/docx `fetchImage`). The orchestrator decodes these into
763
+ * {@link loadedImages} before the synchronous draw. Supplied by
764
+ * {@link XlsxWorkbook} (routing through the worker) or the render worker
765
+ * (reading its retained buffer). Absent ⇒ no images are decoded. */
766
+ fetchImage?: (path: string, mimeType: string) => Promise<Blob>;
748
767
  /** Called once per cell that contains text, with canvas-pixel position and cell address. */
749
768
  onTextRun?: (info: XlsxTextRunInfo) => void;
750
769
  /** Highlighted row range for selected row headers (1-indexed inclusive).
@@ -857,12 +876,22 @@ export declare type ShapeGeom = {
857
876
  type: 'custom';
858
877
  paths: PathInfo[];
859
878
  }
860
- /** Bitmap picture leaf inside a `<xdr:grpSp>`. `dataUrl` is a pre-encoded
861
- * `data:<mime>;base64,…` produced by the Rust parser from the drawing's
862
- * relationship target. */
879
+ /** Bitmap (or vector) picture leaf inside a `<xdr:grpSp>`. `imagePath` is the
880
+ * zip path of the drawing's relationship target the blip's raster `r:embed`
881
+ * fallback, or the SVG itself when no raster is embedded — and `mimeType` its
882
+ * MIME. Bytes are fetched lazily by path; nothing is inlined as base64. */
863
883
  | {
864
884
  type: 'image';
865
- dataUrl: string;
885
+ imagePath: string;
886
+ /** MIME type of the blip at {@link imagePath} (e.g. `image/png`, or
887
+ * `image/svg+xml` for the SVG-only fallback). */
888
+ mimeType: string;
889
+ /** Vector original from the Microsoft `asvg:svgBlip` extension
890
+ * (MS-ODRAWXML), as a zip path. Prefer this over `imagePath` (the raster
891
+ * fallback, or the SVG itself when no raster blip is embedded). Absent
892
+ * when the picture carries no svgBlip extension. Its MIME is always
893
+ * `image/svg+xml` and is owned by the SVG decoder. */
894
+ svgImagePath?: string;
866
895
  };
867
896
 
868
897
  export declare interface ShapeInfo {
@@ -1073,9 +1102,10 @@ export declare interface ViewportRange {
1073
1102
  cols: number;
1074
1103
  }
1075
1104
 
1076
- /** Serializable subset of RenderViewportOptions: drop the callback and the
1077
- * image cache (the worker owns its own). */
1078
- export declare type WireRenderViewportOptions = Omit<RenderViewportOptions, 'onTextRun' | 'loadedImages'>;
1105
+ /** Serializable subset of RenderViewportOptions: drop the callback, the image
1106
+ * cache, and the `fetchImage` loader (all non-cloneable; the worker owns its
1107
+ * own cache and supplies its own in-worker fetchImage). */
1108
+ export declare type WireRenderViewportOptions = Omit<RenderViewportOptions, 'onTextRun' | 'loadedImages' | 'fetchImage'>;
1079
1109
 
1080
1110
  export declare interface Workbook {
1081
1111
  sheets: SheetMeta[];
@@ -1528,8 +1558,19 @@ export declare class XlsxWorkbook {
1528
1558
  private bridge;
1529
1559
  private parsedWorkbook;
1530
1560
  private sheetCache;
1531
- /** Cache of decoded image bitmaps keyed by their data URL. Shared across sheets. */
1561
+ /** Cache of decoded image sources keyed by their zip `imagePath`. Shared
1562
+ * across sheets. */
1532
1563
  private imageCache;
1564
+ /** Cache of fetched image *bytes* (as Blobs) keyed by zip path, populated by
1565
+ * {@link XlsxWorkbook.getImage}. Twin of pptx/docx's per-instance
1566
+ * `_imageCache`; kept separate from {@link XlsxWorkbook.imageCache} (decoded
1567
+ * sources) so each layer dedupes independently. */
1568
+ private imageBlobCache;
1569
+ /** One stable closure per instance: core's path-keyed SVG cache namespaces on
1570
+ * this identity, so two open workbooks never swap a shared zip path (e.g.
1571
+ * xl/media/image1.svg). Reusing one reference also lets the SVG cache hit
1572
+ * across viewport renders. */
1573
+ private readonly _fetchImage;
1533
1574
  private rawData;
1534
1575
  private maxZipEntryBytes;
1535
1576
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -1547,6 +1588,19 @@ export declare class XlsxWorkbook {
1547
1588
  * `null` for sheets that declare no tab color. */
1548
1589
  get tabColors(): (string | null)[];
1549
1590
  getWorksheet(sheetIndex: number): Promise<Worksheet>;
1591
+ /**
1592
+ * Fetch an embedded image's bytes by zip path (e.g. `xl/media/image1.png`),
1593
+ * wrapped in a Blob of the given MIME. The bytes are pulled through the
1594
+ * persistent worker via the `extractImage` message (twin of pptx/docx's
1595
+ * `getImage`/`getMedia`); results are cached by path for the lifetime of this
1596
+ * instance. The renderer's `fetchImage` option points here so image bytes are
1597
+ * extracted lazily rather than inlined as base64 at parse time.
1598
+ *
1599
+ * Routed through the worker even though the main thread also retains
1600
+ * `rawData`, to keep all WASM `extract_image` decoding on the worker (the
1601
+ * route-through-worker decision).
1602
+ */
1603
+ getImage(imagePath: string, mimeType: string): Promise<Blob>;
1550
1604
  /**
1551
1605
  * Resolve a `list`-type data-validation `formula1` (ECMA-376 §18.3.1.32) into
1552
1606
  * the set of allowed values to display, evaluated relative to `sheetIndex`