quicklook-pptx-renderer 0.1.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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +266 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +175 -0
  5. package/dist/diff/compare.d.ts +17 -0
  6. package/dist/diff/compare.js +71 -0
  7. package/dist/index.d.ts +29 -0
  8. package/dist/index.js +72 -0
  9. package/dist/lint.d.ts +27 -0
  10. package/dist/lint.js +328 -0
  11. package/dist/mapper/bleed-map.d.ts +6 -0
  12. package/dist/mapper/bleed-map.js +1 -0
  13. package/dist/mapper/constants.d.ts +2 -0
  14. package/dist/mapper/constants.js +4 -0
  15. package/dist/mapper/drawable-mapper.d.ts +16 -0
  16. package/dist/mapper/drawable-mapper.js +1464 -0
  17. package/dist/mapper/html-generator.d.ts +13 -0
  18. package/dist/mapper/html-generator.js +539 -0
  19. package/dist/mapper/image-mapper.d.ts +14 -0
  20. package/dist/mapper/image-mapper.js +70 -0
  21. package/dist/mapper/nano-malloc.d.ts +130 -0
  22. package/dist/mapper/nano-malloc.js +197 -0
  23. package/dist/mapper/ql-bleed.d.ts +35 -0
  24. package/dist/mapper/ql-bleed.js +254 -0
  25. package/dist/mapper/shape-mapper.d.ts +41 -0
  26. package/dist/mapper/shape-mapper.js +2384 -0
  27. package/dist/mapper/slide-mapper.d.ts +4 -0
  28. package/dist/mapper/slide-mapper.js +112 -0
  29. package/dist/mapper/style-builder.d.ts +12 -0
  30. package/dist/mapper/style-builder.js +30 -0
  31. package/dist/mapper/text-mapper.d.ts +14 -0
  32. package/dist/mapper/text-mapper.js +302 -0
  33. package/dist/model/enums.d.ts +25 -0
  34. package/dist/model/enums.js +2 -0
  35. package/dist/model/types.d.ts +482 -0
  36. package/dist/model/types.js +7 -0
  37. package/dist/package/content-types.d.ts +1 -0
  38. package/dist/package/content-types.js +4 -0
  39. package/dist/package/package.d.ts +10 -0
  40. package/dist/package/package.js +52 -0
  41. package/dist/package/relationships.d.ts +6 -0
  42. package/dist/package/relationships.js +25 -0
  43. package/dist/package/zip.d.ts +6 -0
  44. package/dist/package/zip.js +17 -0
  45. package/dist/reader/color.d.ts +3 -0
  46. package/dist/reader/color.js +79 -0
  47. package/dist/reader/drawing.d.ts +17 -0
  48. package/dist/reader/drawing.js +403 -0
  49. package/dist/reader/effects.d.ts +2 -0
  50. package/dist/reader/effects.js +83 -0
  51. package/dist/reader/fill.d.ts +2 -0
  52. package/dist/reader/fill.js +94 -0
  53. package/dist/reader/presentation.d.ts +5 -0
  54. package/dist/reader/presentation.js +127 -0
  55. package/dist/reader/slide-layout.d.ts +2 -0
  56. package/dist/reader/slide-layout.js +28 -0
  57. package/dist/reader/slide-master.d.ts +4 -0
  58. package/dist/reader/slide-master.js +49 -0
  59. package/dist/reader/slide.d.ts +2 -0
  60. package/dist/reader/slide.js +26 -0
  61. package/dist/reader/text-list-style.d.ts +2 -0
  62. package/dist/reader/text-list-style.js +9 -0
  63. package/dist/reader/text.d.ts +5 -0
  64. package/dist/reader/text.js +295 -0
  65. package/dist/reader/theme.d.ts +2 -0
  66. package/dist/reader/theme.js +109 -0
  67. package/dist/reader/transform.d.ts +2 -0
  68. package/dist/reader/transform.js +21 -0
  69. package/dist/render/image-renderer.d.ts +3 -0
  70. package/dist/render/image-renderer.js +33 -0
  71. package/dist/render/renderer.d.ts +9 -0
  72. package/dist/render/renderer.js +178 -0
  73. package/dist/render/shape-renderer.d.ts +3 -0
  74. package/dist/render/shape-renderer.js +175 -0
  75. package/dist/render/text-renderer.d.ts +3 -0
  76. package/dist/render/text-renderer.js +152 -0
  77. package/dist/resolve/color-resolver.d.ts +18 -0
  78. package/dist/resolve/color-resolver.js +321 -0
  79. package/dist/resolve/font-map.d.ts +2 -0
  80. package/dist/resolve/font-map.js +66 -0
  81. package/dist/resolve/inheritance.d.ts +5 -0
  82. package/dist/resolve/inheritance.js +106 -0
  83. package/package.json +74 -0
@@ -0,0 +1,17 @@
1
+ import type { Drawable, Shape, Picture, Group, Connector, GraphicFrame } from "../model/types.js";
2
+ export declare function readShape(sp: any): Shape;
3
+ export declare function readPicture(pic: any): Picture;
4
+ export declare function readGroup(grpSp: any): Group;
5
+ export declare function readConnector(cxnSp: any): Connector;
6
+ export declare function readGraphicFrame(gf: any): GraphicFrame;
7
+ /**
8
+ * Recover XML document order for spTree children.
9
+ *
10
+ * fast-xml-parser groups elements by tag name, losing the interleaving order.
11
+ * OfficeImport uses XML document order for z-ordering. We recover it by scanning
12
+ * the raw XML with a regex to extract the sequence of child tag names, then
13
+ * pick from each tag's parsed array in that order.
14
+ *
15
+ * If rawXml is not provided, falls back to ID sort (less accurate for non-sequential IDs).
16
+ */
17
+ export declare function readDrawables(spTree: any, rawXml?: string): Drawable[];
@@ -0,0 +1,403 @@
1
+ import { readColor } from "./color.js";
2
+ import { readFill } from "./fill.js";
3
+ import { readTransform } from "./transform.js";
4
+ import { readEffects } from "./effects.js";
5
+ import { readTextBody } from "./text.js";
6
+ function toArray(val) {
7
+ return val == null ? [] : Array.isArray(val) ? val : [val];
8
+ }
9
+ function toNum(val) {
10
+ return val == null ? undefined : Number(val);
11
+ }
12
+ // ── Common helpers ─────────────────────────────────
13
+ function readNonVisual(nvPr) {
14
+ const cNvPr = nvPr?.cNvPr ?? {};
15
+ const base = {
16
+ id: Number(cNvPr["@_id"] ?? 0),
17
+ name: cNvPr["@_name"] ?? "",
18
+ };
19
+ if (cNvPr["@_descr"])
20
+ base.description = cNvPr["@_descr"];
21
+ if (cNvPr["@_hidden"] === "1" || cNvPr["@_hidden"] === "true")
22
+ base.hidden = true;
23
+ if (cNvPr.hlinkClick?.["@_id"])
24
+ base.hyperlink = cNvPr.hlinkClick["@_id"];
25
+ const ph = nvPr?.nvPr?.ph;
26
+ if (ph != null) {
27
+ const info = {};
28
+ if (ph["@_type"])
29
+ info.type = ph["@_type"];
30
+ if (ph["@_idx"] != null)
31
+ info.idx = Number(ph["@_idx"]);
32
+ base.placeholder = info;
33
+ }
34
+ return base;
35
+ }
36
+ function readLineEnd(node) {
37
+ if (node == null)
38
+ return undefined;
39
+ const type = node["@_type"];
40
+ if (!type)
41
+ return undefined;
42
+ const end = { type };
43
+ if (node["@_w"])
44
+ end.width = node["@_w"];
45
+ if (node["@_len"])
46
+ end.length = node["@_len"];
47
+ return end;
48
+ }
49
+ function readStroke(node) {
50
+ if (node == null)
51
+ return undefined;
52
+ const s = {};
53
+ if (node["@_w"] != null)
54
+ s.width = Number(node["@_w"]);
55
+ if (node["@_cap"])
56
+ s.cap = node["@_cap"];
57
+ if (node["@_cmpd"])
58
+ s.compound = node["@_cmpd"];
59
+ const fill = readFill(node);
60
+ if (fill)
61
+ s.fill = fill;
62
+ if (node.prstDash?.["@_val"])
63
+ s.dash = node.prstDash["@_val"];
64
+ if (node.round != null)
65
+ s.join = "round";
66
+ else if (node.bevel != null)
67
+ s.join = "bevel";
68
+ else if (node.miter != null) {
69
+ s.join = "miter";
70
+ if (node.miter["@_lim"] != null)
71
+ s.miterLimit = Number(node.miter["@_lim"]);
72
+ }
73
+ const head = readLineEnd(node.headEnd);
74
+ const tail = readLineEnd(node.tailEnd);
75
+ if (head)
76
+ s.headEnd = head;
77
+ if (tail)
78
+ s.tailEnd = tail;
79
+ return s;
80
+ }
81
+ function readGeometry(spPr) {
82
+ const prstGeom = spPr.prstGeom;
83
+ if (prstGeom == null)
84
+ return undefined;
85
+ const geom = {};
86
+ if (prstGeom["@_prst"])
87
+ geom.preset = prstGeom["@_prst"];
88
+ const gds = toArray(prstGeom.avLst?.gd);
89
+ if (gds.length) {
90
+ const adj = {};
91
+ for (const gd of gds) {
92
+ if (gd["@_name"] && gd["@_fmla"])
93
+ adj[gd["@_name"]] = gd["@_fmla"];
94
+ }
95
+ if (Object.keys(adj).length)
96
+ geom.adjustValues = adj;
97
+ }
98
+ return geom;
99
+ }
100
+ function readStyleRef(node) {
101
+ if (node == null)
102
+ return undefined;
103
+ const ref = { idx: Number(node["@_idx"] ?? 0) };
104
+ const color = readColor(node);
105
+ if (color)
106
+ ref.color = color;
107
+ return ref;
108
+ }
109
+ function readShapeStyle(style) {
110
+ if (style == null)
111
+ return undefined;
112
+ const ss = {};
113
+ const lnRef = readStyleRef(style.lnRef);
114
+ if (lnRef)
115
+ ss.lnRef = lnRef;
116
+ const fillRef = readStyleRef(style.fillRef);
117
+ if (fillRef)
118
+ ss.fillRef = fillRef;
119
+ const effectRef = readStyleRef(style.effectRef);
120
+ if (effectRef)
121
+ ss.effectRef = effectRef;
122
+ if (style.fontRef) {
123
+ const fr = {
124
+ idx: (style.fontRef["@_idx"] ?? "none"),
125
+ };
126
+ const color = readColor(style.fontRef);
127
+ if (color)
128
+ fr.color = color;
129
+ ss.fontRef = fr;
130
+ }
131
+ return ss;
132
+ }
133
+ // ── Shape readers ──────────────────────────────────
134
+ export function readShape(sp) {
135
+ const base = readNonVisual(sp.nvSpPr);
136
+ const spPr = sp.spPr ?? {};
137
+ const shape = { ...base, drawableType: "sp" };
138
+ shape.bounds = readTransform(spPr.xfrm);
139
+ shape.geometry = readGeometry(spPr);
140
+ const fill = readFill(spPr);
141
+ if (fill)
142
+ shape.fill = fill;
143
+ const stroke = readStroke(spPr.ln);
144
+ if (stroke)
145
+ shape.stroke = stroke;
146
+ const effects = readEffects(spPr.effectLst);
147
+ if (effects.length)
148
+ shape.effects = effects;
149
+ if (sp.txBody)
150
+ shape.textBody = readTextBody(sp.txBody);
151
+ const style = readShapeStyle(sp.style);
152
+ if (style)
153
+ shape.shapeStyle = style;
154
+ return shape;
155
+ }
156
+ export function readPicture(pic) {
157
+ const base = readNonVisual(pic.nvPicPr);
158
+ const spPr = pic.spPr ?? {};
159
+ const p = { ...base, drawableType: "pic" };
160
+ p.bounds = readTransform(spPr.xfrm);
161
+ // blipFill
162
+ const bf = pic.blipFill;
163
+ if (bf) {
164
+ if (bf.blip?.["@_embed"])
165
+ p.blipRId = bf.blip["@_embed"];
166
+ const imgFill = readFill({ blipFill: bf });
167
+ if (imgFill)
168
+ p.fill = imgFill;
169
+ }
170
+ p.geometry = readGeometry(spPr);
171
+ // shape-level properties
172
+ const shapeFill = readFill(spPr);
173
+ const shapeStroke = readStroke(spPr.ln);
174
+ const shapeEffects = readEffects(spPr.effectLst);
175
+ if (shapeFill || shapeStroke || shapeEffects.length) {
176
+ p.shapeProperties = {};
177
+ if (shapeFill)
178
+ p.shapeProperties.fill = shapeFill;
179
+ if (shapeStroke)
180
+ p.shapeProperties.stroke = shapeStroke;
181
+ if (shapeEffects.length)
182
+ p.shapeProperties.effects = shapeEffects;
183
+ }
184
+ return p;
185
+ }
186
+ export function readGroup(grpSp) {
187
+ const base = readNonVisual(grpSp.nvGrpSpPr);
188
+ const grpSpPr = grpSp.grpSpPr ?? {};
189
+ const g = { ...base, drawableType: "grpSp", children: [] };
190
+ const xfrm = grpSpPr.xfrm;
191
+ if (xfrm) {
192
+ g.bounds = readTransform(xfrm);
193
+ // child offset/extent
194
+ const chOff = xfrm.chOff;
195
+ const chExt = xfrm.chExt;
196
+ if (chOff && chExt) {
197
+ g.childBounds = {
198
+ x: Number(chOff["@_x"] ?? 0),
199
+ y: Number(chOff["@_y"] ?? 0),
200
+ cx: Number(chExt["@_cx"] ?? 0),
201
+ cy: Number(chExt["@_cy"] ?? 0),
202
+ };
203
+ }
204
+ }
205
+ g.children = readChildDrawables(grpSp);
206
+ return g;
207
+ }
208
+ export function readConnector(cxnSp) {
209
+ const base = readNonVisual(cxnSp.nvCxnSpPr);
210
+ const spPr = cxnSp.spPr ?? {};
211
+ const c = { ...base, drawableType: "cxnSp" };
212
+ c.bounds = readTransform(spPr.xfrm);
213
+ c.geometry = readGeometry(spPr);
214
+ const fill = readFill(spPr);
215
+ if (fill)
216
+ c.fill = fill;
217
+ const stroke = readStroke(spPr.ln);
218
+ if (stroke)
219
+ c.stroke = stroke;
220
+ return c;
221
+ }
222
+ export function readGraphicFrame(gf) {
223
+ const base = readNonVisual(gf.nvGraphicFramePr);
224
+ const f = { ...base, drawableType: "graphicFrame" };
225
+ f.bounds = readTransform(gf.xfrm);
226
+ const graphicData = gf.graphic?.graphicData;
227
+ // chart relationship
228
+ const chart = graphicData?.chart;
229
+ if (chart?.["@_id"])
230
+ f.chartRId = chart["@_id"];
231
+ // SmartArt/diagram relationship
232
+ const relIds = graphicData?.relIds;
233
+ if (relIds?.["@_dm"])
234
+ f.smartArtRId = relIds["@_dm"];
235
+ // OLE object
236
+ const oleObj = graphicData?.oleObj;
237
+ if (oleObj?.["@_id"])
238
+ f.oleRId = oleObj["@_id"];
239
+ // table
240
+ const tbl = graphicData?.tbl;
241
+ if (tbl)
242
+ f.tableData = readTable(tbl);
243
+ return f;
244
+ }
245
+ function readTable(tbl) {
246
+ const gridCols = toArray(tbl.tblGrid?.gridCol).map((gc) => Number(gc["@_w"] ?? 0));
247
+ const tblPr = tbl.tblPr;
248
+ const props = tblPr ? {
249
+ firstRow: tblPr["@_firstRow"] === "1",
250
+ lastRow: tblPr["@_lastRow"] === "1",
251
+ bandRow: tblPr["@_bandRow"] === "1",
252
+ bandCol: tblPr["@_bandCol"] === "1",
253
+ } : undefined;
254
+ const rows = toArray(tbl.tr).map((tr) => {
255
+ const height = Number(tr["@_h"] ?? 0);
256
+ const cells = toArray(tr.tc).map((tc) => {
257
+ const cell = {};
258
+ if (tc.txBody)
259
+ cell.textBody = readTextBody(tc.txBody);
260
+ // gridSpan, hMerge, vMerge are attributes of <a:tc>, not <a:tcPr>
261
+ if (tc["@_gridSpan"] != null)
262
+ cell.gridSpan = Number(tc["@_gridSpan"]);
263
+ if (tc["@_rowSpan"] != null)
264
+ cell.rowSpan = Number(tc["@_rowSpan"]);
265
+ if (tc["@_hMerge"] === "1")
266
+ cell.hMerge = true;
267
+ if (tc["@_vMerge"] === "1")
268
+ cell.vMerge = true;
269
+ const tcPr = tc.tcPr;
270
+ if (tcPr) {
271
+ const fill = readFill(tcPr);
272
+ if (fill)
273
+ cell.fill = fill;
274
+ const borders = {};
275
+ let hasBorder = false;
276
+ for (const side of ["left", "right", "top", "bottom"]) {
277
+ const tag = side === "left" ? "lnL" : side === "right" ? "lnR" : side === "top" ? "lnT" : "lnB";
278
+ const ln = tcPr[tag];
279
+ if (ln) {
280
+ borders[side] = readStroke(ln);
281
+ hasBorder = true;
282
+ }
283
+ }
284
+ if (hasBorder)
285
+ cell.borders = borders;
286
+ if (tcPr["@_anchor"])
287
+ cell.anchor = tcPr["@_anchor"];
288
+ }
289
+ return cell;
290
+ });
291
+ return { height, cells };
292
+ });
293
+ const td = { rows, gridCols };
294
+ if (props)
295
+ td.properties = props;
296
+ const styleId = tblPr?.tableStyleId;
297
+ if (styleId)
298
+ td.tableStyleId = String(styleId);
299
+ return td;
300
+ }
301
+ // ── Tree reader ────────────────────────────────────
302
+ function readChildDrawables(parent) {
303
+ const drawables = [];
304
+ for (const sp of toArray(parent.sp))
305
+ drawables.push(readShape(sp));
306
+ for (const pic of toArray(parent.pic))
307
+ drawables.push(readPicture(pic));
308
+ for (const grp of toArray(parent.grpSp))
309
+ drawables.push(readGroup(grp));
310
+ for (const cxn of toArray(parent.cxnSp))
311
+ drawables.push(readConnector(cxn));
312
+ for (const gf of toArray(parent.graphicFrame))
313
+ drawables.push(readGraphicFrame(gf));
314
+ // mc:AlternateContent: extract drawables from Fallback child (Choice requires features
315
+ // the reader may not support, e.g. chart rendering). OfficeImport uses the fallback
316
+ // which typically contains a pre-rendered image (<p:pic>) or simplified shape.
317
+ for (const ac of toArray(parent.AlternateContent)) {
318
+ const fallback = ac.Fallback ?? ac.Choice;
319
+ if (fallback) {
320
+ const fallbackDrawables = readChildDrawables(fallback);
321
+ drawables.push(...fallbackDrawables);
322
+ }
323
+ }
324
+ return drawables;
325
+ }
326
+ /**
327
+ * Recover XML document order for spTree children.
328
+ *
329
+ * fast-xml-parser groups elements by tag name, losing the interleaving order.
330
+ * OfficeImport uses XML document order for z-ordering. We recover it by scanning
331
+ * the raw XML with a regex to extract the sequence of child tag names, then
332
+ * pick from each tag's parsed array in that order.
333
+ *
334
+ * If rawXml is not provided, falls back to ID sort (less accurate for non-sequential IDs).
335
+ */
336
+ export function readDrawables(spTree, rawXml) {
337
+ if (spTree == null)
338
+ return [];
339
+ const drawables = readChildDrawables(spTree);
340
+ if (rawXml) {
341
+ return reorderByXml(drawables, rawXml);
342
+ }
343
+ // Fallback: sort by ID (works when IDs are sequential)
344
+ drawables.sort((a, b) => a.id - b.id);
345
+ return drawables;
346
+ }
347
+ const DRAWABLE_TAGS = new Set(["sp", "pic", "grpSp", "cxnSp", "graphicFrame"]);
348
+ function reorderByXml(drawables, rawXml) {
349
+ // Extract the tag order from spTree children in the raw XML.
350
+ // Match opening tags: <p:sp, <p:pic, <p:grpSp, <p:cxnSp, <p:graphicFrame
351
+ // Also match without namespace prefix (after removeNSPrefix processing, but raw XML has them).
352
+ const tagOrder = [];
353
+ const tagRegex = /<(?:p:|wsp:)?(?:mc:)?(?:AlternateContent|sp|pic|grpSp|cxnSp|graphicFrame)\b/g;
354
+ let m;
355
+ // Find the spTree region in the raw XML
356
+ const spTreeStart = rawXml.indexOf("<p:spTree");
357
+ const spTreeEnd = rawXml.indexOf("</p:spTree>");
358
+ if (spTreeStart === -1 || spTreeEnd === -1) {
359
+ drawables.sort((a, b) => a.id - b.id);
360
+ return drawables;
361
+ }
362
+ const spTreeXml = rawXml.substring(spTreeStart, spTreeEnd);
363
+ // Track nesting depth to only capture direct children of spTree
364
+ // Simple approach: just capture all tag names in order and skip non-drawable tags
365
+ while ((m = tagRegex.exec(spTreeXml)) !== null) {
366
+ const tag = m[0];
367
+ // Extract tag name after prefix
368
+ const nameMatch = tag.match(/(?:p:|wsp:)?(sp|pic|grpSp|cxnSp|graphicFrame|AlternateContent)$/);
369
+ if (nameMatch && DRAWABLE_TAGS.has(nameMatch[1])) {
370
+ tagOrder.push(nameMatch[1]);
371
+ }
372
+ }
373
+ // Build per-tag queues from the drawables array
374
+ const queues = new Map();
375
+ for (const d of drawables) {
376
+ const tag = d.drawableType === "grpSp" ? "grpSp" : d.drawableType;
377
+ const q = queues.get(tag) ?? [];
378
+ q.push(d);
379
+ queues.set(tag, q);
380
+ }
381
+ // Per-tag index pointers
382
+ const ptrs = new Map();
383
+ for (const [tag] of queues)
384
+ ptrs.set(tag, 0);
385
+ // Rebuild in XML document order
386
+ const ordered = [];
387
+ for (const tag of tagOrder) {
388
+ const q = queues.get(tag);
389
+ const ptr = ptrs.get(tag) ?? 0;
390
+ if (q && ptr < q.length) {
391
+ ordered.push(q[ptr]);
392
+ ptrs.set(tag, ptr + 1);
393
+ }
394
+ }
395
+ // Append any remaining drawables not matched (safety net)
396
+ for (const [tag, q] of queues) {
397
+ const ptr = ptrs.get(tag) ?? 0;
398
+ for (let i = ptr; i < q.length; i++) {
399
+ ordered.push(q[i]);
400
+ }
401
+ }
402
+ return ordered;
403
+ }
@@ -0,0 +1,2 @@
1
+ import type { Effect } from "../model/types.js";
2
+ export declare function readEffects(effectLst: any): Effect[];
@@ -0,0 +1,83 @@
1
+ import { readColor } from "./color.js";
2
+ function toBool(val) {
3
+ if (val == null)
4
+ return undefined;
5
+ return val === "1" || val === "true";
6
+ }
7
+ function toNum(val) {
8
+ return val == null ? undefined : Number(val);
9
+ }
10
+ function readOuterShadow(node) {
11
+ const e = { type: "outerShdw" };
12
+ e.blurRad = toNum(node["@_blurRad"]);
13
+ e.dist = toNum(node["@_dist"]);
14
+ e.dir = toNum(node["@_dir"]);
15
+ e.sx = toNum(node["@_sx"]);
16
+ e.sy = toNum(node["@_sy"]);
17
+ e.kx = toNum(node["@_kx"]);
18
+ e.ky = toNum(node["@_ky"]);
19
+ if (node["@_algn"])
20
+ e.algn = node["@_algn"];
21
+ e.rotWithShape = toBool(node["@_rotWithShape"]);
22
+ const color = readColor(node);
23
+ if (color)
24
+ e.color = color;
25
+ return e;
26
+ }
27
+ function readInnerShadow(node) {
28
+ const e = { type: "innerShdw" };
29
+ e.blurRad = toNum(node["@_blurRad"]);
30
+ e.dist = toNum(node["@_dist"]);
31
+ e.dir = toNum(node["@_dir"]);
32
+ const color = readColor(node);
33
+ if (color)
34
+ e.color = color;
35
+ return e;
36
+ }
37
+ function readGlow(node) {
38
+ const e = { type: "glow" };
39
+ e.rad = toNum(node["@_rad"]);
40
+ const color = readColor(node);
41
+ if (color)
42
+ e.color = color;
43
+ return e;
44
+ }
45
+ function readReflection(node) {
46
+ const e = { type: "reflection" };
47
+ e.blurRad = toNum(node["@_blurRad"]);
48
+ e.stA = toNum(node["@_stA"]);
49
+ e.endA = toNum(node["@_endA"]);
50
+ e.dist = toNum(node["@_dist"]);
51
+ e.dir = toNum(node["@_dir"]);
52
+ e.fadeDir = toNum(node["@_fadeDir"]);
53
+ e.sx = toNum(node["@_sx"]);
54
+ e.sy = toNum(node["@_sy"]);
55
+ e.kx = toNum(node["@_kx"]);
56
+ e.ky = toNum(node["@_ky"]);
57
+ if (node["@_algn"])
58
+ e.algn = node["@_algn"];
59
+ e.rotWithShape = toBool(node["@_rotWithShape"]);
60
+ return e;
61
+ }
62
+ function readBlur(node) {
63
+ const e = { type: "blur" };
64
+ e.rad = toNum(node["@_rad"]);
65
+ e.grow = toBool(node["@_grow"]);
66
+ return e;
67
+ }
68
+ export function readEffects(effectLst) {
69
+ if (effectLst == null)
70
+ return [];
71
+ const effects = [];
72
+ if (effectLst.outerShdw)
73
+ effects.push(readOuterShadow(effectLst.outerShdw));
74
+ if (effectLst.innerShdw)
75
+ effects.push(readInnerShadow(effectLst.innerShdw));
76
+ if (effectLst.glow)
77
+ effects.push(readGlow(effectLst.glow));
78
+ if (effectLst.reflection)
79
+ effects.push(readReflection(effectLst.reflection));
80
+ if (effectLst.blur)
81
+ effects.push(readBlur(effectLst.blur));
82
+ return effects;
83
+ }
@@ -0,0 +1,2 @@
1
+ import type { Fill } from "../model/types.js";
2
+ export declare function readFill(node: any): Fill | undefined;
@@ -0,0 +1,94 @@
1
+ import { readColor } from "./color.js";
2
+ function toArray(val) {
3
+ return val == null ? [] : Array.isArray(val) ? val : [val];
4
+ }
5
+ function readRelativeRect(node) {
6
+ if (node == null)
7
+ return undefined;
8
+ const r = {};
9
+ if (node["@_l"] != null)
10
+ r.l = Number(node["@_l"]);
11
+ if (node["@_t"] != null)
12
+ r.t = Number(node["@_t"]);
13
+ if (node["@_r"] != null)
14
+ r.r = Number(node["@_r"]);
15
+ if (node["@_b"] != null)
16
+ r.b = Number(node["@_b"]);
17
+ return r;
18
+ }
19
+ function readSolidFill(node) {
20
+ const color = readColor(node);
21
+ return color ? { type: "solid", color } : undefined;
22
+ }
23
+ function readGradientFill(node) {
24
+ const stops = toArray(node.gsLst?.gs).map((gs) => ({
25
+ position: Number(gs["@_pos"] ?? 0),
26
+ color: readColor(gs),
27
+ })).filter((s) => s.color);
28
+ const fill = { type: "gradient", stops };
29
+ if (node.lin) {
30
+ fill.linear = {
31
+ angle: Number(node.lin["@_ang"] ?? 5400000),
32
+ scaled: node.lin["@_scaled"] === "1" || node.lin["@_scaled"] === "true",
33
+ };
34
+ }
35
+ if (node.path) {
36
+ fill.path = {
37
+ type: node.path["@_path"] ?? "shape",
38
+ fillToRect: readRelativeRect(node.path.fillToRect),
39
+ };
40
+ }
41
+ if (node["@_rotWithShape"] != null) {
42
+ fill.rotateWithShape = node["@_rotWithShape"] === "1" || node["@_rotWithShape"] === "true";
43
+ }
44
+ return fill;
45
+ }
46
+ function readImageFill(node) {
47
+ const fill = { type: "image" };
48
+ if (node.blip?.["@_embed"])
49
+ fill.blipRId = node.blip["@_embed"];
50
+ if (node.stretch) {
51
+ fill.stretch = { fillRect: readRelativeRect(node.stretch.fillRect) };
52
+ }
53
+ if (node.tile) {
54
+ const t = node.tile;
55
+ fill.tile = {
56
+ tx: Number(t["@_tx"] ?? 0),
57
+ ty: Number(t["@_ty"] ?? 0),
58
+ sx: Number(t["@_sx"] ?? 100000),
59
+ sy: Number(t["@_sy"] ?? 100000),
60
+ };
61
+ if (t["@_flip"])
62
+ fill.tile.flip = t["@_flip"];
63
+ if (t["@_algn"])
64
+ fill.tile.algn = t["@_algn"];
65
+ }
66
+ return fill;
67
+ }
68
+ function readPatternFill(node) {
69
+ const fill = { type: "pattern", preset: node["@_prst"] ?? "solid" };
70
+ const fg = readColor(node.fgClr);
71
+ const bg = readColor(node.bgClr);
72
+ if (fg)
73
+ fill.foreground = fg;
74
+ if (bg)
75
+ fill.background = bg;
76
+ return fill;
77
+ }
78
+ export function readFill(node) {
79
+ if (node == null)
80
+ return undefined;
81
+ if (node.solidFill)
82
+ return readSolidFill(node.solidFill);
83
+ if (node.gradFill)
84
+ return readGradientFill(node.gradFill);
85
+ if (node.blipFill)
86
+ return readImageFill(node.blipFill);
87
+ if (node.pattFill)
88
+ return readPatternFill(node.pattFill);
89
+ if (node.noFill != null)
90
+ return { type: "noFill" };
91
+ if (node.grpFill != null)
92
+ return { type: "grpFill" };
93
+ return undefined;
94
+ }
@@ -0,0 +1,5 @@
1
+ import type { Presentation } from "../model/types.js";
2
+ import type { PptxPackage } from "../package/package.js";
3
+ import { readTextListStyle } from "./text-list-style.js";
4
+ export { readTextListStyle };
5
+ export declare function readPresentation(pkg: PptxPackage): Promise<Presentation>;