pptx-browser 4.1.4 → 4.1.5

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/svg.js +18 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptx-browser",
3
- "version": "4.1.4",
3
+ "version": "4.1.5",
4
4
  "description": "Render, edit, and export PowerPoint (PPTX) slides. Canvas rendering, SVG export, PDF export, PPTX writer/template engine, slide show, text extraction, animations. Zero dependencies.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/svg.js CHANGED
@@ -459,15 +459,15 @@ function toRoman(n) {
459
459
  }
460
460
 
461
461
  // ── Shape → SVG ───────────────────────────────────────────────────────────────
462
- async function shapesToSvg(spTreeEl, rels, imageCache, themeColors, themeData, defs) {
462
+ async function shapesToSvg(spTreeEl, rels, files, themeColors, themeData, defs) {
463
463
  if (!spTreeEl) return '';
464
464
  let out = '';
465
465
  for (const child of spTreeEl.children) {
466
466
  const ln = child.localName;
467
467
  if (ln === 'sp') out += await shapeToSvg(child, themeColors, themeData, defs);
468
- else if (ln === 'pic') out += await pictureToSvg(child, rels, imageCache, themeColors, defs);
468
+ else if (ln === 'pic') out += await pictureToSvg(child, rels, files, themeColors, defs);
469
469
  else if (ln === 'cxnSp') out += await connectorToSvg(child, themeColors, defs);
470
- else if (ln === 'grpSp') out += await groupToSvg(child, rels, imageCache, themeColors, themeData, defs);
470
+ else if (ln === 'grpSp') out += await groupToSvg(child, rels, files, themeColors, themeData, defs);
471
471
  else if (ln === 'graphicFrame') out += await graphicFrameToSvg(child, themeColors, defs);
472
472
  }
473
473
  return out;
@@ -543,7 +543,7 @@ async function shapeToSvg(spEl, themeColors, themeData, defs) {
543
543
  return `<g>${pathSvg}${textSvg}</g>`;
544
544
  }
545
545
 
546
- async function pictureToSvg(picEl, rels, imageCache, themeColors, defs) {
546
+ async function pictureToSvg(picEl, rels, files, themeColors, defs) {
547
547
  const spPr = g1(picEl, 'spPr');
548
548
  const xfrm = g1(spPr, 'xfrm');
549
549
  const b = xfrmBounds(xfrm);
@@ -553,7 +553,7 @@ async function pictureToSvg(picEl, rels, imageCache, themeColors, defs) {
553
553
  const blip = blipFill ? g1(blipFill, 'blip') : null;
554
554
  const rId = blip ? (blip.getAttribute('r:embed') || blip.getAttribute('embed')) : null;
555
555
  const rel = rId ? rels[rId] : null;
556
- const imgData = rel ? imageCache[rel.fullPath] : null;
556
+ const imgData = rel ? files[rel.fullPath] : null;
557
557
 
558
558
  const transform = xfrmAttrs(xfrm);
559
559
  const effectLst = g1(spPr, 'effectLst');
@@ -567,7 +567,8 @@ async function pictureToSvg(picEl, rels, imageCache, themeColors, defs) {
567
567
  const ext = rel.fullPath.split('.').pop().toLowerCase();
568
568
  const mime = ext === 'png' ? 'image/png' : ext === 'gif' ? 'image/gif'
569
569
  : ext === 'svg' ? 'image/svg+xml' : 'image/jpeg';
570
- const b64 = btoa(String.fromCharCode(...(imgData instanceof Uint8Array ? imgData : new Uint8Array(imgData))));
570
+ const raw = imgData instanceof Uint8Array ? imgData : new Uint8Array(imgData);
571
+ const b64 = btoa(Array.from(raw, b => String.fromCharCode(b)).join(''));
571
572
 
572
573
  // Clip to shape bounds
573
574
  const clipId = uid('pic');
@@ -587,12 +588,12 @@ async function connectorToSvg(cxnSpEl, themeColors, defs) {
587
588
  return `<line x1="${px(b.x)}" y1="${px(b.y)}" x2="${px(b.x+b.w)}" y2="${px(b.y+b.h)}" fill="none"${stroke}${transform}/>`;
588
589
  }
589
590
 
590
- async function groupToSvg(grpSpEl, rels, imageCache, themeColors, themeData, defs) {
591
+ async function groupToSvg(grpSpEl, rels, files, themeColors, themeData, defs) {
591
592
  const spPr = g1(grpSpEl, 'grpSpPr');
592
593
  const xfrm = g1(spPr, 'xfrm');
593
594
  const b = xfrmBounds(xfrm);
594
595
  const transform = xfrm ? xfrmAttrs(xfrm) : '';
595
- const children = await shapesToSvg(grpSpEl, rels, imageCache, themeColors, themeData, defs);
596
+ const children = await shapesToSvg(grpSpEl, rels, files, themeColors, themeData, defs);
596
597
  return `<g${transform}>${children}</g>`;
597
598
  }
598
599
 
@@ -606,7 +607,7 @@ async function graphicFrameToSvg(graphicFrame, themeColors, defs) {
606
607
  }
607
608
 
608
609
  // ── Background → SVG ──────────────────────────────────────────────────────────
609
- async function backgroundToSvg(slideDoc, masterDoc, layoutDoc, imageCache, masterRels, themeColors, slideW, slideH, defs) {
610
+ async function backgroundToSvg(slideDoc, masterDoc, layoutDoc, files, masterRels, themeColors, slideW, slideH, defs) {
610
611
  const getbg = (doc) => {
611
612
  const cSld = g1(doc, 'cSld');
612
613
  const bg = cSld ? g1(cSld, 'bg') : null;
@@ -626,11 +627,12 @@ async function backgroundToSvg(slideDoc, masterDoc, layoutDoc, imageCache, maste
626
627
  const blip = g1(fillEl, 'blip');
627
628
  const rId = blip ? (blip.getAttribute('r:embed') || blip.getAttribute('embed')) : null;
628
629
  const rel = rId && masterRels ? masterRels[rId] : null;
629
- const imgData = rel ? imageCache[rel.fullPath] : null;
630
+ const imgData = rel ? files[rel.fullPath] : null;
630
631
  if (imgData) {
631
632
  const ext = rel.fullPath.split('.').pop().toLowerCase();
632
633
  const mime = ext === 'png' ? 'image/png' : 'image/jpeg';
633
- const b64 = btoa(String.fromCharCode(...new Uint8Array(imgData)));
634
+ const raw = imgData instanceof Uint8Array ? imgData : new Uint8Array(imgData);
635
+ const b64 = btoa(Array.from(raw, b => String.fromCharCode(b)).join(''));
634
636
  return `<image width="${px(slideW)}" height="${px(slideH)}" href="data:${mime};base64,${b64}" preserveAspectRatio="xMidYMid slice"/>`;
635
637
  }
636
638
  }
@@ -658,7 +660,7 @@ async function backgroundToSvg(slideDoc, masterDoc, layoutDoc, imageCache, maste
658
660
  */
659
661
  export async function renderSlideToSvg(slideIndex, renderer) {
660
662
  const { _files: files, slidePaths, slideSize, themeColors, themeData,
661
- masterDoc, masterRels, masterImages } = renderer;
663
+ masterDoc, masterRels } = renderer;
662
664
 
663
665
  if (slideIndex < 0 || slideIndex >= slidePaths.length) throw new Error('Slide index out of range');
664
666
 
@@ -675,12 +677,6 @@ export async function renderSlideToSvg(slideIndex, renderer) {
675
677
  ? parseXml(new TextDecoder().decode(files[layoutRel.fullPath])) : null;
676
678
  const layoutRels = layoutRel ? await getRels(files, layoutRel.fullPath) : {};
677
679
 
678
- // Image cache
679
- const { loadImages } = await import('./render.js');
680
- const slideImages = await loadImages(files, slideRels);
681
- const layoutImages = layoutRel ? await loadImages(files, layoutRels) : {};
682
- const allImages = { ...masterImages, ...layoutImages, ...slideImages };
683
-
684
680
  // Slide dimensions in px (96 dpi)
685
681
  const W = slideSize.cx / 914400 * 96;
686
682
  const H = slideSize.cy / 914400 * 96;
@@ -688,7 +684,7 @@ export async function renderSlideToSvg(slideIndex, renderer) {
688
684
  const defs = [];
689
685
 
690
686
  // Background
691
- const bgSvg = await backgroundToSvg(slideDoc, masterDoc, layoutDoc, allImages,
687
+ const bgSvg = await backgroundToSvg(slideDoc, masterDoc, layoutDoc, files,
692
688
  masterRels, themeColors, W, H, defs);
693
689
 
694
690
  // Master / layout decorative shapes
@@ -697,11 +693,11 @@ export async function renderSlideToSvg(slideIndex, renderer) {
697
693
  const slideTree = g1(g1(slideDoc, 'cSld'), 'spTree');
698
694
 
699
695
  const masterSvg = masterTree
700
- ? await shapesToSvg(masterTree, masterRels, masterImages, themeColors, themeData, defs) : '';
696
+ ? await shapesToSvg(masterTree, masterRels, files, themeColors, themeData, defs) : '';
701
697
  const layoutSvg = layoutTree
702
- ? await shapesToSvg(layoutTree, layoutRels, layoutImages, themeColors, themeData, defs) : '';
698
+ ? await shapesToSvg(layoutTree, layoutRels, files, themeColors, themeData, defs) : '';
703
699
  const slideSvg = slideTree
704
- ? await shapesToSvg(slideTree, slideRels, allImages, themeColors, themeData, defs) : '';
700
+ ? await shapesToSvg(slideTree, slideRels, files, themeColors, themeData, defs) : '';
705
701
 
706
702
  const defsBlock = defs.length ? `<defs>${defs.join('\n')}</defs>` : '';
707
703