reamkit 1.16.0 → 1.17.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/dist/esm/core/bidi/segments.js +1 -2
- package/dist/esm/core/converter/project.js +5 -1
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +473 -7
- package/dist/esm/core/drawingml/chart-geometry.d.ts +8 -12
- package/dist/esm/core/drawingml/chart-geometry.js +58 -9
- package/dist/esm/core/drawingml/chart-parser.js +44 -5
- package/dist/esm/core/drawingml/colors.d.ts +1 -1
- package/dist/esm/core/drawingml/colors.js +27 -1
- package/dist/esm/core/drawingml/preset-geometry.js +233 -0
- package/dist/esm/core/drawingml/shape-render.d.ts +12 -0
- package/dist/esm/core/drawingml/shape-render.js +116 -3
- package/dist/esm/core/drawingml/theme-parser.d.ts +10 -0
- package/dist/esm/core/drawingml/theme-parser.js +19 -1
- package/dist/esm/core/font/measure.d.ts +5 -0
- package/dist/esm/core/font/measure.js +21 -1
- package/dist/esm/core/images.d.ts +2 -2
- package/dist/esm/core/images.js +181 -0
- package/dist/esm/core/ir/flow.d.ts +23 -1
- package/dist/esm/core/numbering/apply.d.ts +5 -3
- package/dist/esm/core/numbering/apply.js +42 -11
- package/dist/esm/core/numbering/index.js +2 -0
- package/dist/esm/core/numbering/state.d.ts +13 -1
- package/dist/esm/core/numbering/state.js +256 -15
- package/dist/esm/core/po-helpers.js +16 -1
- package/dist/esm/core/style-cascade/resolver.js +66 -11
- package/dist/esm/core/style-cascade/table.js +35 -11
- package/dist/esm/core/style-cascade/types.d.ts +42 -1
- package/dist/esm/core/style-cascade/types.js +4 -0
- package/dist/esm/core/vector.d.ts +17 -0
- package/dist/esm/excel/print-model.js +1 -1
- package/dist/esm/excel/sheet-to-flow.js +10 -8
- package/dist/esm/excel/worksheet-parser.js +1 -1
- package/dist/esm/html/html-writer.js +18 -4
- package/dist/esm/layout/page-doc.d.ts +62 -2
- package/dist/esm/layout/styled-layout.d.ts +44 -2
- package/dist/esm/layout/styled-layout.js +1870 -228
- package/dist/esm/pdf/shading.js +76 -6
- package/dist/esm/pdf/styled-page-emitter.js +217 -43
- package/dist/esm/pdf/vector-graphics.d.ts +28 -1
- package/dist/esm/pdf/vector-graphics.js +94 -11
- package/dist/esm/pptx/pptx-reader.js +1 -0
- package/dist/esm/pptx/slide-parser.d.ts +21 -4
- package/dist/esm/pptx/slide-parser.js +86 -23
- package/dist/esm/svg/svg-writer.js +1 -1
- package/dist/esm/word/document-parser.d.ts +96 -7
- package/dist/esm/word/document-parser.js +537 -116
- package/dist/esm/word/docx-reader.js +135 -43
- package/dist/esm/word/docx-writer.js +6 -1
- package/dist/esm/word/drawing-parser.d.ts +53 -5
- package/dist/esm/word/drawing-parser.js +1540 -54
- package/dist/esm/word/index.d.ts +4 -4
- package/dist/esm/word/numbering-parser.d.ts +2 -1
- package/dist/esm/word/numbering-parser.js +107 -21
- package/dist/esm/word/paragraph-properties.d.ts +11 -1
- package/dist/esm/word/paragraph-properties.js +219 -10
- package/dist/esm/word/run-properties.js +45 -1
- package/dist/esm/word/settings-parser.d.ts +24 -0
- package/dist/esm/word/settings-parser.js +31 -5
- package/dist/esm/word/shading.d.ts +11 -0
- package/dist/esm/word/shading.js +64 -0
- package/dist/esm/word/styles-parser.js +8 -2
- package/dist/esm/word/table-parser.d.ts +9 -1
- package/dist/esm/word/table-parser.js +182 -30
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Chart, ChartSeries } from '../document-model/index.js';
|
|
1
|
+
import { Chart, ChartSeries, ShapeDash } from '../document-model/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* An axis-aligned rectangle in the scene's local y-up frame: bars, scatter
|
|
4
4
|
* point markers, legend swatches. Position is the bottom-left corner.
|
|
@@ -11,6 +11,8 @@ export interface ChartRect {
|
|
|
11
11
|
readonly fillHex?: string;
|
|
12
12
|
readonly strokeHex?: string;
|
|
13
13
|
readonly strokeWidthPt?: number;
|
|
14
|
+
/** §20.1.10.49 — the outline's preset dash, when it names one. */
|
|
15
|
+
readonly strokeDash?: ShapeDash;
|
|
14
16
|
}
|
|
15
17
|
/** An open stroked polyline: line-chart series, gridlines and axis lines. */
|
|
16
18
|
export interface ChartPolyline {
|
|
@@ -73,6 +75,11 @@ export interface ChartScene {
|
|
|
73
75
|
readonly polygons?: ReadonlyArray<ChartPolygon>;
|
|
74
76
|
/** §21.2.2.198 chart-space fill + outline: drawn under everything else. */
|
|
75
77
|
readonly background?: ChartRect;
|
|
78
|
+
/**
|
|
79
|
+
* §21.2.2.145 the PLOT rectangle's own fill + outline, drawn over the chart
|
|
80
|
+
* frame and under the gridlines.
|
|
81
|
+
*/
|
|
82
|
+
readonly plotBackground?: ChartRect;
|
|
76
83
|
/**
|
|
77
84
|
* Major gridlines, drawn UNDER the plotted data. Kept apart from the other
|
|
78
85
|
* polylines because z-order is the whole point: gridlines over the bars strip
|
|
@@ -131,17 +138,6 @@ export declare function niceScale(dataMin: number, dataMax: number, maxTicks?: n
|
|
|
131
138
|
* @returns The label text.
|
|
132
139
|
*/
|
|
133
140
|
export declare function formatTick(v: number, step: number): string;
|
|
134
|
-
/**
|
|
135
|
-
* Lay out a bar/column {@link Chart} into a {@link ChartScene}. Honours
|
|
136
|
-
* `chart.grouping` (clustered / stacked / percentStacked) and `chart.barDir`
|
|
137
|
-
* (column vs horizontal bar), over the shared cartesian frame.
|
|
138
|
-
*
|
|
139
|
-
* @param chart The bar/column chart.
|
|
140
|
-
* @param wPt Frame width in points.
|
|
141
|
-
* @param hPt Frame height in points.
|
|
142
|
-
* @param measure Text measurer used to size labels and reserve axis gutters.
|
|
143
|
-
* @returns The positioned scene primitives.
|
|
144
|
-
*/
|
|
145
141
|
export declare function buildBarScene(chart: Chart, wPt: number, hPt: number, measure: MeasureText): ChartScene;
|
|
146
142
|
/**
|
|
147
143
|
* The name a series shows in the legend: its own `c:tx`, or Excel's positional
|
|
@@ -186,7 +186,7 @@ function buildFrame(chart, wPt, hPt, measure, horizontal, opts = {}) {
|
|
|
186
186
|
const fmtVal = opts.formatValue ?? ((v) => formatTick(v, scale.step));
|
|
187
187
|
const tickVals = ticks(scale);
|
|
188
188
|
const vals2 = onSecondary.flatMap((s) => s.values.slice(0, nCats));
|
|
189
|
-
const scale2 = vals2.length > 0 ? niceScale(Math.min(0, ...vals2), Math.max(0, ...vals2),
|
|
189
|
+
const scale2 = vals2.length > 0 ? niceScale(Math.min(0, ...vals2), Math.max(0, ...vals2), tickBudget(hPt)) : void 0;
|
|
190
190
|
const tickVals2 = scale2 ? ticks(scale2) : [];
|
|
191
191
|
let top = 4;
|
|
192
192
|
if (chart.title) top += 13 * 1.6;
|
|
@@ -202,6 +202,18 @@ function buildFrame(chart, wPt, hPt, measure, horizontal, opts = {}) {
|
|
|
202
202
|
const plotH = Math.max(1, hPt - top - y0);
|
|
203
203
|
const valueOffset = (v) => (v - scale.min) / (scale.max - scale.min) * (horizontal ? plotW : plotH);
|
|
204
204
|
const zeroOffset = valueOffset(0);
|
|
205
|
+
const plotBackground = chart.plotFillHex ?? chart.plotLine?.colorHex ? {
|
|
206
|
+
x: x0,
|
|
207
|
+
y: y0,
|
|
208
|
+
w: plotW,
|
|
209
|
+
h: plotH,
|
|
210
|
+
...chart.plotFillHex ? { fillHex: chart.plotFillHex } : {},
|
|
211
|
+
...chart.plotLine?.colorHex ? {
|
|
212
|
+
strokeHex: chart.plotLine.colorHex,
|
|
213
|
+
strokeWidthPt: chart.plotLine.widthPt ?? .75,
|
|
214
|
+
...chart.plotLine.dash ? { strokeDash: chart.plotLine.dash } : {}
|
|
215
|
+
} : {}
|
|
216
|
+
} : void 0;
|
|
205
217
|
pushChartTitle(labels, chart, wPt, hPt);
|
|
206
218
|
if (chart.valAxisTitle) labels.push({
|
|
207
219
|
text: chart.valAxisTitle,
|
|
@@ -288,6 +300,7 @@ function buildFrame(chart, wPt, hPt, measure, horizontal, opts = {}) {
|
|
|
288
300
|
rects,
|
|
289
301
|
polylines,
|
|
290
302
|
gridlines,
|
|
303
|
+
...plotBackground ? { plotBackground } : {},
|
|
291
304
|
labels
|
|
292
305
|
};
|
|
293
306
|
}
|
|
@@ -352,6 +365,24 @@ function chartValueFormatter(chart) {
|
|
|
352
365
|
* @param measure Text measurer used to size labels and reserve axis gutters.
|
|
353
366
|
* @returns The positioned scene primitives.
|
|
354
367
|
*/
|
|
368
|
+
/**
|
|
369
|
+
* §21.2.2.198 `c:ser/c:spPr/a:ln` — a bar's own outline, as the stroke fields a
|
|
370
|
+
* {@link ChartRect} carries. Chart_BorderLine_Style.docx outlines each of its
|
|
371
|
+
* series in a colour and dash of its own, and drawing bars unstroked lost all
|
|
372
|
+
* of it.
|
|
373
|
+
*
|
|
374
|
+
* @param series The series the bar belongs to.
|
|
375
|
+
* @returns The stroke fields, or an empty object when the series has no rule.
|
|
376
|
+
*/
|
|
377
|
+
function barOutline(series) {
|
|
378
|
+
const ln = series.line;
|
|
379
|
+
if (!ln || ln.none === true || !ln.colorHex) return {};
|
|
380
|
+
return {
|
|
381
|
+
strokeHex: ln.colorHex,
|
|
382
|
+
strokeWidthPt: ln.widthPt ?? .75,
|
|
383
|
+
...ln.dash && ln.dash !== "solid" ? { strokeDash: ln.dash } : {}
|
|
384
|
+
};
|
|
385
|
+
}
|
|
355
386
|
function buildBarScene(chart, wPt, hPt, measure) {
|
|
356
387
|
const g = chart.grouping ?? "clustered";
|
|
357
388
|
const stacked = g === "stacked" || g === "percentStacked";
|
|
@@ -379,19 +410,22 @@ function buildBarScene(chart, wPt, hPt, measure) {
|
|
|
379
410
|
const lo = Math.min(o0, o1);
|
|
380
411
|
const span = Math.abs(o1 - o0);
|
|
381
412
|
const color = pointColor(series, c) ?? seriesColor(series, s, chart.seriesColorCycle);
|
|
413
|
+
const outline = barOutline(series);
|
|
382
414
|
if (horizontal) f.rects.push({
|
|
383
415
|
x: f.x0 + lo,
|
|
384
416
|
y: along,
|
|
385
417
|
w: span,
|
|
386
418
|
h: barW,
|
|
387
|
-
fillHex: color
|
|
419
|
+
fillHex: color,
|
|
420
|
+
...outline
|
|
388
421
|
});
|
|
389
422
|
else f.rects.push({
|
|
390
423
|
x: along,
|
|
391
424
|
y: f.y0 + lo,
|
|
392
425
|
w: barW,
|
|
393
426
|
h: span,
|
|
394
|
-
fillHex: color
|
|
427
|
+
fillHex: color,
|
|
428
|
+
...outline
|
|
395
429
|
});
|
|
396
430
|
if (chart.showValues && span > 9) {
|
|
397
431
|
const raw = series.values[c] ?? 0;
|
|
@@ -407,6 +441,8 @@ function buildBarScene(chart, wPt, hPt, measure) {
|
|
|
407
441
|
rects: f.rects,
|
|
408
442
|
polylines: f.polylines,
|
|
409
443
|
gridlines: f.gridlines,
|
|
444
|
+
...f.plotBackground ? { plotBackground: f.plotBackground } : {},
|
|
445
|
+
...f.plotBackground ? { plotBackground: f.plotBackground } : {},
|
|
410
446
|
wedges: [],
|
|
411
447
|
labels: f.labels
|
|
412
448
|
};
|
|
@@ -423,6 +459,7 @@ function buildBarScene(chart, wPt, hPt, measure) {
|
|
|
423
459
|
const len = f.valueOffset(series.values[c] ?? 0) - f.zeroOffset;
|
|
424
460
|
const color = pointColor(series, c) ?? seriesColor(series, s, chart.seriesColorCycle);
|
|
425
461
|
const along = slotStart + b * barW;
|
|
462
|
+
const outline = barOutline(series);
|
|
426
463
|
if (horizontal) {
|
|
427
464
|
const bx = f.x0 + f.zeroOffset + Math.min(0, len);
|
|
428
465
|
f.rects.push({
|
|
@@ -430,7 +467,8 @@ function buildBarScene(chart, wPt, hPt, measure) {
|
|
|
430
467
|
y: along,
|
|
431
468
|
w: Math.abs(len),
|
|
432
469
|
h: barW,
|
|
433
|
-
fillHex: color
|
|
470
|
+
fillHex: color,
|
|
471
|
+
...outline
|
|
434
472
|
});
|
|
435
473
|
} else {
|
|
436
474
|
const by = f.y0 + f.zeroOffset + Math.min(0, len);
|
|
@@ -439,7 +477,8 @@ function buildBarScene(chart, wPt, hPt, measure) {
|
|
|
439
477
|
y: by,
|
|
440
478
|
w: barW,
|
|
441
479
|
h: Math.abs(len),
|
|
442
|
-
fillHex: color
|
|
480
|
+
fillHex: color,
|
|
481
|
+
...outline
|
|
443
482
|
});
|
|
444
483
|
}
|
|
445
484
|
if (chart.showValues) {
|
|
@@ -466,6 +505,7 @@ function buildBarScene(chart, wPt, hPt, measure) {
|
|
|
466
505
|
rects: f.rects,
|
|
467
506
|
polylines: f.polylines,
|
|
468
507
|
gridlines: f.gridlines,
|
|
508
|
+
...f.plotBackground ? { plotBackground: f.plotBackground } : {},
|
|
469
509
|
wedges: [],
|
|
470
510
|
labels: f.labels
|
|
471
511
|
};
|
|
@@ -580,6 +620,7 @@ function buildAreaScene(chart, wPt, hPt, measure) {
|
|
|
580
620
|
rects: f.rects,
|
|
581
621
|
polylines: f.polylines,
|
|
582
622
|
gridlines: f.gridlines,
|
|
623
|
+
...f.plotBackground ? { plotBackground: f.plotBackground } : {},
|
|
583
624
|
wedges: [],
|
|
584
625
|
labels: f.labels,
|
|
585
626
|
polygons
|
|
@@ -670,8 +711,12 @@ function autoRange(vals) {
|
|
|
670
711
|
const hi = Math.max(...vals);
|
|
671
712
|
return [lo > 0 && lo < 5 / 6 * hi ? 0 : lo, hi];
|
|
672
713
|
}
|
|
673
|
-
/**
|
|
674
|
-
|
|
714
|
+
/**
|
|
715
|
+
* Ticks that fit along an axis `extentPt` long (mirrors {@link axisScale}).
|
|
716
|
+
* A tick every 32pt is what both references draw: at 24 a 250pt plot carried
|
|
717
|
+
* eleven of them (0, 0.5, 1 … 5.5) where both label 0…6 in whole numbers.
|
|
718
|
+
*/
|
|
719
|
+
var tickBudget = (extentPt) => Math.min(10, Math.max(4, Math.round(extentPt / 32)));
|
|
675
720
|
/** Side (points) of the square stamped for a series that names no symbol. */
|
|
676
721
|
var DEFAULT_MARKER_PT = 4;
|
|
677
722
|
/**
|
|
@@ -722,7 +767,9 @@ function pushMarker(rects, wedges, marker, x, y, color) {
|
|
|
722
767
|
*/
|
|
723
768
|
function buildLineScene(chart, wPt, hPt, measure) {
|
|
724
769
|
const allVals = chart.series.flatMap((s) => s.values);
|
|
725
|
-
const
|
|
770
|
+
const lo = allVals.length > 0 ? Math.min(...allVals) : 0;
|
|
771
|
+
const hi = allVals.length > 0 ? Math.max(...allVals) : 1;
|
|
772
|
+
const range = lo > 0 && lo > 5 / 6 * hi ? [lo, hi] : [Math.min(0, lo), Math.max(0, hi)];
|
|
726
773
|
const lineFormat = chartValueFormatter(chart);
|
|
727
774
|
const f = buildFrame(chart, wPt, hPt, measure, false, {
|
|
728
775
|
dataRange: range,
|
|
@@ -760,6 +807,7 @@ function buildLineScene(chart, wPt, hPt, measure) {
|
|
|
760
807
|
rects: f.rects,
|
|
761
808
|
polylines: f.polylines,
|
|
762
809
|
gridlines: f.gridlines,
|
|
810
|
+
...f.plotBackground ? { plotBackground: f.plotBackground } : {},
|
|
763
811
|
wedges,
|
|
764
812
|
labels: f.labels
|
|
765
813
|
};
|
|
@@ -1003,7 +1051,8 @@ function withFrame(scene, chart, wPt, hPt) {
|
|
|
1003
1051
|
...chart.frameFillHex ? { fillHex: chart.frameFillHex } : {},
|
|
1004
1052
|
...chart.frameLineHex ? {
|
|
1005
1053
|
strokeHex: chart.frameLineHex,
|
|
1006
|
-
strokeWidthPt: .75
|
|
1054
|
+
strokeWidthPt: chart.frameLineWidthPt ?? .75,
|
|
1055
|
+
...chart.frameLineDash ? { strokeDash: chart.frameLineDash } : {}
|
|
1007
1056
|
} : {}
|
|
1008
1057
|
};
|
|
1009
1058
|
return {
|
|
@@ -100,10 +100,15 @@ function parseChart(chartXml, resolveColor) {
|
|
|
100
100
|
const valAxisMin = axisScaling(plotArea, "c:min");
|
|
101
101
|
const valAxisMax = axisScaling(plotArea, "c:max");
|
|
102
102
|
const catAxisReversed = axisOrientation(catAxNode) === "maxMin";
|
|
103
|
-
const
|
|
104
|
-
const
|
|
103
|
+
const chartSpace = tree.find((c) => poIs(c, "c:chartSpace"));
|
|
104
|
+
const spaceSpPr = poChildren(chartSpace).find((c) => poIs(c, "c:spPr"));
|
|
105
105
|
const frameLine = spaceSpPr ? poChildren(spaceSpPr).find((c) => poIs(c, "a:ln")) : void 0;
|
|
106
|
-
const
|
|
106
|
+
const frameStyle = lineStyleOf(chartSpace, resolveColor);
|
|
107
|
+
const frameFillHex = spaceSpPr ? frameFillOf(spaceSpPr, resolveColor) : "FFFFFF";
|
|
108
|
+
const plotSpPr = poChildren(plotArea).find((c) => poIs(c, "c:spPr"));
|
|
109
|
+
const plotFillHex = plotSpPr ? frameFillOf(plotSpPr, resolveColor) : void 0;
|
|
110
|
+
const plotLine = lineStyleOf(plotArea, resolveColor);
|
|
111
|
+
const frameLineHex = spaceSpPr ? frameLine ? frameFillOf(frameLine, resolveColor) : void 0 : "D9D9D9";
|
|
107
112
|
const numberFormat = valueFormatCode(plotArea);
|
|
108
113
|
const legend = poChildren(chart).find((c) => poIs(c, "c:legend"));
|
|
109
114
|
const legendPos = legend ? poVal(poChildren(legend).find((c) => poIs(c, "c:legendPos"))) : void 0;
|
|
@@ -138,6 +143,10 @@ function parseChart(chartXml, resolveColor) {
|
|
|
138
143
|
...valAxisMax !== void 0 ? { valAxisMax } : {},
|
|
139
144
|
...frameFillHex ? { frameFillHex } : {},
|
|
140
145
|
...frameLineHex ? { frameLineHex } : {},
|
|
146
|
+
...frameStyle?.widthPt !== void 0 ? { frameLineWidthPt: frameStyle.widthPt } : {},
|
|
147
|
+
...frameStyle?.dash ? { frameLineDash: frameStyle.dash } : {},
|
|
148
|
+
...plotFillHex ? { plotFillHex } : {},
|
|
149
|
+
...plotLine && plotLine.none !== true ? { plotLine } : {},
|
|
141
150
|
...numberFormat ? { numberFormat } : {}
|
|
142
151
|
};
|
|
143
152
|
}
|
|
@@ -238,6 +247,22 @@ function dataPointColors(ser, resolveColor) {
|
|
|
238
247
|
}
|
|
239
248
|
return out;
|
|
240
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* The BACKGROUND fill of a frame (the chart space, the plot rectangle): its own
|
|
252
|
+
* `a:solidFill` and nothing else. Unlike a series, a frame that states
|
|
253
|
+
* `<a:noFill/>` is not filled in the colour of its own rule —
|
|
254
|
+
* Chart_Plot_BorderLine_Style.docx rules its plot in orange and we painted the
|
|
255
|
+
* whole plot orange.
|
|
256
|
+
*
|
|
257
|
+
* @param spPr The frame's `c:spPr`, or `undefined`.
|
|
258
|
+
* @param resolveColor Maps a DrawingML colour reference to 6-hex.
|
|
259
|
+
* @returns The fill colour, or `undefined` when the frame states none.
|
|
260
|
+
*/
|
|
261
|
+
function frameFillOf(spPr, resolveColor) {
|
|
262
|
+
if (!spPr) return void 0;
|
|
263
|
+
const solid = poChildren(spPr).find((c) => poIs(c, "a:solidFill"));
|
|
264
|
+
return solid ? colorFromSolidFill(solid, resolveColor) : void 0;
|
|
265
|
+
}
|
|
241
266
|
function fillColorOf(spPr, resolveColor) {
|
|
242
267
|
if (!spPr) return void 0;
|
|
243
268
|
const directFill = poChildren(spPr).find((c) => poIs(c, "a:solidFill"));
|
|
@@ -349,6 +374,16 @@ function axisScaling(plotArea, tag) {
|
|
|
349
374
|
* @param resolveColor Maps a DrawingML colour reference to 6 hex digits.
|
|
350
375
|
* @returns The rule, or undefined when the node says nothing about it.
|
|
351
376
|
*/
|
|
377
|
+
var DASHES = new Set([
|
|
378
|
+
"solid",
|
|
379
|
+
"dot",
|
|
380
|
+
"dash",
|
|
381
|
+
"dashDot",
|
|
382
|
+
"lgDash",
|
|
383
|
+
"lgDashDot",
|
|
384
|
+
"sysDash",
|
|
385
|
+
"sysDot"
|
|
386
|
+
]);
|
|
352
387
|
function lineStyleOf(owner, resolveColor) {
|
|
353
388
|
const spPr = owner ? poChildren(owner).find((c) => poIs(c, "c:spPr")) : void 0;
|
|
354
389
|
const ln = spPr ? poChildren(spPr).find((c) => poIs(c, "a:ln")) : void 0;
|
|
@@ -358,10 +393,14 @@ function lineStyleOf(owner, resolveColor) {
|
|
|
358
393
|
const colorHex = solid ? colorFromSolidFill(solid, resolveColor) : void 0;
|
|
359
394
|
const emu = Number(poAttr(ln, "w"));
|
|
360
395
|
const widthPt = Number.isFinite(emu) && emu > 0 ? emu / 12700 : void 0;
|
|
361
|
-
|
|
396
|
+
const prst = poChildren(ln).find((c) => poIs(c, "a:prstDash"));
|
|
397
|
+
const dashVal = prst ? poAttr(prst, "val") : void 0;
|
|
398
|
+
const dash = dashVal !== void 0 && DASHES.has(dashVal) ? dashVal : void 0;
|
|
399
|
+
if (!colorHex && widthPt === void 0 && !dash) return void 0;
|
|
362
400
|
return {
|
|
363
401
|
...colorHex ? { colorHex } : {},
|
|
364
|
-
...widthPt !== void 0 ? { widthPt } : {}
|
|
402
|
+
...widthPt !== void 0 ? { widthPt } : {},
|
|
403
|
+
...dash ? { dash } : {}
|
|
365
404
|
};
|
|
366
405
|
}
|
|
367
406
|
function valueFormatCode(plotArea) {
|
|
@@ -2,7 +2,7 @@ import { PoNode } from '../po-helpers.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* A colour transform child (§20.1.2.3): `lumMod`/`lumOff` modulate luminance,
|
|
4
4
|
* `shade` darkens toward black, `tint` lightens toward white. `val` is normalised
|
|
5
|
-
* to 0..1 (the XML stores thousandths of a percent). `alpha`
|
|
5
|
+
* to 0..1 (the XML stores thousandths of a percent). `alpha` composites over white
|
|
6
6
|
* (solid fills emit no transparency).
|
|
7
7
|
*/
|
|
8
8
|
export interface ColorMod {
|
|
@@ -102,7 +102,11 @@ function applyColorMods(hex, mods) {
|
|
|
102
102
|
} else if (m.kind === "satOff") {
|
|
103
103
|
const [h, sat, l] = rgbToHsl(r, g, b);
|
|
104
104
|
[r, g, b] = hslToRgb(h, clamp01(sat + m.val), l);
|
|
105
|
-
} else if (m.kind === "
|
|
105
|
+
} else if (m.kind === "alpha") {
|
|
106
|
+
r = r * m.val + (1 - m.val);
|
|
107
|
+
g = g * m.val + (1 - m.val);
|
|
108
|
+
b = b * m.val + (1 - m.val);
|
|
109
|
+
} else {
|
|
106
110
|
const [h, s, l] = rgbToHsl(r, g, b);
|
|
107
111
|
[r, g, b] = hslToRgb(h, clamp01(s * m.val), l);
|
|
108
112
|
}
|
|
@@ -157,6 +161,22 @@ function makeColorResolver(palette) {
|
|
|
157
161
|
}
|
|
158
162
|
/** A {@link ColorResolver} backed by the {@link DEFAULT_THEME_PALETTE}. */
|
|
159
163
|
var defaultColorResolver = makeColorResolver(DEFAULT_THEME_PALETTE);
|
|
164
|
+
var PRESET_COLORS = new Map([
|
|
165
|
+
["black", "000000"],
|
|
166
|
+
["white", "FFFFFF"],
|
|
167
|
+
["gray", "808080"],
|
|
168
|
+
["grey", "808080"],
|
|
169
|
+
["darkGray".toLowerCase(), "A9A9A9"],
|
|
170
|
+
["lightGray".toLowerCase(), "D3D3D3"],
|
|
171
|
+
["red", "FF0000"],
|
|
172
|
+
["green", "008000"],
|
|
173
|
+
["blue", "0000FF"],
|
|
174
|
+
["yellow", "FFFF00"],
|
|
175
|
+
["cyan", "00FFFF"],
|
|
176
|
+
["magenta", "FF00FF"],
|
|
177
|
+
["dkGray".toLowerCase(), "A9A9A9"],
|
|
178
|
+
["ltGray".toLowerCase(), "D3D3D3"]
|
|
179
|
+
]);
|
|
160
180
|
/**
|
|
161
181
|
* Read the colour transform children ({@link ColorMod}s) under an `a:srgbClr` /
|
|
162
182
|
* `a:schemeClr` node, normalising each `val` from thousandths-of-a-percent to 0..1.
|
|
@@ -221,6 +241,12 @@ function resolveColorNode(c, resolveColor) {
|
|
|
221
241
|
if (last && /^[0-9A-Fa-f]{6}$/.test(last)) return last.toUpperCase();
|
|
222
242
|
return SYSTEM_COLORS.get(poAttr(c, "val") ?? "");
|
|
223
243
|
}
|
|
244
|
+
if (poIs(c, "a:prstClr")) {
|
|
245
|
+
const hex = PRESET_COLORS.get((poAttr(c, "val") ?? "").toLowerCase());
|
|
246
|
+
if (hex === void 0) return void 0;
|
|
247
|
+
const presetMods = readColorMods(c);
|
|
248
|
+
return presetMods.length > 0 ? applyColorMods(hex, presetMods) : hex;
|
|
249
|
+
}
|
|
224
250
|
const isSrgb = poIs(c, "a:srgbClr");
|
|
225
251
|
if (!isSrgb && !poIs(c, "a:schemeClr")) return void 0;
|
|
226
252
|
const v = poAttr(c, "val");
|
|
@@ -86,8 +86,33 @@ function presetPaths(preset, w, h, adjust) {
|
|
|
86
86
|
[0, h / 2]
|
|
87
87
|
])];
|
|
88
88
|
}
|
|
89
|
+
case "round1Rect":
|
|
90
|
+
case "round2SameRect":
|
|
91
|
+
case "round2DiagRect":
|
|
92
|
+
case "snip1Rect":
|
|
93
|
+
case "snip2SameRect":
|
|
94
|
+
case "snip2DiagRect":
|
|
95
|
+
case "snipRoundRect": return [cornerRect(preset, w, h, adjust)];
|
|
96
|
+
case "star4":
|
|
97
|
+
case "star5":
|
|
98
|
+
case "star6":
|
|
99
|
+
case "star7":
|
|
100
|
+
case "star8":
|
|
101
|
+
case "star10":
|
|
102
|
+
case "star12":
|
|
103
|
+
case "star16":
|
|
104
|
+
case "star24":
|
|
105
|
+
case "star32": {
|
|
106
|
+
const s = STARS.get(preset);
|
|
107
|
+
return s ? [star(w, h, s, adjust)] : null;
|
|
108
|
+
}
|
|
89
109
|
case "line":
|
|
90
110
|
case "straightConnector1": return [new PathBuilder().moveTo(0, h).lineTo(w, 0).build()];
|
|
111
|
+
case "bentConnector2": return [new PathBuilder().moveTo(0, h).lineTo(w, h).lineTo(w, 0).build()];
|
|
112
|
+
case "bentConnector3": {
|
|
113
|
+
const bx = clamp(frac(adjust, "adj1", 5e4), 0, 1) * w;
|
|
114
|
+
return [new PathBuilder().moveTo(0, h).lineTo(bx, h).lineTo(bx, 0).lineTo(w, 0).build()];
|
|
115
|
+
}
|
|
91
116
|
case "rightArrow": return [blockArrow(w, h, adjust, "right")];
|
|
92
117
|
case "leftArrow": return [blockArrow(w, h, adjust, "left")];
|
|
93
118
|
case "upArrow": return [blockArrow(w, h, adjust, "up")];
|
|
@@ -157,6 +182,214 @@ function customPaths(geom, wPt, hPt) {
|
|
|
157
182
|
}
|
|
158
183
|
return [b.build()];
|
|
159
184
|
}
|
|
185
|
+
var SQUARE = {
|
|
186
|
+
cut: 0,
|
|
187
|
+
round: false
|
|
188
|
+
};
|
|
189
|
+
var CORNER_RECTS = new Map([
|
|
190
|
+
["round1Rect", {
|
|
191
|
+
defaults: [16667, 0],
|
|
192
|
+
corners: [
|
|
193
|
+
void 0,
|
|
194
|
+
0,
|
|
195
|
+
void 0,
|
|
196
|
+
void 0
|
|
197
|
+
],
|
|
198
|
+
round: true
|
|
199
|
+
}],
|
|
200
|
+
["snip1Rect", {
|
|
201
|
+
defaults: [16667, 0],
|
|
202
|
+
corners: [
|
|
203
|
+
void 0,
|
|
204
|
+
0,
|
|
205
|
+
void 0,
|
|
206
|
+
void 0
|
|
207
|
+
],
|
|
208
|
+
round: false
|
|
209
|
+
}],
|
|
210
|
+
["round2SameRect", {
|
|
211
|
+
defaults: [16667, 0],
|
|
212
|
+
corners: [
|
|
213
|
+
0,
|
|
214
|
+
0,
|
|
215
|
+
1,
|
|
216
|
+
1
|
|
217
|
+
],
|
|
218
|
+
round: true
|
|
219
|
+
}],
|
|
220
|
+
["snip2SameRect", {
|
|
221
|
+
defaults: [16667, 0],
|
|
222
|
+
corners: [
|
|
223
|
+
0,
|
|
224
|
+
0,
|
|
225
|
+
1,
|
|
226
|
+
1
|
|
227
|
+
],
|
|
228
|
+
round: false
|
|
229
|
+
}],
|
|
230
|
+
["round2DiagRect", {
|
|
231
|
+
defaults: [16667, 0],
|
|
232
|
+
corners: [
|
|
233
|
+
0,
|
|
234
|
+
1,
|
|
235
|
+
0,
|
|
236
|
+
1
|
|
237
|
+
],
|
|
238
|
+
round: true
|
|
239
|
+
}],
|
|
240
|
+
["snip2DiagRect", {
|
|
241
|
+
defaults: [16667, 0],
|
|
242
|
+
corners: [
|
|
243
|
+
0,
|
|
244
|
+
1,
|
|
245
|
+
0,
|
|
246
|
+
1
|
|
247
|
+
],
|
|
248
|
+
round: false
|
|
249
|
+
}],
|
|
250
|
+
["snipRoundRect", {
|
|
251
|
+
defaults: [16667, 16667],
|
|
252
|
+
corners: [
|
|
253
|
+
0,
|
|
254
|
+
1,
|
|
255
|
+
void 0,
|
|
256
|
+
void 0
|
|
257
|
+
],
|
|
258
|
+
round: [false, true]
|
|
259
|
+
}]
|
|
260
|
+
]);
|
|
261
|
+
function cornerRect(preset, w, h, adjust) {
|
|
262
|
+
const spec = CORNER_RECTS.get(preset);
|
|
263
|
+
const ss = Math.min(w, h);
|
|
264
|
+
const guide = (i) => {
|
|
265
|
+
return clamp((adjust.get(i === 0 ? "adj1" : "adj2") ?? (i === 0 ? adjust.get("adj") : void 0) ?? spec.defaults[i]) / 1e5, 0, .5) * ss;
|
|
266
|
+
};
|
|
267
|
+
return roundedCorners(w, h, spec.corners.map((g) => {
|
|
268
|
+
if (g === void 0) return SQUARE;
|
|
269
|
+
const round = typeof spec.round === "boolean" ? spec.round : spec.round[g];
|
|
270
|
+
return {
|
|
271
|
+
cut: guide(g),
|
|
272
|
+
round
|
|
273
|
+
};
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
function roundedCorners(w, h, [tl, tr, br, bl]) {
|
|
277
|
+
const at = [
|
|
278
|
+
{
|
|
279
|
+
c: tl,
|
|
280
|
+
from: [0, h - tl.cut],
|
|
281
|
+
to: [tl.cut, h],
|
|
282
|
+
centre: [tl.cut, h - tl.cut],
|
|
283
|
+
start: Math.PI
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
c: tr,
|
|
287
|
+
from: [w - tr.cut, h],
|
|
288
|
+
to: [w, h - tr.cut],
|
|
289
|
+
centre: [w - tr.cut, h - tr.cut],
|
|
290
|
+
start: Math.PI / 2
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
c: br,
|
|
294
|
+
from: [w, br.cut],
|
|
295
|
+
to: [w - br.cut, 0],
|
|
296
|
+
centre: [w - br.cut, br.cut],
|
|
297
|
+
start: 0
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
c: bl,
|
|
301
|
+
from: [bl.cut, 0],
|
|
302
|
+
to: [0, bl.cut],
|
|
303
|
+
centre: [bl.cut, bl.cut],
|
|
304
|
+
start: -Math.PI / 2
|
|
305
|
+
}
|
|
306
|
+
];
|
|
307
|
+
const b = new PathBuilder();
|
|
308
|
+
at.forEach((corner, i) => {
|
|
309
|
+
if (i === 0) b.moveTo(corner.from[0], corner.from[1]);
|
|
310
|
+
else b.lineTo(corner.from[0], corner.from[1]);
|
|
311
|
+
if (corner.c.cut <= 0) return;
|
|
312
|
+
if (corner.c.round) b.append(arcToBeziers(corner.centre[0], corner.centre[1], corner.c.cut, corner.c.cut, corner.start, -Math.PI / 2));
|
|
313
|
+
else b.lineTo(corner.to[0], corner.to[1]);
|
|
314
|
+
});
|
|
315
|
+
return b.close().build();
|
|
316
|
+
}
|
|
317
|
+
var STARS = new Map([
|
|
318
|
+
["star4", {
|
|
319
|
+
points: 4,
|
|
320
|
+
adj: 12500,
|
|
321
|
+
hf: 1e5,
|
|
322
|
+
vf: 1e5
|
|
323
|
+
}],
|
|
324
|
+
["star5", {
|
|
325
|
+
points: 5,
|
|
326
|
+
adj: 19098,
|
|
327
|
+
hf: 105146,
|
|
328
|
+
vf: 110557
|
|
329
|
+
}],
|
|
330
|
+
["star6", {
|
|
331
|
+
points: 6,
|
|
332
|
+
adj: 28868,
|
|
333
|
+
hf: 115470,
|
|
334
|
+
vf: 1e5
|
|
335
|
+
}],
|
|
336
|
+
["star7", {
|
|
337
|
+
points: 7,
|
|
338
|
+
adj: 34601,
|
|
339
|
+
hf: 102572,
|
|
340
|
+
vf: 105210
|
|
341
|
+
}],
|
|
342
|
+
["star8", {
|
|
343
|
+
points: 8,
|
|
344
|
+
adj: 37500,
|
|
345
|
+
hf: 1e5,
|
|
346
|
+
vf: 1e5
|
|
347
|
+
}],
|
|
348
|
+
["star10", {
|
|
349
|
+
points: 10,
|
|
350
|
+
adj: 42533,
|
|
351
|
+
hf: 105146,
|
|
352
|
+
vf: 1e5
|
|
353
|
+
}],
|
|
354
|
+
["star12", {
|
|
355
|
+
points: 12,
|
|
356
|
+
adj: 37500,
|
|
357
|
+
hf: 1e5,
|
|
358
|
+
vf: 1e5
|
|
359
|
+
}],
|
|
360
|
+
["star16", {
|
|
361
|
+
points: 16,
|
|
362
|
+
adj: 37500,
|
|
363
|
+
hf: 1e5,
|
|
364
|
+
vf: 1e5
|
|
365
|
+
}],
|
|
366
|
+
["star24", {
|
|
367
|
+
points: 24,
|
|
368
|
+
adj: 37500,
|
|
369
|
+
hf: 1e5,
|
|
370
|
+
vf: 1e5
|
|
371
|
+
}],
|
|
372
|
+
["star32", {
|
|
373
|
+
points: 32,
|
|
374
|
+
adj: 37500,
|
|
375
|
+
hf: 1e5,
|
|
376
|
+
vf: 1e5
|
|
377
|
+
}]
|
|
378
|
+
]);
|
|
379
|
+
function star(w, h, preset, adjust) {
|
|
380
|
+
const inner = clamp(frac(adjust, "adj", preset.adj) * 2, 0, 1);
|
|
381
|
+
const hf = preset.hf / 1e5;
|
|
382
|
+
const vf = preset.vf / 1e5;
|
|
383
|
+
const pts = [];
|
|
384
|
+
for (let i = 0; i < preset.points; i++) {
|
|
385
|
+
const out = -Math.PI / 2 + i * 2 * Math.PI / preset.points;
|
|
386
|
+
for (const [angle, r] of [[out, 1], [out + Math.PI / preset.points, inner]]) {
|
|
387
|
+
const x = w / 2 * (1 + hf * r * Math.cos(angle));
|
|
388
|
+
pts.push([x, h - h / 2 * vf * (1 + r * Math.sin(angle))]);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return polygon(pts);
|
|
392
|
+
}
|
|
160
393
|
function regularPolygon(w, h, n) {
|
|
161
394
|
const cx = w / 2;
|
|
162
395
|
const cy = h / 2;
|
|
@@ -37,6 +37,18 @@ export declare function gradientToSolid(gradient: ShapeGradient): string;
|
|
|
37
37
|
* @returns The `<linearGradient>` or `<radialGradient>` markup.
|
|
38
38
|
*/
|
|
39
39
|
export declare function gradientSvgDef(id: string, g: ShapeGradient): string;
|
|
40
|
+
/**
|
|
41
|
+
* §20.1.8.24 / §20.1.8.42 — the arrowheads a line asks for at its ends, as
|
|
42
|
+
* filled paths in the same local frame as the shape's own geometry. The head
|
|
43
|
+
* rides the first point of the first subpath and the tail the last point of
|
|
44
|
+
* the last one, each turned along the segment that reaches it.
|
|
45
|
+
*
|
|
46
|
+
* @param paths The shape's geometry paths.
|
|
47
|
+
* @param line The parsed line (its `headEnd`/`tailEnd` are read).
|
|
48
|
+
* @param strokeWidthPt The pen width the decorations are sized against.
|
|
49
|
+
* @returns The decoration paths (empty when the line asks for none).
|
|
50
|
+
*/
|
|
51
|
+
export declare function lineEndPaths(paths: ReadonlyArray<VectorPath>, line: ShapeLine | undefined, strokeWidthPt: number): Array<VectorPath>;
|
|
40
52
|
/**
|
|
41
53
|
* Build a {@link StrokeStyle} from a shape's `a:ln` line, resolving the default
|
|
42
54
|
* width (0.75pt), dash pattern and line cap. Returns `undefined` for no line or
|