reamkit 1.23.0 → 1.25.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.
- package/README.md +22 -11
- package/dist/esm/core/bmp.d.ts +33 -0
- package/dist/esm/core/bmp.js +276 -0
- package/dist/esm/core/converter/facade.d.ts +3 -3
- package/dist/esm/core/converter/facade.js +12 -0
- package/dist/esm/core/converter/ream.d.ts +48 -4
- package/dist/esm/core/converter/ream.js +25 -4
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +54 -0
- package/dist/esm/core/drawingml/chart-geometry.js +3 -2
- package/dist/esm/core/drawingml/diagram/colors.d.ts +52 -0
- package/dist/esm/core/drawingml/diagram/colors.js +125 -0
- package/dist/esm/core/drawingml/diagram/data-model.d.ts +47 -0
- package/dist/esm/core/drawingml/diagram/data-model.js +119 -0
- package/dist/esm/core/drawingml/diagram/layout-engine.d.ts +46 -0
- package/dist/esm/core/drawingml/diagram/layout-engine.js +948 -0
- package/dist/esm/core/drawingml/diagram/run.d.ts +37 -0
- package/dist/esm/core/drawingml/diagram/run.js +50 -0
- package/dist/esm/core/drawingml/diagram/to-drawing.d.ts +16 -0
- package/dist/esm/core/drawingml/diagram/to-drawing.js +86 -0
- package/dist/esm/core/drawingml/preset-geometry.js +116 -6
- package/dist/esm/core/drawingml/text-warp.d.ts +58 -0
- package/dist/esm/core/drawingml/text-warp.js +355 -0
- package/dist/esm/core/drawingml/theme-parser.js +9 -3
- package/dist/esm/core/font/measure.d.ts +12 -0
- package/dist/esm/core/font/measure.js +36 -0
- package/dist/esm/core/images.d.ts +30 -2
- package/dist/esm/core/images.js +121 -5
- package/dist/esm/core/metafile/emf.js +144 -16
- package/dist/esm/core/metafile/picture.d.ts +49 -0
- package/dist/esm/core/metafile/picture.js +70 -1
- package/dist/esm/core/metafile/wmf.js +53 -4
- package/dist/esm/core/ole/escher-blip.js +11 -1
- package/dist/esm/core/outline.d.ts +17 -0
- package/dist/esm/core/outline.js +30 -0
- package/dist/esm/core/style-cascade/resolver.js +1 -0
- package/dist/esm/core/style-cascade/types.d.ts +3 -1
- package/dist/esm/excel/print-model.js +2 -2
- package/dist/esm/excel/sheet-drawing.js +1 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +10 -0
- package/dist/esm/excel/sheet-to-flow.js +30 -3
- package/dist/esm/html/html-writer.js +5 -3
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/layout/page-doc.d.ts +35 -0
- package/dist/esm/layout/page-doc.js +14 -1
- package/dist/esm/layout/styled-layout.js +217 -30
- package/dist/esm/markdown/markdown-writer.d.ts +41 -0
- package/dist/esm/markdown/markdown-writer.js +733 -0
- package/dist/esm/pdf/shading.js +8 -6
- package/dist/esm/pdf/styled-page-emitter.js +62 -4
- package/dist/esm/pdf/vector-graphics.js +1 -1
- package/dist/esm/pdf-reader/annots.d.ts +24 -0
- package/dist/esm/pdf-reader/annots.js +126 -0
- package/dist/esm/pdf-reader/content.d.ts +131 -5
- package/dist/esm/pdf-reader/content.js +169 -12
- package/dist/esm/pdf-reader/display.d.ts +56 -0
- package/dist/esm/pdf-reader/display.js +162 -0
- package/dist/esm/pdf-reader/document.d.ts +36 -1
- package/dist/esm/pdf-reader/document.js +92 -25
- package/dist/esm/pdf-reader/embedded-fonts.d.ts +31 -0
- package/dist/esm/pdf-reader/embedded-fonts.js +94 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +61 -6
- package/dist/esm/pdf-reader/flow-build.js +128 -22
- package/dist/esm/pdf-reader/font.js +185 -4
- package/dist/esm/pdf-reader/image-decode.js +56 -5
- package/dist/esm/pdf-reader/images.d.ts +6 -0
- package/dist/esm/pdf-reader/images.js +25 -5
- package/dist/esm/pdf-reader/jpeg.d.ts +18 -0
- package/dist/esm/pdf-reader/jpeg.js +419 -0
- package/dist/esm/pdf-reader/layout.d.ts +1 -1
- package/dist/esm/pdf-reader/layout.js +221 -32
- package/dist/esm/pdf-reader/pattern-tint.d.ts +17 -0
- package/dist/esm/pdf-reader/pattern-tint.js +181 -0
- package/dist/esm/pdf-reader/reader.d.ts +9 -1
- package/dist/esm/pdf-reader/reader.js +22 -6
- package/dist/esm/pdf-reader/shading.d.ts +14 -0
- package/dist/esm/pdf-reader/shading.js +27 -1
- package/dist/esm/pdf-reader/tagged.js +156 -17
- package/dist/esm/pdf-reader/text.d.ts +13 -1
- package/dist/esm/pdf-reader/text.js +70 -3
- package/dist/esm/pdf-reader/vector.d.ts +25 -1
- package/dist/esm/pdf-reader/vector.js +168 -12
- package/dist/esm/pptx/ppt/ppt-reader.js +95 -27
- package/dist/esm/pptx/ppt/ppt-text.d.ts +41 -0
- package/dist/esm/pptx/ppt/ppt-text.js +327 -37
- package/dist/esm/pptx/pptx-reader.js +90 -10
- package/dist/esm/pptx/slide-parser.d.ts +4 -1
- package/dist/esm/pptx/slide-parser.js +104 -13
- package/dist/esm/pptx/sp-helpers.d.ts +7 -3
- package/dist/esm/pptx/sp-helpers.js +45 -7
- package/dist/esm/pptx/table-style.d.ts +7 -0
- package/dist/esm/pptx/table-style.js +59 -7
- package/dist/esm/svg/svg-writer.js +1 -0
- package/dist/esm/word/document-parser.d.ts +4 -1
- package/dist/esm/word/document-parser.js +4 -1
- package/dist/esm/word/docx-reader.js +26 -13
- package/dist/esm/word/docx-writer.js +15 -1
- package/dist/esm/word/drawing-parser.d.ts +20 -0
- package/dist/esm/word/drawing-parser.js +44 -5
- package/dist/esm/word/table-parser.js +3 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { FEATURES } from "../core/ir/features.js";
|
|
|
4
4
|
import { EMPTY_STYLE_SHEET, resolveBodyStyles } from "../core/style-cascade/resolver.js";
|
|
5
5
|
import "../core/style-cascade/index.js";
|
|
6
6
|
import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs } from "../core/po-helpers.js";
|
|
7
|
+
import { cachedDiagramTree, laidOutDiagramTree } from "../core/drawingml/diagram/run.js";
|
|
7
8
|
import { packageHasPart } from "../core/bytes.js";
|
|
8
9
|
import { DEFAULT_SCHEME_ALIAS, DEFAULT_THEME_PALETTE, defaultColorResolver, makeColorResolver } from "../core/drawingml/colors.js";
|
|
9
10
|
import { parseChart, withChartColorStyle } from "../core/drawingml/chart-parser.js";
|
|
@@ -207,7 +208,81 @@ function parseSlide(tree, ctx, inheritedBg, pageW, pageH, inheritedShapes = [])
|
|
|
207
208
|
if (bg) out.push(backdropElement(bg, pageW, pageH));
|
|
208
209
|
out.push(...inheritedShapes.map(asBackdrop));
|
|
209
210
|
if (spTree) out.push(...parseSlideShapes(spTree, shapeCtx));
|
|
210
|
-
|
|
211
|
+
out.push(...parseSlideControls(cSld, shapeCtx));
|
|
212
|
+
return inPaintOrder(out);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* §19.3.1 — a slide's shape tree IS its z-order: what stands later in it is
|
|
216
|
+
* drawn over what stands earlier, whatever KIND either of them is.
|
|
217
|
+
*
|
|
218
|
+
* The page otherwise paints kind by kind — every image, then every shape — and
|
|
219
|
+
* on a slide that is simply wrong. 54542_cropped_bitmap.pptx is six logos each
|
|
220
|
+
* standing on its own coloured panel, written panel-then-logo six times over,
|
|
221
|
+
* and painted by kind all six logos went down first and all six panels covered
|
|
222
|
+
* them.
|
|
223
|
+
*
|
|
224
|
+
* @param elements The slide's elements, in the order the tree gives them.
|
|
225
|
+
* @returns The same elements, each float carrying its place in that order.
|
|
226
|
+
*/
|
|
227
|
+
function inPaintOrder(elements) {
|
|
228
|
+
return elements.map((el, z) => {
|
|
229
|
+
if (el.kind === "shape") return {
|
|
230
|
+
...el,
|
|
231
|
+
shape: withZ(el.shape, z)
|
|
232
|
+
};
|
|
233
|
+
if (el.kind === "image") return {
|
|
234
|
+
...el,
|
|
235
|
+
image: withZ(el.image, z)
|
|
236
|
+
};
|
|
237
|
+
if (el.kind === "table") {
|
|
238
|
+
const anchor = el.table.properties.float;
|
|
239
|
+
return anchor ? {
|
|
240
|
+
...el,
|
|
241
|
+
table: {
|
|
242
|
+
...el.table,
|
|
243
|
+
properties: {
|
|
244
|
+
...el.table.properties,
|
|
245
|
+
float: {
|
|
246
|
+
...anchor,
|
|
247
|
+
zOrder: z
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} : el;
|
|
252
|
+
}
|
|
253
|
+
return el;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
/** The same block with its float carrying `z`, when it floats at all. */
|
|
257
|
+
function withZ(block, z) {
|
|
258
|
+
return block.float ? {
|
|
259
|
+
...block,
|
|
260
|
+
float: {
|
|
261
|
+
...block.float,
|
|
262
|
+
zOrder: z
|
|
263
|
+
}
|
|
264
|
+
} : block;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* §19.3.1.15 `p:controls` — the ActiveX controls a slide carries.
|
|
268
|
+
*
|
|
269
|
+
* They sit BESIDE the shape tree rather than in it, so a reader that walks
|
|
270
|
+
* `p:spTree` alone never sees them. Each one's `mc:Fallback` is a `p:pic` of
|
|
271
|
+
* what the control looks like — the picture PowerPoint cached precisely so that
|
|
272
|
+
* a reader which cannot run the control still draws it — and by the time the
|
|
273
|
+
* slide is parsed the alternate content is already resolved to that fallback.
|
|
274
|
+
* activex_picture.pptx is seventeen of them over an EMPTY `p:spTree`, and it
|
|
275
|
+
* rendered as a blank page.
|
|
276
|
+
*
|
|
277
|
+
* @param cSld The slide's `p:cSld`.
|
|
278
|
+
* @param ctx The slide's parsing context.
|
|
279
|
+
* @returns The controls' cached pictures as ordinary floating pictures.
|
|
280
|
+
*/
|
|
281
|
+
function parseSlideControls(cSld, ctx) {
|
|
282
|
+
const controls = cSld ? poChildren(cSld).find((c) => poIs(c, "p:controls")) : void 0;
|
|
283
|
+
if (!controls) return [];
|
|
284
|
+
const pics = poChildren(controls).flatMap((c) => poIs(c, "p:control") ? poChildren(c).filter((k) => poIs(k, "p:pic")) : []);
|
|
285
|
+
return pics.length === 0 ? [] : parseSlideShapes({ "p:spTree": pics }, ctx);
|
|
211
286
|
}
|
|
212
287
|
function partBackground(tree, root, colors, resolveImage, themeFills) {
|
|
213
288
|
const sld = tree.find((n) => poIs(n, root));
|
|
@@ -312,23 +387,28 @@ function makeSlideChartResolver(pkg, slidePath, charts, colors, resources) {
|
|
|
312
387
|
}
|
|
313
388
|
function makeSlideDiagramResolver(pkg, slidePath) {
|
|
314
389
|
const cache = /* @__PURE__ */ new Map();
|
|
315
|
-
return (relId) => {
|
|
390
|
+
return (relId, frame) => {
|
|
316
391
|
if (cache.has(relId)) return cache.get(relId);
|
|
317
|
-
let spTree;
|
|
318
392
|
const dataRel = pkg.getPartRelationships(slidePath).find((r) => r.id === relId);
|
|
319
393
|
const data = dataRel ? pkg.resolveRelatedPart(slidePath, dataRel) : void 0;
|
|
320
394
|
const draw = data ? drawingPart(pkg, slidePath, data) : void 0;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (found) {
|
|
324
|
-
spTree = found;
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
395
|
+
let spTree = draw ? cachedDiagramTree(draw.data, parseXml) : void 0;
|
|
396
|
+
if (!spTree && data) spTree = laidOutDiagram(pkg, slidePath, data, frame);
|
|
328
397
|
cache.set(relId, spTree);
|
|
329
398
|
return spTree;
|
|
330
399
|
};
|
|
331
400
|
}
|
|
401
|
+
function laidOutDiagram(pkg, slidePath, data, frame) {
|
|
402
|
+
const related = (type) => {
|
|
403
|
+
const rel = pkg.getPartRelationships(slidePath).find((r) => r.type.endsWith(type));
|
|
404
|
+
return rel ? pkg.resolveRelatedPart(slidePath, rel)?.data : void 0;
|
|
405
|
+
};
|
|
406
|
+
return laidOutDiagramTree({
|
|
407
|
+
data: data.data,
|
|
408
|
+
layout: related("/diagramLayout"),
|
|
409
|
+
colors: related("/diagramColors")
|
|
410
|
+
}, frame, parseXml);
|
|
411
|
+
}
|
|
332
412
|
/**
|
|
333
413
|
* The pre-rendered drawing a diagram's data part points at.
|
|
334
414
|
*
|
|
@@ -59,7 +59,10 @@ export interface SlideContext {
|
|
|
59
59
|
* drawing override (its `dsp:spTree`), or `undefined` when the file ships no
|
|
60
60
|
* override (E-SMARTART SA0).
|
|
61
61
|
*/
|
|
62
|
-
readonly resolveDiagram?: (relId: string
|
|
62
|
+
readonly resolveDiagram?: (relId: string, frame: {
|
|
63
|
+
readonly cx: number;
|
|
64
|
+
readonly cy: number;
|
|
65
|
+
}) => PoNode | undefined;
|
|
63
66
|
/**
|
|
64
67
|
* Sink for graceful-degradation notices (E-SMARTART SA3): a SmartArt that
|
|
65
68
|
* declares a diagram but ships no drawing override records a dropped-feature
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { emuToPt, pt } from "../core/ir/units.js";
|
|
2
2
|
import { FEATURES } from "../core/ir/features.js";
|
|
3
|
+
import { isTextWarp } from "../core/drawingml/text-warp.js";
|
|
3
4
|
import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs, poTag, poText } from "../core/po-helpers.js";
|
|
4
5
|
import { defaultColorResolver, placeholderColors, resolveColorNode } from "../core/drawingml/colors.js";
|
|
5
6
|
import { boxFromXfrm, parsePh, parseXfrmBox, rPrToRunProps } from "./sp-helpers.js";
|
|
6
7
|
import { lineSpacing, parseBullet, spacingFractions, spacingFromLineFraction } from "./placeholder-cascade.js";
|
|
7
|
-
import { colorChangeOf, parseCustGeom, parseFill, parseLine, parsePrstGeom, parseShadow, parseXfrm, statesFill, styleRefFill, styleRefFontColor, styleRefLine } from "../word/drawing-parser.js";
|
|
8
|
+
import { colorChangeOf, parseCustGeom, parseFill, parseLine, parsePrstGeom, parseShadow, parseSrcRect, parseXfrm, statesFill, styleRefFill, styleRefFontColor, styleRefLine, withStatedDirection } from "../word/drawing-parser.js";
|
|
8
9
|
import { cellStyle, lineBorder, tableStyleFlags, tableStyleId, withCellStyle, withoutFill } from "./table-style.js";
|
|
9
10
|
//#region src/pptx/slide-parser.ts
|
|
10
11
|
var CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
|
|
@@ -46,17 +47,49 @@ function parseSlideShapes(container, ctx = {}, transform = IDENTITY_TRANSFORM, s
|
|
|
46
47
|
shape
|
|
47
48
|
});
|
|
48
49
|
} else if (poIs(child, "p:pic")) {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const clipped = pictureAsShape(child);
|
|
51
|
+
const shape = clipped ? parseSp(clipped, ctx, transform) : void 0;
|
|
52
|
+
if (shape) out.push({
|
|
53
|
+
kind: "shape",
|
|
54
|
+
shape
|
|
53
55
|
});
|
|
56
|
+
else {
|
|
57
|
+
const image = parsePic(child, ctx, transform);
|
|
58
|
+
if (image) out.push({
|
|
59
|
+
kind: "image",
|
|
60
|
+
image
|
|
61
|
+
});
|
|
62
|
+
}
|
|
54
63
|
} else if (poIs(child, "p:graphicFrame")) out.push(...parseGraphicFrame(child, ctx, transform));
|
|
55
64
|
else if (poIs(child, "p:grpSp")) out.push(...parseSlideShapes(child, ctx, composeGroupTransform(child, transform), skipPlaceholders));
|
|
56
65
|
}
|
|
57
66
|
return out;
|
|
58
67
|
}
|
|
59
68
|
/**
|
|
69
|
+
* A `p:pic` that names a geometry of its own, rewritten as the `p:sp` it is.
|
|
70
|
+
*
|
|
71
|
+
* A picture holds its `p:blipFill` BESIDE `p:spPr`; a shape holds its fill
|
|
72
|
+
* INSIDE it, under the drawing namespace. Moving the one into the other is the
|
|
73
|
+
* whole difference, and it buys the shape path entire — the geometry, the
|
|
74
|
+
* outline, the crop, the recolour — instead of a second clipper that would
|
|
75
|
+
* drift from it.
|
|
76
|
+
*
|
|
77
|
+
* @param pic The `p:pic` node.
|
|
78
|
+
* @returns The equivalent `p:sp`, or undefined when the picture is a plain
|
|
79
|
+
* rectangle and wants no clipping at all.
|
|
80
|
+
*/
|
|
81
|
+
function pictureAsShape(pic) {
|
|
82
|
+
const spPr = poChildren(pic).find((c) => poIs(c, "p:spPr"));
|
|
83
|
+
const prst = spPr ? poChildren(spPr).find((c) => poIs(c, "a:prstGeom")) : void 0;
|
|
84
|
+
const custom = spPr ? poChildren(spPr).find((c) => poIs(c, "a:custGeom")) : void 0;
|
|
85
|
+
const shape = poAttr(prst, "prst");
|
|
86
|
+
if (custom === void 0 && (shape === void 0 || shape === "rect")) return void 0;
|
|
87
|
+
const blipFill = poChildren(pic).find((c) => poIs(c, "p:blipFill"));
|
|
88
|
+
if (!blipFill || !spPr) return void 0;
|
|
89
|
+
const nv = poChildren(pic).find((c) => poIs(c, "p:nvPicPr"));
|
|
90
|
+
return { "p:sp": [...nv ? [{ "p:nvSpPr": poChildren(nv) }] : [], { "p:spPr": [{ "a:blipFill": poChildren(blipFill) }, ...poChildren(spPr)] }] };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
60
93
|
* Whether a shape is a placeholder — `p:ph` in its OWN non-visual properties.
|
|
61
94
|
* Read as "anywhere below", a group holding one would take the whole group
|
|
62
95
|
* with it.
|
|
@@ -132,7 +165,7 @@ function parseSp(sp, ctx, transform) {
|
|
|
132
165
|
const ownFill = stated(statesFill);
|
|
133
166
|
const styleFill = style ? styleRefFill(style, colors, themeStyles) : void 0;
|
|
134
167
|
const lentFill = lent(statesFill);
|
|
135
|
-
const styled = useBgFill ? backgroundThrough(ctx.backgroundFill, box, ctx.slideSize) : ownFill ? parseFill(ownFill, colors, ctx.resolveImage) : styleFill && styleFill.kind !== "none" ? styleFill : lentFill ? parseFill(lentFill, colors, ctx.resolveImage) : spPr ? parseFill(spPr, colors, ctx.resolveImage) : { kind: "none" };
|
|
168
|
+
const styled = withStatedDirection(useBgFill ? backgroundThrough(ctx.backgroundFill, box, ctx.slideSize) : ownFill ? parseFill(ownFill, colors, ctx.resolveImage) : styleFill && styleFill.kind !== "none" ? styleFill : lentFill ? parseFill(lentFill, colors, ctx.resolveImage) : spPr ? parseFill(spPr, colors, ctx.resolveImage) : { kind: "none" }, spPr);
|
|
136
169
|
const lineFrom = from((n) => poChildren(n).some((c) => poIs(c, "a:ln")));
|
|
137
170
|
let line = lineFrom ? parseLine(lineFrom, colors) : void 0;
|
|
138
171
|
if (style) {
|
|
@@ -236,7 +269,10 @@ function parseGraphicFrame(gf, ctx, transform) {
|
|
|
236
269
|
if (uri === DIAGRAM_URI) {
|
|
237
270
|
const relIds = poFindDescendant(gf, "dgm:relIds");
|
|
238
271
|
const dmRelId = relIds ? poAttr(relIds, "dm") : void 0;
|
|
239
|
-
const spTree = dmRelId !== void 0 ? ctx.resolveDiagram?.(dmRelId
|
|
272
|
+
const spTree = dmRelId !== void 0 ? ctx.resolveDiagram?.(dmRelId, {
|
|
273
|
+
cx: box.cx,
|
|
274
|
+
cy: box.cy
|
|
275
|
+
}) : void 0;
|
|
240
276
|
if (!spTree) {
|
|
241
277
|
if (dmRelId !== void 0) ctx.onLoss?.(noDiagramOverrideLoss());
|
|
242
278
|
return [];
|
|
@@ -551,7 +587,10 @@ function parseGeometry(spPr) {
|
|
|
551
587
|
return RECT_GEOMETRY;
|
|
552
588
|
}
|
|
553
589
|
function parsePic(pic, ctx, transform) {
|
|
554
|
-
const
|
|
590
|
+
const spPr = poChildren(pic).find((c) => poIs(c, "p:spPr"));
|
|
591
|
+
const ph = parsePh(pic);
|
|
592
|
+
let own = parseXfrmBox(spPr);
|
|
593
|
+
if (!own && ph && ctx.cascade) own = ctx.cascade.geometryFor(ph);
|
|
555
594
|
if (!own) return void 0;
|
|
556
595
|
const box = transform(own);
|
|
557
596
|
const blipFill = poChildren(pic).find((c) => poIs(c, "p:blipFill"));
|
|
@@ -562,12 +601,19 @@ function parsePic(pic, ctx, transform) {
|
|
|
562
601
|
const fixed = blip ? poChildren(blip).find((c) => poIs(c, "a:alphaModFix")) : void 0;
|
|
563
602
|
const amt = fixed ? poIntAttr(fixed, "amt") : void 0;
|
|
564
603
|
const alpha = amt === void 0 ? void 0 : Math.min(1, Math.max(0, amt / 1e5));
|
|
604
|
+
const crop = parseSrcRect(blipFill ? poFindDescendant(blipFill, "a:srcRect") : void 0);
|
|
605
|
+
const xfrm = spPr ? poChildren(spPr).find((c) => poIs(c, "a:xfrm")) : void 0;
|
|
606
|
+
const rot = xfrm ? poIntAttr(xfrm, "rot") : void 0;
|
|
565
607
|
const altText = picAltText(pic);
|
|
566
608
|
return {
|
|
567
609
|
float: floatAt(box),
|
|
568
610
|
...resource !== void 0 ? { resource } : {},
|
|
569
611
|
...colorChange ? { colorChange } : {},
|
|
570
612
|
...alpha !== void 0 && alpha < 1 ? { alpha } : {},
|
|
613
|
+
...crop ? { crop } : {},
|
|
614
|
+
...rot !== void 0 && rot !== 0 ? { rotation60k: rot } : {},
|
|
615
|
+
...poAttr(xfrm, "flipH") === "1" ? { flipH: true } : {},
|
|
616
|
+
...poAttr(xfrm, "flipV") === "1" ? { flipV: true } : {},
|
|
571
617
|
width: emuToPt(box.cx),
|
|
572
618
|
height: emuToPt(box.cy),
|
|
573
619
|
paragraphProperties: {},
|
|
@@ -616,6 +662,12 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor, theme
|
|
|
616
662
|
const rIns = bodyPr ? poIntAttr(bodyPr, "rIns") : void 0;
|
|
617
663
|
const bIns = bodyPr ? poIntAttr(bodyPr, "bIns") : void 0;
|
|
618
664
|
const a = bodyPr ? poAttr(bodyPr, "anchor") : void 0;
|
|
665
|
+
const autofit = bodyPr ? poChildren(bodyPr).find((c) => poIs(c, "a:normAutofit")) : void 0;
|
|
666
|
+
const shrink = autofit !== void 0 && poIntAttr(autofit, "fontScale") === void 0;
|
|
667
|
+
const warp = bodyPr ? textWarp(bodyPr) : void 0;
|
|
668
|
+
const v = bodyPr ? poAttr(bodyPr, "vert") : void 0;
|
|
669
|
+
const vertical = v === "vert270" ? "vert270" : v !== void 0 && v !== "horz" ? "vert" : void 0;
|
|
670
|
+
const upright = bodyPr ? poAttr(bodyPr, "upright") === "1" : false;
|
|
619
671
|
const anchor = a === "ctr" || a === "b" || a === "t" ? a : ph && cascade ? cascade.anchorFor(ph) : void 0;
|
|
620
672
|
return {
|
|
621
673
|
content: fitted,
|
|
@@ -623,7 +675,33 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor, theme
|
|
|
623
675
|
...tIns !== void 0 ? { insetTop: emuToPt(tIns) } : {},
|
|
624
676
|
...rIns !== void 0 ? { insetRight: emuToPt(rIns) } : {},
|
|
625
677
|
...bIns !== void 0 ? { insetBottom: emuToPt(bIns) } : {},
|
|
626
|
-
...anchor ? { anchor } : {}
|
|
678
|
+
...anchor ? { anchor } : {},
|
|
679
|
+
...vertical ? { vertical } : {},
|
|
680
|
+
...upright ? { upright } : {},
|
|
681
|
+
...shrink ? { shrinkToFit: true } : {},
|
|
682
|
+
...warp ? { warp } : {}
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* §20.1.9.10 `a:prstTxWarp` — the WordArt curve a body's text is bent through,
|
|
687
|
+
* with the `a:avLst` `adj` guide when it states one. Unread, tdf114848's eight
|
|
688
|
+
* pieces of WordArt were set as eight ordinary paragraphs, each wrapped onto
|
|
689
|
+
* three lines of upright type where both references draw one bent line.
|
|
690
|
+
*
|
|
691
|
+
* @param bodyPr The body's `a:bodyPr`.
|
|
692
|
+
* @returns The preset and its adjustment, or `undefined` when the body states
|
|
693
|
+
* no warp or states the enumeration's `textNoShape`.
|
|
694
|
+
*/
|
|
695
|
+
function textWarp(bodyPr) {
|
|
696
|
+
const node = poChildren(bodyPr).find((c) => poIs(c, "a:prstTxWarp"));
|
|
697
|
+
const preset = node ? poAttr(node, "prst") : void 0;
|
|
698
|
+
if (node === void 0 || preset === void 0 || !isTextWarp(preset)) return void 0;
|
|
699
|
+
const avLst = poChildren(node).find((c) => poIs(c, "a:avLst"));
|
|
700
|
+
const adj = avLst ? poChildren(avLst).find((c) => poIs(c, "a:gd") && poAttr(c, "name") === "adj") : void 0;
|
|
701
|
+
const value = adj ? /^val\s+(-?\d+)$/u.exec(poAttr(adj, "fmla") ?? "")?.[1] : void 0;
|
|
702
|
+
return {
|
|
703
|
+
preset,
|
|
704
|
+
...value !== void 0 ? { adjust: Number(value) } : {}
|
|
627
705
|
};
|
|
628
706
|
}
|
|
629
707
|
/**
|
|
@@ -683,9 +761,19 @@ function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters, sty
|
|
|
683
761
|
const algn = pPr ? poAttr(pPr, "algn") : void 0;
|
|
684
762
|
const alignment = algn !== void 0 ? ALGN_TO_ALIGNMENT[algn] : void 0;
|
|
685
763
|
const runs = [];
|
|
686
|
-
for (const child of poChildren(aP))
|
|
687
|
-
|
|
688
|
-
|
|
764
|
+
for (const child of poChildren(aP)) {
|
|
765
|
+
if (poIs(child, "a:br")) {
|
|
766
|
+
const last = runs[runs.length - 1];
|
|
767
|
+
if (last) runs[runs.length - 1] = {
|
|
768
|
+
...last,
|
|
769
|
+
text: `${last.text}\n`
|
|
770
|
+
};
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
if (poIs(child, "a:r") || poIs(child, "a:fld")) {
|
|
774
|
+
const run = parseSlideRun(child, defaults, colors, resolveLink, themeFonts);
|
|
775
|
+
if (run) runs.push(run);
|
|
776
|
+
}
|
|
689
777
|
}
|
|
690
778
|
const marL = pPr ? poIntAttr(pPr, "marL") : void 0;
|
|
691
779
|
const indent = pPr ? poIntAttr(pPr, "indent") : void 0;
|
|
@@ -840,12 +928,15 @@ function parseTableCell(tc, colors) {
|
|
|
840
928
|
const tcPr = poChildren(tc).find((c) => poIs(c, "a:tcPr"));
|
|
841
929
|
const shadingHex = tcPr ? cellFillHex(tcPr, colors) : void 0;
|
|
842
930
|
const borders = tcPr ? cellOwnBorders(tcPr, colors) : void 0;
|
|
931
|
+
const vert = tcPr ? poAttr(tcPr, "vert") : void 0;
|
|
932
|
+
const textDirection = vert === "vert" || vert === "eaVert" || vert === "mongolianVert" ? "vert" : vert === "vert270" ? "vert270" : void 0;
|
|
843
933
|
return {
|
|
844
934
|
properties: {
|
|
845
935
|
...gridSpan !== void 0 && gridSpan > 1 ? { colSpan: gridSpan } : {},
|
|
846
936
|
...merge ? { merge } : {},
|
|
847
937
|
...shadingHex ? { shading: { colorHex: shadingHex } } : {},
|
|
848
|
-
...borders ? { borders } : {}
|
|
938
|
+
...borders ? { borders } : {},
|
|
939
|
+
...textDirection ? { textDirection } : {}
|
|
849
940
|
},
|
|
850
941
|
content
|
|
851
942
|
};
|
|
@@ -19,9 +19,13 @@ export interface ShapeBoxEmu {
|
|
|
19
19
|
readonly cy: number;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* `p:
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* `p:nvPr/p:ph` → the placeholder reference, or `undefined` for an ordinary
|
|
23
|
+
* (non-placeholder) shape. A bare `<p:ph/>` returns an empty ref (still a
|
|
24
|
+
* placeholder: `type` defaults to `'obj'`).
|
|
25
|
+
*
|
|
26
|
+
* A PICTURE is a placeholder as readily as a shape is — a content placeholder
|
|
27
|
+
* filled with a photograph writes `p:nvPicPr/p:nvPr/p:ph` and an EMPTY `p:spPr`,
|
|
28
|
+
* leaving its whole geometry to the layout (customshape-bitmapfill-srcrect).
|
|
25
29
|
*/
|
|
26
30
|
export declare function parsePh(sp: PoNode): PlaceholderRef | undefined;
|
|
27
31
|
/**
|
|
@@ -4,14 +4,24 @@ import { resolveColorNode } from "../core/drawingml/colors.js";
|
|
|
4
4
|
import { resolveThemeFont } from "../core/drawingml/theme-parser.js";
|
|
5
5
|
//#region src/pptx/sp-helpers.ts
|
|
6
6
|
var isTrue = (v) => v === "1" || v === "true" || v === "on";
|
|
7
|
+
var NON_VISUAL = [
|
|
8
|
+
"p:nvSpPr",
|
|
9
|
+
"p:nvPicPr",
|
|
10
|
+
"p:nvGraphicFramePr",
|
|
11
|
+
"p:nvCxnSpPr"
|
|
12
|
+
];
|
|
7
13
|
/**
|
|
8
|
-
* `p:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
14
|
+
* `p:nvPr/p:ph` → the placeholder reference, or `undefined` for an ordinary
|
|
15
|
+
* (non-placeholder) shape. A bare `<p:ph/>` returns an empty ref (still a
|
|
16
|
+
* placeholder: `type` defaults to `'obj'`).
|
|
17
|
+
*
|
|
18
|
+
* A PICTURE is a placeholder as readily as a shape is — a content placeholder
|
|
19
|
+
* filled with a photograph writes `p:nvPicPr/p:nvPr/p:ph` and an EMPTY `p:spPr`,
|
|
20
|
+
* leaving its whole geometry to the layout (customshape-bitmapfill-srcrect).
|
|
11
21
|
*/
|
|
12
22
|
function parsePh(sp) {
|
|
13
|
-
const
|
|
14
|
-
const nvPr =
|
|
23
|
+
const nonVisual = poChildren(sp).find((c) => NON_VISUAL.some((n) => poIs(c, n)));
|
|
24
|
+
const nvPr = nonVisual ? poChildren(nonVisual).find((c) => poIs(c, "p:nvPr")) : void 0;
|
|
15
25
|
const ph = nvPr ? poChildren(nvPr).find((c) => poIs(c, "p:ph")) : void 0;
|
|
16
26
|
if (!ph) return void 0;
|
|
17
27
|
const type = poAttr(ph, "type");
|
|
@@ -88,8 +98,36 @@ function capsOf(cap) {
|
|
|
88
98
|
}
|
|
89
99
|
function solidFillColor(rPr, colors) {
|
|
90
100
|
const solidFill = poChildren(rPr).find((c) => poIs(c, "a:solidFill"));
|
|
91
|
-
if (
|
|
92
|
-
|
|
101
|
+
if (solidFill) {
|
|
102
|
+
for (const c of poChildren(solidFill)) {
|
|
103
|
+
const hex = resolveColorNode(c, colors);
|
|
104
|
+
if (hex) return hex;
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
return gradientFillColor(rPr, colors);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* §20.1.8.33 — a run may be filled with a GRADIENT, and WordArt always is: the
|
|
112
|
+
* text of tdf114848's second page runs through five stops of accent1. A run
|
|
113
|
+
* here wears one colour, so the gradient gives up the stop nearest its middle —
|
|
114
|
+
* the one most of the glyph is painted in. Unread, the run had no colour at all
|
|
115
|
+
* and every word came out in the default black.
|
|
116
|
+
*/
|
|
117
|
+
function gradientFillColor(rPr, colors) {
|
|
118
|
+
const grad = poChildren(rPr).find((c) => poIs(c, "a:gradFill"));
|
|
119
|
+
const list = grad ? poChildren(grad).find((c) => poIs(c, "a:gsLst")) : void 0;
|
|
120
|
+
const stops = list ? poChildren(list).filter((c) => poIs(c, "a:gs")) : [];
|
|
121
|
+
let best;
|
|
122
|
+
for (const gs of stops) {
|
|
123
|
+
const at = Math.abs((poIntAttr(gs, "pos") ?? 0) - 5e4);
|
|
124
|
+
if (!best || at < best.at) best = {
|
|
125
|
+
at,
|
|
126
|
+
node: gs
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (!best) return void 0;
|
|
130
|
+
for (const c of poChildren(best.node)) {
|
|
93
131
|
const hex = resolveColorNode(c, colors);
|
|
94
132
|
if (hex) return hex;
|
|
95
133
|
}
|
|
@@ -13,6 +13,13 @@ export interface TableStyleFlags {
|
|
|
13
13
|
/** What one part of a table style says about a cell. */
|
|
14
14
|
export interface TableStylePart {
|
|
15
15
|
readonly shadingHex?: string;
|
|
16
|
+
/**
|
|
17
|
+
* §20.1.2.3.1 — how opaque that shading is, when the part asks for less than
|
|
18
|
+
* all of it. A cell's fill is a layer over the table's background, not over
|
|
19
|
+
* the page, so the two have to be composed rather than each flattened to
|
|
20
|
+
* white on its own.
|
|
21
|
+
*/
|
|
22
|
+
readonly shadingAlpha?: number;
|
|
16
23
|
readonly borders?: CellBorders;
|
|
17
24
|
readonly bold?: boolean;
|
|
18
25
|
readonly italic?: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pt } from "../core/ir/units.js";
|
|
2
2
|
import { poAttr, poChildren, poIntAttr, poIs, poTag, poText } from "../core/po-helpers.js";
|
|
3
|
-
import { readColorMods, resolveColorNode } from "../core/drawingml/colors.js";
|
|
3
|
+
import { placeholderColors, readColorMods, resolveColorNode } from "../core/drawingml/colors.js";
|
|
4
4
|
//#region src/pptx/table-style.ts
|
|
5
5
|
/** The `a:tblPr` flags, all off unless the table says otherwise. */
|
|
6
6
|
function tableStyleFlags(tblPr) {
|
|
@@ -40,12 +40,57 @@ function cellStyle(style, flags, at, colors, theme) {
|
|
|
40
40
|
let out = tableBackground(style, colors, theme);
|
|
41
41
|
for (const name of names) {
|
|
42
42
|
const part = poChildren(style).find((c) => poIs(c, name));
|
|
43
|
-
if (part)
|
|
43
|
+
if (!part) continue;
|
|
44
|
+
const next = partStyle(part, colors, theme);
|
|
45
|
+
out = {
|
|
44
46
|
...out,
|
|
45
|
-
...
|
|
47
|
+
...next,
|
|
48
|
+
...overFill(out.shadingHex, next)
|
|
46
49
|
};
|
|
47
50
|
}
|
|
48
|
-
|
|
51
|
+
const { shadingAlpha: _drop, ...flat } = out;
|
|
52
|
+
return flat;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A part's fill laid OVER what is already under it.
|
|
56
|
+
*
|
|
57
|
+
* A colour resolves flattened against the page, because that is what a shape's
|
|
58
|
+
* fill sits on; a table cell's sits on the table's background. Undoing the one
|
|
59
|
+
* and redoing the other needs only the alpha: bnc480256's banding is `accent1`
|
|
60
|
+
* at 40% over a background the theme's gradient makes pale, and taken against
|
|
61
|
+
* white instead it came out as the flat accent with every second row white.
|
|
62
|
+
*/
|
|
63
|
+
function overFill(under, part) {
|
|
64
|
+
const a = part.shadingAlpha;
|
|
65
|
+
if (a === void 0 || a >= 1 || part.shadingHex === void 0 || under === void 0) return {};
|
|
66
|
+
const flat = rgb(part.shadingHex);
|
|
67
|
+
const back = rgb(under);
|
|
68
|
+
if (!flat || !back) return {};
|
|
69
|
+
return { shadingHex: toHex(flat.map((v, i) => v - (1 - a) * (1 - (back[i] ?? 1)))) };
|
|
70
|
+
}
|
|
71
|
+
function alphaOf(fill) {
|
|
72
|
+
const walk = (node) => {
|
|
73
|
+
for (const child of poChildren(node)) {
|
|
74
|
+
if (poIs(child, "a:alpha")) {
|
|
75
|
+
const v = poIntAttr(child, "val");
|
|
76
|
+
if (v !== void 0) return Math.max(0, Math.min(1, v / 1e5));
|
|
77
|
+
}
|
|
78
|
+
const deeper = walk(child);
|
|
79
|
+
if (deeper !== void 0) return deeper;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
return walk(fill) ?? 1;
|
|
83
|
+
}
|
|
84
|
+
function rgb(h) {
|
|
85
|
+
const m = /^([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/u.exec(h);
|
|
86
|
+
return m ? [
|
|
87
|
+
1,
|
|
88
|
+
2,
|
|
89
|
+
3
|
|
90
|
+
].map((i) => parseInt(m[i] ?? "0", 16) / 255) : void 0;
|
|
91
|
+
}
|
|
92
|
+
function toHex(v) {
|
|
93
|
+
return v.map((c) => Math.round(Math.max(0, Math.min(1, c)) * 255).toString(16).padStart(2, "0").toUpperCase()).join("");
|
|
49
94
|
}
|
|
50
95
|
function tableBackground(style, colors, theme) {
|
|
51
96
|
const bg = poChildren(style).find((c) => poIs(c, "a:tblBg"));
|
|
@@ -68,9 +113,14 @@ function refFillColor(ref, colors, theme) {
|
|
|
68
113
|
const idx = poIntAttr(ref, "idx");
|
|
69
114
|
const slot = idx !== void 0 && idx > 0 ? theme?.fills?.[idx - 1] : void 0;
|
|
70
115
|
if (!slot) return own;
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
116
|
+
const named = own === void 0 ? colors : placeholderColors(colors, own);
|
|
117
|
+
const solid = poIs(slot, "a:solidFill") ? slot : void 0;
|
|
118
|
+
if (solid) return colorOf(solid, named) ?? own;
|
|
119
|
+
const grad = poIs(slot, "a:gradFill") ? slot : void 0;
|
|
120
|
+
const list = grad ? poChildren(grad).find((c) => poIs(c, "a:gsLst")) : void 0;
|
|
121
|
+
const stops = list ? poChildren(list).filter((c) => poIs(c, "a:gs")) : [];
|
|
122
|
+
const last = stops[stops.length - 1];
|
|
123
|
+
return (last ? colorOf(last, named) : void 0) ?? own;
|
|
74
124
|
}
|
|
75
125
|
function bandName(index, edge, axis) {
|
|
76
126
|
return (edge ? index - 1 : index) % 2 === 0 ? `a:band1${axis}` : `a:band2${axis}`;
|
|
@@ -81,12 +131,14 @@ function partStyle(part, colors, theme) {
|
|
|
81
131
|
const fill = tcStyle ? poChildren(tcStyle).find((c) => poIs(c, "a:fill")) : void 0;
|
|
82
132
|
const solid = fill ? poChildren(fill).find((c) => poIs(c, "a:solidFill")) : void 0;
|
|
83
133
|
const shadingHex = solid ? colorOf(solid, colors) : void 0;
|
|
134
|
+
const shadingAlpha = solid ? alphaOf(solid) : void 0;
|
|
84
135
|
const bdr = tcStyle ? poChildren(tcStyle).find((c) => poIs(c, "a:tcBdr")) : void 0;
|
|
85
136
|
const borders = bdr ? partBorders(bdr, colors, theme) : void 0;
|
|
86
137
|
const on = (name) => poAttr(txStyle, name) === "on";
|
|
87
138
|
const colorHex = txStyle ? colorOf(txStyle, colors) : void 0;
|
|
88
139
|
return {
|
|
89
140
|
...shadingHex ? { shadingHex } : {},
|
|
141
|
+
...shadingAlpha !== void 0 && shadingAlpha < 1 ? { shadingAlpha } : {},
|
|
90
142
|
...borders ? { borders } : {},
|
|
91
143
|
...txStyle && on("b") ? { bold: true } : {},
|
|
92
144
|
...txStyle && on("i") ? { italic: true } : {},
|
|
@@ -88,6 +88,7 @@ function emitPage(out, page, laid, losses, idc) {
|
|
|
88
88
|
}
|
|
89
89
|
for (const sh of plan.shapes) emitShape(out, sh.shape, idc);
|
|
90
90
|
for (const picture of plan.pictures) for (const item of picture) emitPageItem(out, item, laid, losses, idc);
|
|
91
|
+
for (const run of plan.ordered) for (const item of run) emitPageItem(out, item, laid, losses, idc);
|
|
91
92
|
for (const t of plan.lines) emitTextLine(out, t, losses, idc);
|
|
92
93
|
}
|
|
93
94
|
/**
|
|
@@ -39,7 +39,10 @@ export interface ParseContext {
|
|
|
39
39
|
* pre-rendered drawing override, or `undefined` when the file ships none
|
|
40
40
|
* (E-SMARTART SA2).
|
|
41
41
|
*/
|
|
42
|
-
readonly resolveDiagram?: (relId: string
|
|
42
|
+
readonly resolveDiagram?: (relId: string, frame: {
|
|
43
|
+
readonly cx: number;
|
|
44
|
+
readonly cy: number;
|
|
45
|
+
}) => ResolvedDiagram | undefined;
|
|
43
46
|
/**
|
|
44
47
|
* §21.2 a `c:chart` `@r:id` → the chart part's path, the key the reader files
|
|
45
48
|
* parsed charts under. Relationship ids are scoped to their owning part, so a
|
|
@@ -484,7 +484,10 @@ function blocksForDrawing(content, paragraphProperties, ctx) {
|
|
|
484
484
|
}
|
|
485
485
|
}];
|
|
486
486
|
if (content.kind === "diagram") {
|
|
487
|
-
const diagram = ctx.resolveDiagram?.(content.dmRelId
|
|
487
|
+
const diagram = ctx.resolveDiagram?.(content.dmRelId, {
|
|
488
|
+
cx: content.widthEmu,
|
|
489
|
+
cy: content.heightEmu
|
|
490
|
+
});
|
|
488
491
|
if (!diagram) {
|
|
489
492
|
ctx.onLoss?.(noDiagramOverrideLoss());
|
|
490
493
|
return null;
|
|
@@ -5,7 +5,7 @@ import { resolveTableStyles } from "../core/style-cascade/table.js";
|
|
|
5
5
|
import "../core/style-cascade/index.js";
|
|
6
6
|
import { applyNumbering, applyNumberingToHeadersFooters } from "../core/numbering/apply.js";
|
|
7
7
|
import "../core/numbering/index.js";
|
|
8
|
-
import {
|
|
8
|
+
import { cachedDiagramTree, laidOutDiagramTree } from "../core/drawingml/diagram/run.js";
|
|
9
9
|
import { packageHasPart } from "../core/bytes.js";
|
|
10
10
|
import { DEFAULT_THEME_PALETTE, makeColorResolver } from "../core/drawingml/colors.js";
|
|
11
11
|
import { parseChart, withChartColorStyle } from "../core/drawingml/chart-parser.js";
|
|
@@ -185,29 +185,42 @@ function infoFromCore(core) {
|
|
|
185
185
|
}
|
|
186
186
|
function makeDiagramResolver(pkg, partName, store) {
|
|
187
187
|
const cache = /* @__PURE__ */ new Map();
|
|
188
|
-
return (relId) => {
|
|
189
|
-
|
|
188
|
+
return (relId, frame) => {
|
|
189
|
+
const key = `${relId}|${frame.cx}x${frame.cy}`;
|
|
190
|
+
if (cache.has(key)) return cache.get(key);
|
|
190
191
|
let resolved;
|
|
191
192
|
const dataRel = pkg.getPartRelationships(partName).find((r) => r.id === relId);
|
|
192
193
|
const data = dataRel ? pkg.resolveRelatedPart(partName, dataRel) : void 0;
|
|
193
194
|
if (data) {
|
|
194
195
|
const own = pkg.getPartRelationships(data.path).find((r) => r.type.endsWith("/diagramDrawing"));
|
|
195
196
|
const draw = own ? pkg.resolveRelatedPart(data.path, own) : drawingFromOwner(pkg, partName, data.path);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
197
|
+
const cached = draw ? cachedDiagramTree(draw.data, parseXml) : void 0;
|
|
198
|
+
if (cached && draw) resolved = {
|
|
199
|
+
spTree: cached,
|
|
200
|
+
resolveImage: makeImageResolver(pkg, store, draw.path)
|
|
201
|
+
};
|
|
202
|
+
else {
|
|
203
|
+
const spTree = laidOutDiagramTree({
|
|
204
|
+
data: data.data,
|
|
205
|
+
layout: siblingPart(pkg, partName, data.path, "/diagramLayout"),
|
|
206
|
+
colors: siblingPart(pkg, partName, data.path, "/diagramColors")
|
|
207
|
+
}, frame, parseXml);
|
|
208
|
+
if (spTree) resolved = { spTree };
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
|
-
cache.set(
|
|
211
|
+
cache.set(key, resolved);
|
|
208
212
|
return resolved;
|
|
209
213
|
};
|
|
210
214
|
}
|
|
215
|
+
function siblingPart(pkg, ownerPart, dataPart, type) {
|
|
216
|
+
const own = pkg.getPartRelationships(dataPart).find((r) => r.type.endsWith(type));
|
|
217
|
+
if (own) return pkg.resolveRelatedPart(dataPart, own)?.data;
|
|
218
|
+
const index = (path) => /(\d*)\.[^.]+$/u.exec(path)?.[1] ?? "";
|
|
219
|
+
const want = index(dataPart);
|
|
220
|
+
const rels = pkg.getPartRelationships(ownerPart).filter((r) => r.type.endsWith(type));
|
|
221
|
+
const rel = rels.find((r) => index(r.target) === want) ?? (rels.length === 1 ? rels[0] : void 0);
|
|
222
|
+
return rel ? pkg.resolveRelatedPart(ownerPart, rel)?.data : void 0;
|
|
223
|
+
}
|
|
211
224
|
function drawingFromOwner(pkg, ownerPart, dataPart) {
|
|
212
225
|
const drawings = pkg.getPartRelationships(ownerPart).filter((r) => r.type.endsWith("/diagramDrawing"));
|
|
213
226
|
if (drawings.length === 0) return void 0;
|