@silurus/ooxml 0.62.0 → 0.64.0

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) */
@@ -769,6 +800,9 @@ export declare interface NumberingInfo {
769
800
  text: string;
770
801
  indentLeft: number;
771
802
  tab: number;
803
+ /** ECMA-376 §17.9.28 `<w:suff>` — "tab" (default) | "space" | "nothing".
804
+ * Where body text starts after the marker on the first line. */
805
+ suff: string;
772
806
  }
773
807
 
774
808
  export declare interface ParaBorderEdge {
@@ -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) */
@@ -1968,6 +2018,9 @@ declare interface NumberingInfo {
1968
2018
  text: string;
1969
2019
  indentLeft: number;
1970
2020
  tab: number;
2021
+ /** ECMA-376 §17.9.28 `<w:suff>` — "tab" (default) | "space" | "nothing".
2022
+ * Where body text starts after the marker on the first line. */
2023
+ suff: string;
1971
2024
  }
1972
2025
 
1973
2026
  declare interface NumFmt {
@@ -2015,6 +2068,23 @@ declare interface Paragraph {
2015
2068
  runs: TextRun[];
2016
2069
  }
2017
2070
 
2071
+ /**
2072
+ * PPTX paragraph. Extends the shared core `Paragraph` with the PPTX-only
2073
+ * `eaLnBrk` flag that the pptx parser emits but the shared core model does not
2074
+ * carry (docx/xlsx paragraphs don't surface it). Mirrors the Rust
2075
+ * `Paragraph` struct's `ea_ln_brk` field 1:1.
2076
+ */
2077
+ declare interface Paragraph_2 extends Paragraph {
2078
+ /**
2079
+ * `<a:pPr eaLnBrk>` (ECMA-376 §21.1.2.2.7, xsd:boolean, default true). When
2080
+ * true, East Asian text may break at character boundaries (kinsoku rules);
2081
+ * when false, an East Asian word must not be split mid-character. The parser
2082
+ * resolves the paragraph → body/list-style → layout/master cascade and always
2083
+ * emits an effective boolean.
2084
+ */
2085
+ eaLnBrk: boolean;
2086
+ }
2087
+
2018
2088
  declare interface ParagraphBorders {
2019
2089
  top: ParaBorderEdge | null;
2020
2090
  bottom: ParaBorderEdge | null;
@@ -2145,8 +2215,35 @@ declare interface PictureElement {
2145
2215
  rotation: number;
2146
2216
  flipH: boolean;
2147
2217
  flipV: boolean;
2148
- /** Data URL, e.g. "data:image/png;base64,..." */
2149
- 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;
2228
+ /**
2229
+ * Microsoft 2016 SVG extension (`<a:blip><a:extLst><a:ext
2230
+ * uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip r:embed>`). When
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).
2243
+ */
2244
+ intrinsicWidthPx?: number;
2245
+ /** Intrinsic pixel height of the raster blip (PNG IHDR). Omitted for non-PNG. */
2246
+ intrinsicHeightPx?: number;
2150
2247
  /**
2151
2248
  * Border line from `<p:pic><p:spPr><a:ln>` (ECMA-376 §20.1.2.2.24). A
2152
2249
  * `p:pic`'s spPr is `CT_ShapeProperties` (§19.3.1.37), so a picture carries
@@ -2264,7 +2361,7 @@ export declare namespace pptx {
2264
2361
  SpaceLine,
2265
2362
  TabStop,
2266
2363
  TextBody,
2267
- Paragraph,
2364
+ Paragraph_2 as Paragraph,
2268
2365
  TextRun,
2269
2366
  TextRunData,
2270
2367
  LineBreak,
@@ -2306,6 +2403,12 @@ declare class PptxPresentation {
2306
2403
  private _presentation;
2307
2404
  private _meta;
2308
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;
2309
2412
  private _workerReady;
2310
2413
  private _workerReadyCallbacks;
2311
2414
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -2361,6 +2464,14 @@ declare class PptxPresentation {
2361
2464
  */
2362
2465
  getMedia(mediaPath: string): Promise<Blob>;
2363
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>;
2364
2475
  /**
2365
2476
  * Render a slide and attach canvas-native playback controls for any
2366
2477
  * embedded audio/video. Returns a {@link PresentationHandle} that owns the
@@ -2542,6 +2653,13 @@ declare interface RenderOptions {
2542
2653
  * demand, keeping the parse output free of inlined base64.
2543
2654
  */
2544
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>;
2545
2663
  /**
2546
2664
  * When true, renderMedia draws only the poster frame — play/pause badges
2547
2665
  * and progress bars are left to the caller. Set by the pptx presentSlide
@@ -2615,8 +2733,15 @@ declare interface RenderViewportOptions {
2615
2733
  freezeCols?: number;
2616
2734
  /** Scale factor applied to all cell/header dimensions (default 1). */
2617
2735
  cellScale?: number;
2618
- /** 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). */
2619
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>;
2620
2745
  /** Called once per cell that contains text, with canvas-pixel position and cell address. */
2621
2746
  onTextRun?: (info: XlsxTextRunInfo) => void;
2622
2747
  /** Highlighted row range for selected row headers (1-indexed inclusive).
@@ -2863,12 +2988,22 @@ declare type ShapeGeom = {
2863
2988
  type: 'custom';
2864
2989
  paths: PathInfo[];
2865
2990
  }
2866
- /** Bitmap picture leaf inside a `<xdr:grpSp>`. `dataUrl` is a pre-encoded
2867
- * `data:<mime>;base64,…` produced by the Rust parser from the drawing's
2868
- * 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. */
2869
2995
  | {
2870
2996
  type: 'image';
2871
- 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;
2872
3007
  };
2873
3008
 
2874
3009
  declare interface ShapeInfo {
@@ -3331,6 +3466,12 @@ declare interface TextBody extends TextBody_2 {
3331
3466
  * omitted from JSON when false. Only meaningful when `numCol > 1`.
3332
3467
  */
3333
3468
  rtlCol?: boolean;
3469
+ /**
3470
+ * Narrow the inherited `paragraphs` to the PPTX `Paragraph` so consumers see
3471
+ * the PPTX-only `eaLnBrk` flag. PPTX `Paragraph extends CoreParagraph`, so
3472
+ * this is a covariant refinement of `CoreTextBody.paragraphs`.
3473
+ */
3474
+ paragraphs: Paragraph_2[];
3334
3475
  }
3335
3476
 
3336
3477
  declare interface TextBody_2 {
@@ -3474,6 +3615,17 @@ declare interface TextRunData {
3474
3615
  * fill-only.
3475
3616
  */
3476
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;
3477
3629
  }
3478
3630
 
3479
3631
  /**
@@ -3509,9 +3661,10 @@ declare interface ViewportRange {
3509
3661
  /** Serializable subset of RenderPageOptions (callbacks cannot cross the wire). */
3510
3662
  declare type WireRenderPageOptions = Omit<RenderPageOptions, 'onTextRun'>;
3511
3663
 
3512
- /** Serializable subset of RenderViewportOptions: drop the callback and the
3513
- * image cache (the worker owns its own). */
3514
- 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'>;
3515
3668
 
3516
3669
  declare interface Workbook {
3517
3670
  sheets: SheetMeta[];
@@ -4036,8 +4189,19 @@ declare class XlsxWorkbook {
4036
4189
  private bridge;
4037
4190
  private parsedWorkbook;
4038
4191
  private sheetCache;
4039
- /** 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. */
4040
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;
4041
4205
  private rawData;
4042
4206
  private maxZipEntryBytes;
4043
4207
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -4055,6 +4219,19 @@ declare class XlsxWorkbook {
4055
4219
  * `null` for sheets that declare no tab color. */
4056
4220
  get tabColors(): (string | null)[];
4057
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>;
4058
4235
  /**
4059
4236
  * Resolve a `list`-type data-validation `formula1` (ECMA-376 §18.3.1.32) into
4060
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}).
@@ -863,7 +870,24 @@ export declare interface NoFill {
863
870
  fillType: 'none';
864
871
  }
865
872
 
866
- export declare interface Paragraph {
873
+ /**
874
+ * PPTX paragraph. Extends the shared core `Paragraph` with the PPTX-only
875
+ * `eaLnBrk` flag that the pptx parser emits but the shared core model does not
876
+ * carry (docx/xlsx paragraphs don't surface it). Mirrors the Rust
877
+ * `Paragraph` struct's `ea_ln_brk` field 1:1.
878
+ */
879
+ export declare interface Paragraph extends Paragraph_2 {
880
+ /**
881
+ * `<a:pPr eaLnBrk>` (ECMA-376 §21.1.2.2.7, xsd:boolean, default true). When
882
+ * true, East Asian text may break at character boundaries (kinsoku rules);
883
+ * when false, an East Asian word must not be split mid-character. The parser
884
+ * resolves the paragraph → body/list-style → layout/master cascade and always
885
+ * emits an effective boolean.
886
+ */
887
+ eaLnBrk: boolean;
888
+ }
889
+
890
+ declare interface Paragraph_2 {
867
891
  /** Alignment: "l" | "ctr" | "r" | "just" */
868
892
  alignment: string;
869
893
  /** Left margin in EMU */
@@ -943,8 +967,35 @@ export declare interface PictureElement {
943
967
  rotation: number;
944
968
  flipH: boolean;
945
969
  flipV: boolean;
946
- /** Data URL, e.g. "data:image/png;base64,..." */
947
- 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;
980
+ /**
981
+ * Microsoft 2016 SVG extension (`<a:blip><a:extLst><a:ext
982
+ * uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip r:embed>`). When
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).
995
+ */
996
+ intrinsicWidthPx?: number;
997
+ /** Intrinsic pixel height of the raster blip (PNG IHDR). Omitted for non-PNG. */
998
+ intrinsicHeightPx?: number;
948
999
  /**
949
1000
  * Border line from `<p:pic><p:spPr><a:ln>` (ECMA-376 §20.1.2.2.24). A
950
1001
  * `p:pic`'s spPr is `CT_ShapeProperties` (§19.3.1.37), so a picture carries
@@ -1044,6 +1095,12 @@ export declare class PptxPresentation {
1044
1095
  private _presentation;
1045
1096
  private _meta;
1046
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;
1047
1104
  private _workerReady;
1048
1105
  private _workerReadyCallbacks;
1049
1106
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
@@ -1099,6 +1156,14 @@ export declare class PptxPresentation {
1099
1156
  */
1100
1157
  getMedia(mediaPath: string): Promise<Blob>;
1101
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>;
1102
1167
  /**
1103
1168
  * Render a slide and attach canvas-native playback controls for any
1104
1169
  * embedded audio/video. Returns a {@link PresentationHandle} that owns the
@@ -1280,6 +1345,13 @@ export declare interface RenderOptions {
1280
1345
  * demand, keeping the parse output free of inlined base64.
1281
1346
  */
1282
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>;
1283
1355
  /**
1284
1356
  * When true, renderMedia draws only the poster frame — play/pause badges
1285
1357
  * and progress bars are left to the caller. Set by the pptx presentSlide
@@ -1567,12 +1639,18 @@ export declare interface TextBody extends TextBody_2 {
1567
1639
  * omitted from JSON when false. Only meaningful when `numCol > 1`.
1568
1640
  */
1569
1641
  rtlCol?: boolean;
1642
+ /**
1643
+ * Narrow the inherited `paragraphs` to the PPTX `Paragraph` so consumers see
1644
+ * the PPTX-only `eaLnBrk` flag. PPTX `Paragraph extends CoreParagraph`, so
1645
+ * this is a covariant refinement of `CoreTextBody.paragraphs`.
1646
+ */
1647
+ paragraphs: Paragraph[];
1570
1648
  }
1571
1649
 
1572
1650
  declare interface TextBody_2 {
1573
1651
  /** Vertical anchor: "t" | "ctr" | "b" */
1574
1652
  verticalAnchor: string;
1575
- paragraphs: Paragraph[];
1653
+ paragraphs: Paragraph_2[];
1576
1654
  /** Default pt size from lstStyle (overrides renderer default when present) */
1577
1655
  defaultFontSize: number | null;
1578
1656
  /** Inherited bold from layout/master defRPr (null = not set, use false as final default) */
@@ -1710,6 +1788,17 @@ export declare interface TextRunData {
1710
1788
  * fill-only.
1711
1789
  */
1712
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;
1713
1802
  }
1714
1803
 
1715
1804
  /**