@office-kit/pptx-preview 0.13.0 → 0.15.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 +15 -6
- package/dist/{index-DwLYANVE.d.ts → index-74n14k3Y.d.ts} +55 -44
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/{src-DYfIZIh8.js → src-pb3C61GD.js} +792 -1124
- package/dist/src-pb3C61GD.js.map +1 -0
- package/fonts/LICENSES.md +1 -1
- package/package.json +3 -4
- package/dist/src-DYfIZIh8.js.map +0 -1
|
@@ -1,50 +1,22 @@
|
|
|
1
|
-
import { getEffectiveColorMap, getGroupChildren, getGroupTransform, getParagraphAlignment, getParagraphBullet, getParagraphBulletImageBytes, getParagraphBulletStyle, getParagraphIndent, getParagraphLevel, getParagraphPropertiesEffective, getParagraphSpacing, getPresentationFirstSlideNumber, getPresentationFonts, getPresentationTheme, getShapeAdjustValues, getShapeAltTitle, getShapeBodyPrEffective, getShapeBounds, getShapeBoundsResolved, getShapeChartSpec, getShapeClickAction, getShapeCustomGeometry, getShapeDescription, getShapeEffectsEffective, getShapeFillColorResolved, getShapeFillEffective, getShapeFillOpacity, getShapeFlip, getShapeGradientFill, getShapeGradientFillEffective, getShapeHyperlinkTooltip, getShapeId, getShapeImageBiLevelThreshold, getShapeImageBrightness, getShapeImageBytes, getShapeImageContrast, getShapeImageCrop, getShapeImageDuotone, getShapeImageFillBytes, getShapeImageFillLayout, getShapeImageFormat, getShapeImageIntrinsicSize, getShapeImageLinkUrl, getShapeImageOpacity, getShapeImagePartName, getShapeKind, getShapeName, getShapeParagraphCount, getShapeParagraphElements, getShapePatternFill, getShapePlaceholderType, getShapePreset, getShapeRotation, getShapeRunClickAction, getShapeRunFormat, getShapeRunFormatEffective, getShapeRunHyperlink, getShapeRunHyperlinkTooltip, getShapeStrokeArrow, getShapeStrokeCap, getShapeStrokeColorResolved, getShapeStrokeCompound, getShapeStrokeDash, getShapeStrokeEffective, getShapeStrokeJoin, getShapeStrokeOpacity, getShapeTextAnchor, getShapeTextAutoFit, getShapeTextAutoFitParams, getShapeTextBodyRotationDeg, getShapeTextColumns, getShapeTextDirection, getShapeTextMargins, getShapeXmlString, getSlideBackground, getSlideBackgroundGradientFill, getSlideBackgroundImageBytes, getSlideBackgroundImageCrop, getSlideBackgroundImageFillLayout, getSlideBackgroundImageIntrinsicSize, getSlideBackgroundImageOpacity, getSlideBackgroundPatternFill, getSlideIndex, getSlideLayout, getSlideLayoutBackground, getSlideLayoutBackgroundGradientFill, getSlideLayoutBackgroundImageBytes, getSlideLayoutBackgroundPatternFill, getSlideLayoutShapes, getSlideMasterBackground, getSlideMasterBackgroundGradientFill, getSlideMasterBackgroundImageBytes, getSlideMasterBackgroundPatternFill, getSlideMasterShapes, getSlideShapes, getSlideSize, getSlides, getTableCellAnchor, getTableCellAppearanceEffective, getTableCellMargins, getTableCellParagraphs, getTableCellRunFormatEffective, getTableCellSpan, getTableCellTextDirection, getTableCells, getTableColumnWidths, getTableDimensions, getTableRowHeights, isChartShape, isParagraphBulletPicture, isShapeHidden, isShapeImageGrayscale, isShapePlaceholder, isShapeTextBox, isSlideBackgroundGraphicsHidden, isSlideLayoutBackgroundGraphicsHidden, isTableShape, resolveDeckBodyTextColor } from "@office-kit/pptx";
|
|
1
|
+
import { emu, getEffectiveColorMap, getGroupChildren, getGroupTransform, getParagraphAlignment, getParagraphBullet, getParagraphBulletImageBytes, getParagraphBulletStyle, getParagraphElementLanguages, getParagraphIndent, getParagraphLevel, getParagraphPropertiesEffective, getParagraphSpacing, getPresentationFirstSlideNumber, getPresentationFonts, getPresentationTheme, getPresetGeometry, getShape3D, getShapeAdjustValues, getShapeAltTitle, getShapeBodyPrEffective, getShapeBounds, getShapeBoundsResolved, getShapeChartSpec, getShapeClickAction, getShapeCustomGeometry, getShapeDescription, getShapeEffectsEffective, getShapeFillColorResolved, getShapeFillEffective, getShapeFillOpacity, getShapeFlip, getShapeGradientFill, getShapeGradientFillEffective, getShapeHyperlinkTooltip, getShapeId, getShapeImageBiLevelThreshold, getShapeImageBrightness, getShapeImageBytes, getShapeImageContrast, getShapeImageCrop, getShapeImageDuotone, getShapeImageFillBytes, getShapeImageFillLayout, getShapeImageFormat, getShapeImageIntrinsicSize, getShapeImageLinkUrl, getShapeImageOpacity, getShapeImagePartName, getShapeKind, getShapeName, getShapeParagraphCount, getShapeParagraphElements, getShapePatternFill, getShapePlaceholderType, getShapePreset, getShapeRotation, getShapeRunClickAction, getShapeRunFormat, getShapeRunFormatEffective, getShapeRunHyperlink, getShapeRunHyperlinkTooltip, getShapeStrokeArrow, getShapeStrokeCap, getShapeStrokeColorResolved, getShapeStrokeCompound, getShapeStrokeDash, getShapeStrokeEffective, getShapeStrokeGradient, getShapeStrokeJoin, getShapeStrokeOpacity, getShapeStrokeSketch, getShapeText3D, getShapeTextAnchor, getShapeTextAutoFit, getShapeTextAutoFitParams, getShapeTextBodyRotationDeg, getShapeTextColumns, getShapeTextDirection, getShapeTextMargins, getShapeXmlString, getSlideBackground, getSlideBackgroundGradientFill, getSlideBackgroundImageBytes, getSlideBackgroundImageCrop, getSlideBackgroundImageFillLayout, getSlideBackgroundImageIntrinsicSize, getSlideBackgroundImageOpacity, getSlideBackgroundPatternFill, getSlideIndex, getSlideLayout, getSlideLayoutBackground, getSlideLayoutBackgroundGradientFill, getSlideLayoutBackgroundImageBytes, getSlideLayoutBackgroundPatternFill, getSlideLayoutShapes, getSlideMasterBackground, getSlideMasterBackgroundGradientFill, getSlideMasterBackgroundImageBytes, getSlideMasterBackgroundPatternFill, getSlideMasterShapes, getSlideShapes, getSlideSize, getSlides, getTableBackgroundEffective, getTableCellAnchor, getTableCellAppearanceEffective, getTableCellMargins, getTableCellParagraphs, getTableCellRunFormatEffective, getTableCellSpan, getTableCellText3D, getTableCellTextDirection, getTableCells, getTableColumnWidths, getTableDimensions, getTableRowHeights, isChartShape, isParagraphBulletPicture, isShapeHidden, isShapeImageGrayscale, isShapePlaceholder, isShapeTextBox, isSlideBackgroundGraphicsHidden, isSlideLayoutBackgroundGraphicsHidden, isTableShape, resolveDeckBodyTextColor } from "@office-kit/pptx";
|
|
2
2
|
//#region src/text-body-rect.ts
|
|
3
|
-
const presetTextRect = (preset) => {
|
|
4
|
-
switch (preset) {
|
|
5
|
-
case "triangle": return {
|
|
6
|
-
l: .25,
|
|
7
|
-
t: .5,
|
|
8
|
-
r: .75,
|
|
9
|
-
b: 1
|
|
10
|
-
};
|
|
11
|
-
case "diamond": return {
|
|
12
|
-
l: .25,
|
|
13
|
-
t: .25,
|
|
14
|
-
r: .75,
|
|
15
|
-
b: .75
|
|
16
|
-
};
|
|
17
|
-
case "pentagon": return {
|
|
18
|
-
l: .191,
|
|
19
|
-
t: .236,
|
|
20
|
-
r: .809,
|
|
21
|
-
b: 1
|
|
22
|
-
};
|
|
23
|
-
case "star5": return {
|
|
24
|
-
l: .309,
|
|
25
|
-
t: .382,
|
|
26
|
-
r: .691,
|
|
27
|
-
b: .764
|
|
28
|
-
};
|
|
29
|
-
case "leftRightArrow": return {
|
|
30
|
-
l: .18,
|
|
31
|
-
t: .35,
|
|
32
|
-
r: .82,
|
|
33
|
-
b: .65
|
|
34
|
-
};
|
|
35
|
-
default: return null;
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
3
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
4
|
+
* Where a shape lays out its text, as fractions of its own extent: the
|
|
5
|
+
* `<a:rect>` its geometry states, written in its `<a:custGeom>` or in
|
|
6
|
+
* ECMA-376's definition of its preset (an ellipse's inscribed rectangle, a
|
|
7
|
+
* triangle's lower middle, an arrow's shaft). `null` lays text into the whole
|
|
8
|
+
* box: a shape that inherits its geometry, or whose rectangle has no room.
|
|
9
|
+
*
|
|
10
|
+
* The rectangle is in the shape's own `<a:ext>` space, so dividing by that —
|
|
11
|
+
* not by on-screen bounds, which carry a group's or autofit's scale — is what
|
|
12
|
+
* lets the result travel with the shape.
|
|
44
13
|
*/
|
|
45
|
-
function
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
14
|
+
function shapeTextRect(shape) {
|
|
15
|
+
const extent = getShapeBounds(shape);
|
|
16
|
+
if (extent === null || extent.w <= 0 || extent.h <= 0) return null;
|
|
17
|
+
const preset = getShapePreset(shape);
|
|
18
|
+
const rect = (preset === null ? getShapeCustomGeometry(shape) : getPresetGeometry(preset, extent, getShapeAdjustValues(shape)))?.textRect;
|
|
19
|
+
if (!rect || rect.r <= rect.l || rect.b <= rect.t) return null;
|
|
48
20
|
return {
|
|
49
21
|
l: rect.l / extent.w,
|
|
50
22
|
t: rect.t / extent.h,
|
|
@@ -53,18 +25,13 @@ function shapeCustomTextRect(custom, extent) {
|
|
|
53
25
|
};
|
|
54
26
|
}
|
|
55
27
|
/**
|
|
56
|
-
* Text layout rectangle used by the preview
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* margins collapse a
|
|
60
|
-
*
|
|
61
|
-
* A custom-geometry shape states its own rectangle in `<a:custGeom><a:rect>`.
|
|
62
|
-
* Pass it as `custom`, as fractions of the shape's extent so that it scales
|
|
63
|
-
* with `bounds` the way a preset region does, and it wins: unlike the table
|
|
64
|
-
* above it is not an approximation of anything — it is what the file says.
|
|
28
|
+
* Text layout rectangle used by the preview: `region` (from
|
|
29
|
+
* {@link shapeTextRect}, or `null` for the whole box) placed in `bounds`, less
|
|
30
|
+
* the body insets. All coordinates and margins must use the same unit
|
|
31
|
+
* (normally EMU). When margins collapse a region, the region is kept without
|
|
32
|
+
* them, as the reference desktop app does.
|
|
65
33
|
*/
|
|
66
|
-
function resolveTextBodyRect(
|
|
67
|
-
const region = custom ?? presetTextRect(preset);
|
|
34
|
+
function resolveTextBodyRect(bounds, margins, region) {
|
|
68
35
|
const x = bounds.x + (region?.l ?? 0) * bounds.w;
|
|
69
36
|
const y = bounds.y + (region?.t ?? 0) * bounds.h;
|
|
70
37
|
const w = ((region?.r ?? 1) - (region?.l ?? 0)) * bounds.w;
|
|
@@ -86,17 +53,17 @@ function resolveTextBodyRect(preset, bounds, margins, custom) {
|
|
|
86
53
|
}
|
|
87
54
|
//#endregion
|
|
88
55
|
//#region src/text-body-style.ts
|
|
89
|
-
/** Mac
|
|
56
|
+
/** The reference desktop app on Mac uses zero spacing when `spcCol` is absent. */
|
|
90
57
|
const DEFAULT_COLUMN_GAP_PX = 0;
|
|
91
|
-
const EMU_PER_PX$
|
|
58
|
+
const EMU_PER_PX$3 = 9525;
|
|
92
59
|
const NONE = {
|
|
93
60
|
declarations: "",
|
|
94
61
|
transform: ""
|
|
95
62
|
};
|
|
96
63
|
/**
|
|
97
64
|
* `<a:bodyPr vert="…"/>` as CSS. `writing-mode` is the right primitive for
|
|
98
|
-
* the East-Asian and Mongolian cases, and `text-orientation` for the
|
|
99
|
-
* ones, which stack upright glyphs. `vert270` reads bottom-to-top, which no
|
|
65
|
+
* the East-Asian and Mongolian cases, and `text-orientation` for the
|
|
66
|
+
* `wordArtVert` ones, which stack upright glyphs. `vert270` reads bottom-to-top, which no
|
|
100
67
|
* writing-mode expresses on its own — hence the half turn. Its columns still
|
|
101
68
|
* follow the OOXML vertical-rl progression before that half turn; using
|
|
102
69
|
* vertical-lr here reverses the column order relative to the SVG renderer.
|
|
@@ -134,7 +101,7 @@ function verticalTextStyle(vert) {
|
|
|
134
101
|
*/
|
|
135
102
|
function textColumnsStyle(cols) {
|
|
136
103
|
if (!cols || cols.count < 2) return "";
|
|
137
|
-
const gapPx = cols.gapEmu !== void 0 ? (cols.gapEmu / EMU_PER_PX$
|
|
104
|
+
const gapPx = cols.gapEmu !== void 0 ? (cols.gapEmu / EMU_PER_PX$3).toFixed(2) : DEFAULT_COLUMN_GAP_PX;
|
|
138
105
|
return `column-count:${cols.count};column-gap:${gapPx}px`;
|
|
139
106
|
}
|
|
140
107
|
//#endregion
|
|
@@ -250,6 +217,30 @@ const paragraphNumberLabels = (paraData) => {
|
|
|
250
217
|
return numberLabels;
|
|
251
218
|
};
|
|
252
219
|
//#endregion
|
|
220
|
+
//#region src/decimal-separator.ts
|
|
221
|
+
const separators = /* @__PURE__ */ new Map();
|
|
222
|
+
/**
|
|
223
|
+
* The character a decimal tab stop aligns on for a run's language
|
|
224
|
+
* (`<a:rPr lang>`): `,` for `de-DE`, `.` for `en-US`. Runs without a
|
|
225
|
+
* language, or with one Intl does not know, align on `.`. The reference desktop app on Mac
|
|
226
|
+
* uses the run language too, not the UI or system locale (native capture
|
|
227
|
+
* 2026-10-07: Set Proofing Language to German moved alignment to `,`).
|
|
228
|
+
*/
|
|
229
|
+
function decimalSeparatorOf(lang) {
|
|
230
|
+
if (!lang) return ".";
|
|
231
|
+
let separator = separators.get(lang);
|
|
232
|
+
if (separator === void 0) {
|
|
233
|
+
separator = ".";
|
|
234
|
+
try {
|
|
235
|
+
separator = new Intl.NumberFormat(lang, { numberingSystem: "latn" }).formatToParts(1.5).find((part) => part.type === "decimal")?.value ?? ".";
|
|
236
|
+
} catch (error) {
|
|
237
|
+
if (!(error instanceof RangeError)) throw error;
|
|
238
|
+
}
|
|
239
|
+
separators.set(lang, separator);
|
|
240
|
+
}
|
|
241
|
+
return separator;
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
253
244
|
//#region src/emf.ts
|
|
254
245
|
const WORD_BYTES = 4;
|
|
255
246
|
const SHORT_BYTES = 2;
|
|
@@ -526,7 +517,7 @@ const FALLBACK_DESCENT = .22;
|
|
|
526
517
|
const FALLBACK_LINEGAP = .08;
|
|
527
518
|
const BASELINE_LEADING_DROP = .036;
|
|
528
519
|
const GRID_NUDGE_X = -.75;
|
|
529
|
-
const EMU_PER_PX$
|
|
520
|
+
const EMU_PER_PX$2 = 9525;
|
|
530
521
|
let reflectionNamespace = 0;
|
|
531
522
|
const EAST_ASIAN_CHAR = /[ᄀ-ᅟ⺀-〾ぁ-㏿㐀-䶿一-鿿ꀀ-가-힣豈-︰-﹏-⦆¢-₩]/;
|
|
532
523
|
const CLOSING_PUNCT = /^[、。,.・)」』】〉》”’!?:;ー〜…,.!?:;)\]}]+$/;
|
|
@@ -711,7 +702,7 @@ const layoutCore = (input, measure) => {
|
|
|
711
702
|
fieldWidth = decimalWidth = 0;
|
|
712
703
|
} else {
|
|
713
704
|
fieldWidth += token.width;
|
|
714
|
-
const decimal = token.text.indexOf(".");
|
|
705
|
+
const decimal = token.text.indexOf(token.piece.decimalSeparator ?? ".");
|
|
715
706
|
decimalWidth = decimal < 0 ? decimalWidth + token.width : mWidth(token.text.slice(0, decimal), {
|
|
716
707
|
...specOf(token.piece),
|
|
717
708
|
sizePx: renderedSizePxOf(token.piece)
|
|
@@ -869,7 +860,7 @@ const lineContentExtent = (line, dx) => {
|
|
|
869
860
|
};
|
|
870
861
|
};
|
|
871
862
|
const resolveFillPaints = (placements) => {
|
|
872
|
-
if (!placements.some(({ line }) => line.tokens.some((t) => t.piece.fillPaint))) return {
|
|
863
|
+
if (!placements.some(({ line }) => line.tokens.some((t) => t.piece.fillPaint || t.piece.outlinePaint))) return {
|
|
873
864
|
defs: "",
|
|
874
865
|
placements
|
|
875
866
|
};
|
|
@@ -897,12 +888,7 @@ const resolveFillPaints = (placements) => {
|
|
|
897
888
|
};
|
|
898
889
|
const painted = /* @__PURE__ */ new Map();
|
|
899
890
|
let defs = "";
|
|
900
|
-
const
|
|
901
|
-
const repaint = (piece) => {
|
|
902
|
-
const paint = piece.fillPaint;
|
|
903
|
-
if (paint === void 0) return piece;
|
|
904
|
-
let next = pieces.get(piece);
|
|
905
|
-
if (next) return next;
|
|
891
|
+
const resolve = (paint) => {
|
|
906
892
|
let fill = painted.get(paint);
|
|
907
893
|
if (fill === void 0) {
|
|
908
894
|
const built = paint(bounds);
|
|
@@ -910,9 +896,16 @@ const resolveFillPaints = (placements) => {
|
|
|
910
896
|
fill = built.fill;
|
|
911
897
|
painted.set(paint, fill);
|
|
912
898
|
}
|
|
899
|
+
return fill;
|
|
900
|
+
};
|
|
901
|
+
const pieces = /* @__PURE__ */ new Map();
|
|
902
|
+
const repaint = (piece) => {
|
|
903
|
+
let next = pieces.get(piece);
|
|
904
|
+
if (next) return next;
|
|
913
905
|
next = {
|
|
914
906
|
...piece,
|
|
915
|
-
fillHex:
|
|
907
|
+
...piece.fillPaint ? { fillHex: resolve(piece.fillPaint) } : {},
|
|
908
|
+
...piece.outlinePaint ? { outlineHex: resolve(piece.outlinePaint) } : {}
|
|
916
909
|
};
|
|
917
910
|
pieces.set(piece, next);
|
|
918
911
|
return next;
|
|
@@ -921,7 +914,7 @@ const resolveFillPaints = (placements) => {
|
|
|
921
914
|
...placement,
|
|
922
915
|
line: {
|
|
923
916
|
...placement.line,
|
|
924
|
-
tokens: placement.line.tokens.map((token) => token.piece.fillPaint ? {
|
|
917
|
+
tokens: placement.line.tokens.map((token) => token.piece.fillPaint || token.piece.outlinePaint ? {
|
|
925
918
|
...token,
|
|
926
919
|
piece: repaint(token.piece)
|
|
927
920
|
} : token)
|
|
@@ -1069,8 +1062,9 @@ const emitLine = (line, baselineY, dx, descent, nextEffectId, effectsOnly, effec
|
|
|
1069
1062
|
const reflections = effectKind === "reflection" || effectKind === "all" ? emitTextReflections(groups, line.textAnchor, x0, baselineY, descent, nextEffectId) : "";
|
|
1070
1063
|
const outerEffects = effectKind === "outer" || effectKind === "all" ? emitTextOuterEffects(groups, line.textAnchor, x0, baselineY, nextEffectId) : "";
|
|
1071
1064
|
const innerShadows = effectKind === "innerShadow" || effectKind === "all" ? emitTextInnerShadows(groups, line.textAnchor, x0, baselineY, nextEffectId) : "";
|
|
1072
|
-
|
|
1073
|
-
|
|
1065
|
+
const bevels = effectKind === "bevel" || effectKind === "all" ? emitTextBevel(groups, line.textAnchor, x0, baselineY, nextEffectId) : "";
|
|
1066
|
+
if (effectsOnly) return outerEffects + reflections + bevels + innerShadows;
|
|
1067
|
+
return emitHighlights(groups, line.textAnchor, x0, baselineY) + outerEffects + reflections + text + bevels + innerShadows + emitTextDecorations(groups, line.textAnchor, x0, baselineY);
|
|
1074
1068
|
};
|
|
1075
1069
|
const unpaintedPiece = (piece) => {
|
|
1076
1070
|
const { outlineHex: _outline, shadow: _shadow, glow: _glow, ...rest } = piece;
|
|
@@ -1118,7 +1112,7 @@ const emitTextReflections = (groups, textAnchor, x0, baselineY, descent, nextEff
|
|
|
1118
1112
|
continue;
|
|
1119
1113
|
}
|
|
1120
1114
|
const scaleY = reflection.scaleY ?? 1;
|
|
1121
|
-
const distPx = (reflection.offsetEmu ?? 0) / EMU_PER_PX$
|
|
1115
|
+
const distPx = (reflection.offsetEmu ?? 0) / EMU_PER_PX$2;
|
|
1122
1116
|
const contactY = baselineY + descent;
|
|
1123
1117
|
const angleRad = (reflection.angleDeg ?? 0) * Math.PI / 180;
|
|
1124
1118
|
const offsetX = distPx * Math.cos(angleRad);
|
|
@@ -1131,7 +1125,7 @@ const emitTextReflections = (groups, textAnchor, x0, baselineY, descent, nextEff
|
|
|
1131
1125
|
const gradientId = `${id}-gradient`;
|
|
1132
1126
|
const maskId = `${id}-mask`;
|
|
1133
1127
|
const filterId = `${id}-blur`;
|
|
1134
|
-
const blurPx = Math.max(0, (reflection.blurEmu ?? 0) / EMU_PER_PX$
|
|
1128
|
+
const blurPx = Math.max(0, (reflection.blurEmu ?? 0) / EMU_PER_PX$2 / 2);
|
|
1135
1129
|
const fadeDirection = reflection.fadeDirection;
|
|
1136
1130
|
const defs = `<defs><linearGradient id="${gradientId}" ${fadeDirection === void 0 || fadeDirection === 90 ? "x1=\"0\" y1=\"1\" x2=\"0\" y2=\"0\"" : (() => {
|
|
1137
1131
|
const radians = fadeDirection * Math.PI / 180;
|
|
@@ -1167,8 +1161,8 @@ const emitTextOuterEffects = (groups, textAnchor, x0, baselineY, nextId) => {
|
|
|
1167
1161
|
if (shadow) {
|
|
1168
1162
|
const id = nextId("outer-shadow");
|
|
1169
1163
|
const angle = (shadow.angleDeg ?? 45) * Math.PI / 180;
|
|
1170
|
-
const distance = (shadow.offsetEmu ?? 38100) / EMU_PER_PX$
|
|
1171
|
-
const blur = Math.max(0, (shadow.blurEmu ?? 50800) / EMU_PER_PX$
|
|
1164
|
+
const distance = (shadow.offsetEmu ?? 38100) / EMU_PER_PX$2;
|
|
1165
|
+
const blur = Math.max(0, (shadow.blurEmu ?? 50800) / EMU_PER_PX$2 / 2);
|
|
1172
1166
|
const glyphSize = renderedSizePxOf(group.piece);
|
|
1173
1167
|
const pad = Math.max(1, distance + blur * 3);
|
|
1174
1168
|
const color = shadow.color ?? "#000000";
|
|
@@ -1178,7 +1172,7 @@ const emitTextOuterEffects = (groups, textAnchor, x0, baselineY, nextId) => {
|
|
|
1178
1172
|
}
|
|
1179
1173
|
if (glow) {
|
|
1180
1174
|
const id = nextId("glow");
|
|
1181
|
-
const radius = Math.max(0, (glow.radiusEmu ?? 63500) / EMU_PER_PX$
|
|
1175
|
+
const radius = Math.max(0, (glow.radiusEmu ?? 63500) / EMU_PER_PX$2);
|
|
1182
1176
|
const glyphSize = renderedSizePxOf(group.piece);
|
|
1183
1177
|
const pad = Math.max(1, radius * 2);
|
|
1184
1178
|
const color = glow.color ?? "#FFFF00";
|
|
@@ -1202,9 +1196,9 @@ const emitTextInnerShadows = (groups, textAnchor, x0, baselineY, nextId) => {
|
|
|
1202
1196
|
}
|
|
1203
1197
|
const id = nextId("inner-shadow");
|
|
1204
1198
|
const angle = (shadow.angleDeg ?? 45) * Math.PI / 180;
|
|
1205
|
-
const dx = (shadow.offsetEmu ?? 38100) / EMU_PER_PX$
|
|
1206
|
-
const dy = (shadow.offsetEmu ?? 38100) / EMU_PER_PX$
|
|
1207
|
-
const blurPx = Math.max(0, (shadow.blurEmu ?? 50800) / EMU_PER_PX$
|
|
1199
|
+
const dx = (shadow.offsetEmu ?? 38100) / EMU_PER_PX$2 * Math.cos(angle);
|
|
1200
|
+
const dy = (shadow.offsetEmu ?? 38100) / EMU_PER_PX$2 * Math.sin(angle);
|
|
1201
|
+
const blurPx = Math.max(0, (shadow.blurEmu ?? 50800) / EMU_PER_PX$2 / 2);
|
|
1208
1202
|
const color = shadow.color ?? "#000000";
|
|
1209
1203
|
const opacity = Math.max(0, Math.min(1, shadow.opacity ?? 1));
|
|
1210
1204
|
const defs = `<defs><filter id="${id}" x="-25%" y="-25%" width="150%" height="150%"><feGaussianBlur in="SourceAlpha" stdDeviation="${fmt(blurPx)}" result="innerBlur"/><feOffset in="innerBlur" dx="${fmt(dx)}" dy="${fmt(dy)}" result="innerOff"/><feComposite in="innerOff" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="innerMask"/><feFlood flood-color="${escapeXml$1(color)}" flood-opacity="${opacity.toFixed(3)}" result="innerColor"/><feComposite in="innerColor" in2="innerMask" operator="in" result="innerOut"/><feComposite in="innerOut" in2="SourceAlpha" operator="in"/></filter></defs>`;
|
|
@@ -1214,6 +1208,25 @@ const emitTextInnerShadows = (groups, textAnchor, x0, baselineY, nextId) => {
|
|
|
1214
1208
|
}
|
|
1215
1209
|
return parts.join("");
|
|
1216
1210
|
};
|
|
1211
|
+
const emitTextBevel = (groups, textAnchor, x0, baselineY, nextId) => {
|
|
1212
|
+
const bevel = groups.find((g) => g.piece.bevel && !g.isTab && g.width > 0)?.piece.bevel;
|
|
1213
|
+
if (!bevel) return "";
|
|
1214
|
+
const id = nextId("bevel");
|
|
1215
|
+
const widthPx = bevel.widthEmu / EMU_PER_PX$2;
|
|
1216
|
+
const surfaceScale = bevel.heightEmu / EMU_PER_PX$2 * bevel.relief;
|
|
1217
|
+
const table = [...bevel.profile.slice(1).map(() => 0), ...bevel.profile];
|
|
1218
|
+
const flat = Math.sin(bevel.elevationDeg * Math.PI / 180);
|
|
1219
|
+
const lightGain = bevel.contrast / (1 - flat);
|
|
1220
|
+
const shadeGain = bevel.contrast / flat;
|
|
1221
|
+
const light = `<feDistantLight azimuth="${fmt(bevel.azimuthDeg)}" elevation="${fmt(bevel.elevationDeg)}"/>`;
|
|
1222
|
+
const specular = bevel.specular ? `<feSpecularLighting in="bevelHeight" surfaceScale="${fmt(surfaceScale)}" specularConstant="${fmt(bevel.specular.constant)}" specularExponent="${fmt(bevel.specular.exponent)}" lighting-color="#fff" result="bevelSpecular">${light}</feSpecularLighting>` : "";
|
|
1223
|
+
const defs = `<defs><filter id="${id}" x="-25%" y="-25%" width="150%" height="150%" color-interpolation-filters="sRGB" data-pptx-bevel="1"><feGaussianBlur in="SourceAlpha" stdDeviation="${fmt(widthPx / 2)}" result="bevelBlur"/><feComponentTransfer in="bevelBlur" result="bevelHeight"><feFuncA type="table" tableValues="${table.map(fmt).join(" ")}"/></feComponentTransfer><feDiffuseLighting in="bevelHeight" surfaceScale="${fmt(surfaceScale)}" diffuseConstant="1" lighting-color="#fff" result="bevelDiffuse">${light}</feDiffuseLighting><feColorMatrix in="bevelDiffuse" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ${fmt(lightGain)} 0 0 0 ${fmt(-lightGain * flat)}" result="bevelLight"/><feColorMatrix in="bevelDiffuse" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ${fmt(-shadeGain)} 0 0 0 ${fmt(shadeGain * flat)}" result="bevelShade"/>` + specular + `<feMerge result="bevelMerged"><feMergeNode in="bevelShade"/><feMergeNode in="bevelLight"/>${specular ? "<feMergeNode in=\"bevelSpecular\"/>" : ""}</feMerge><feComposite in="bevelMerged" in2="SourceAlpha" operator="in"/></filter></defs>`;
|
|
1224
|
+
const beveled = groups.map((g) => g.piece.bevel && !g.isTab ? g : {
|
|
1225
|
+
...g,
|
|
1226
|
+
piece: unpaintedPiece(g.piece)
|
|
1227
|
+
});
|
|
1228
|
+
return `${defs}<text x="${fmt(x0)}" y="${fmt(baselineY)}" text-anchor="${textAnchor}" xml:space="preserve" filter="url(#${id})" aria-hidden="true" pointer-events="none" data-pptx-bevel="text">${beveled.map(tspan).join("")}</text>`;
|
|
1229
|
+
};
|
|
1217
1230
|
const baselineShiftPxOf = (p) => p.sizePx * p.baseline;
|
|
1218
1231
|
const SUPER_SUB_SIZE_RATIO = .65;
|
|
1219
1232
|
const SMALL_CAPS_LOWERCASE_RATIO = .8;
|
|
@@ -1473,6 +1486,206 @@ function browserTextMeasurer() {
|
|
|
1473
1486
|
};
|
|
1474
1487
|
}
|
|
1475
1488
|
//#endregion
|
|
1489
|
+
//#region src/text-bevel.ts
|
|
1490
|
+
const DEFAULT_BEVEL_EMU$1 = 76200;
|
|
1491
|
+
const DEFAULT_PRESET = "circle";
|
|
1492
|
+
const DEFAULT_RIG = {
|
|
1493
|
+
type: "threePt",
|
|
1494
|
+
direction: "t"
|
|
1495
|
+
};
|
|
1496
|
+
const PROFILE_SAMPLES = 9;
|
|
1497
|
+
const PROFILES = {
|
|
1498
|
+
circle: (t) => Math.sqrt(1 - (1 - t) ** 2),
|
|
1499
|
+
relaxedInset: (t) => Math.sin(t * Math.PI / 2) ** 2,
|
|
1500
|
+
slope: (t) => t,
|
|
1501
|
+
angle: (t) => t,
|
|
1502
|
+
softRound: (t) => t * t * (3 - 2 * t),
|
|
1503
|
+
convex: (t) => Math.sqrt(Math.sqrt(1 - (1 - t) ** 2)),
|
|
1504
|
+
coolSlant: (t) => Math.min(1, t * 1.6),
|
|
1505
|
+
hardEdge: (t) => Math.min(1, t * 3),
|
|
1506
|
+
cross: (t) => t < .5 ? t * 1.6 : .8 + (t - .5) * .4,
|
|
1507
|
+
divot: (t) => t < .35 ? t / .35 : 1 - .55 * Math.sin((t - .35) / .65 * Math.PI),
|
|
1508
|
+
riblet: (t) => t * .7 + .3 * Math.abs(Math.sin(t * 2.5 * Math.PI)),
|
|
1509
|
+
artDeco: (t) => Math.min(1, Math.floor(t * 3 + .5) / 3 + (t * 3 - Math.floor(t * 3)) * .12)
|
|
1510
|
+
};
|
|
1511
|
+
const DIRECTION_AZIMUTH = {
|
|
1512
|
+
r: 0,
|
|
1513
|
+
br: 45,
|
|
1514
|
+
b: 90,
|
|
1515
|
+
bl: 135,
|
|
1516
|
+
l: 180,
|
|
1517
|
+
tl: 225,
|
|
1518
|
+
t: 270,
|
|
1519
|
+
tr: 315
|
|
1520
|
+
};
|
|
1521
|
+
const RIG_LOOK = (type) => {
|
|
1522
|
+
if (type === "flat" || type.startsWith("legacyFlat")) return null;
|
|
1523
|
+
if (type === "harsh" || type.startsWith("legacyHarsh") || type === "contrasting") return {
|
|
1524
|
+
elevationDeg: 30,
|
|
1525
|
+
contrast: .65
|
|
1526
|
+
};
|
|
1527
|
+
if (type === "soft" || type === "flood" || type === "brightRoom" || type === "glow") return {
|
|
1528
|
+
elevationDeg: 45,
|
|
1529
|
+
contrast: .55
|
|
1530
|
+
};
|
|
1531
|
+
return {
|
|
1532
|
+
elevationDeg: 38,
|
|
1533
|
+
contrast: .65
|
|
1534
|
+
};
|
|
1535
|
+
};
|
|
1536
|
+
const MATTE = {
|
|
1537
|
+
contrastScale: 1,
|
|
1538
|
+
specular: null
|
|
1539
|
+
};
|
|
1540
|
+
const MATERIAL_LOOK = {
|
|
1541
|
+
plastic: {
|
|
1542
|
+
contrastScale: 1,
|
|
1543
|
+
specular: {
|
|
1544
|
+
constant: .6,
|
|
1545
|
+
exponent: 20
|
|
1546
|
+
}
|
|
1547
|
+
},
|
|
1548
|
+
legacyPlastic: {
|
|
1549
|
+
contrastScale: 1,
|
|
1550
|
+
specular: {
|
|
1551
|
+
constant: .6,
|
|
1552
|
+
exponent: 20
|
|
1553
|
+
}
|
|
1554
|
+
},
|
|
1555
|
+
metal: {
|
|
1556
|
+
contrastScale: 1.2,
|
|
1557
|
+
specular: {
|
|
1558
|
+
constant: .9,
|
|
1559
|
+
exponent: 12
|
|
1560
|
+
}
|
|
1561
|
+
},
|
|
1562
|
+
legacyMetal: {
|
|
1563
|
+
contrastScale: 1.2,
|
|
1564
|
+
specular: {
|
|
1565
|
+
constant: .9,
|
|
1566
|
+
exponent: 12
|
|
1567
|
+
}
|
|
1568
|
+
},
|
|
1569
|
+
softmetal: {
|
|
1570
|
+
contrastScale: 1.1,
|
|
1571
|
+
specular: {
|
|
1572
|
+
constant: .6,
|
|
1573
|
+
exponent: 8
|
|
1574
|
+
}
|
|
1575
|
+
},
|
|
1576
|
+
clear: {
|
|
1577
|
+
contrastScale: .9,
|
|
1578
|
+
specular: {
|
|
1579
|
+
constant: .8,
|
|
1580
|
+
exponent: 30
|
|
1581
|
+
}
|
|
1582
|
+
},
|
|
1583
|
+
softEdge: {
|
|
1584
|
+
contrastScale: .9,
|
|
1585
|
+
specular: {
|
|
1586
|
+
constant: .25,
|
|
1587
|
+
exponent: 10
|
|
1588
|
+
}
|
|
1589
|
+
},
|
|
1590
|
+
powder: {
|
|
1591
|
+
contrastScale: .8,
|
|
1592
|
+
specular: null
|
|
1593
|
+
},
|
|
1594
|
+
translucentPowder: {
|
|
1595
|
+
contrastScale: .7,
|
|
1596
|
+
specular: null
|
|
1597
|
+
},
|
|
1598
|
+
flat: {
|
|
1599
|
+
contrastScale: 0,
|
|
1600
|
+
specular: null
|
|
1601
|
+
}
|
|
1602
|
+
};
|
|
1603
|
+
const RELIEF = 2.5;
|
|
1604
|
+
/**
|
|
1605
|
+
* The bevel to shade a text body with, or `null` when it has no top bevel or
|
|
1606
|
+
* its rig/material renders it unshaded.
|
|
1607
|
+
*/
|
|
1608
|
+
const textBevelOf = (text3d) => {
|
|
1609
|
+
const bevel = text3d?.bevelTop;
|
|
1610
|
+
if (!bevel) return null;
|
|
1611
|
+
const widthEmu = bevel.widthEmu ?? DEFAULT_BEVEL_EMU$1;
|
|
1612
|
+
const heightEmu = bevel.heightEmu ?? DEFAULT_BEVEL_EMU$1;
|
|
1613
|
+
if (widthEmu <= 0 || heightEmu <= 0) return null;
|
|
1614
|
+
const rig = text3d.scene?.lightRig ?? DEFAULT_RIG;
|
|
1615
|
+
const look = RIG_LOOK(rig.type);
|
|
1616
|
+
const material = (text3d.material && MATERIAL_LOOK[text3d.material]) ?? MATTE;
|
|
1617
|
+
if (!look || material.contrastScale === 0) return null;
|
|
1618
|
+
const profile = PROFILES[bevel.preset ?? DEFAULT_PRESET];
|
|
1619
|
+
const azimuthDeg = (DIRECTION_AZIMUTH[rig.direction] + (rig.rotation?.revolutionDeg ?? 0)) % 360;
|
|
1620
|
+
return {
|
|
1621
|
+
widthEmu,
|
|
1622
|
+
heightEmu,
|
|
1623
|
+
profile: Array.from({ length: PROFILE_SAMPLES }, (_, i) => Math.max(0, Math.min(1, profile(i / (PROFILE_SAMPLES - 1))))),
|
|
1624
|
+
azimuthDeg,
|
|
1625
|
+
elevationDeg: look.elevationDeg,
|
|
1626
|
+
contrast: Math.min(1, look.contrast * material.contrastScale),
|
|
1627
|
+
relief: RELIEF,
|
|
1628
|
+
specular: material.specular
|
|
1629
|
+
};
|
|
1630
|
+
};
|
|
1631
|
+
//#endregion
|
|
1632
|
+
//#region src/shape-3d.ts
|
|
1633
|
+
const EMU_PER_PX$1 = 9525;
|
|
1634
|
+
const DEFAULT_BEVEL_EMU = 76200;
|
|
1635
|
+
const LIGHT_AZIMUTH_DEG = 225;
|
|
1636
|
+
const LIGHT_ELEVATION_DEG = 45;
|
|
1637
|
+
const radians = (degrees) => degrees * Math.PI / 180;
|
|
1638
|
+
/**
|
|
1639
|
+
* An SVG `matrix(...)` for the camera's explicit rotation about the point
|
|
1640
|
+
* (`cx`, `cy`) in px, or `null` when the camera keeps the shape face-on.
|
|
1641
|
+
* The camera turns, so the shape appears turned the opposite way: a camera
|
|
1642
|
+
* revolution of +6° (Picture Style "Rotated, White") tilts the picture 6°
|
|
1643
|
+
* counter-clockwise.
|
|
1644
|
+
*/
|
|
1645
|
+
const cameraTransform = (shape3d, cx, cy) => {
|
|
1646
|
+
const rotation = shape3d?.scene?.cameraRotation;
|
|
1647
|
+
if (!rotation) return null;
|
|
1648
|
+
const { latitudeDeg, longitudeDeg, revolutionDeg } = rotation;
|
|
1649
|
+
if (latitudeDeg === 0 && longitudeDeg === 0 && revolutionDeg === 0) return null;
|
|
1650
|
+
const lon = radians(-longitudeDeg);
|
|
1651
|
+
const lat = radians(-latitudeDeg);
|
|
1652
|
+
const rev = radians(-revolutionDeg);
|
|
1653
|
+
const ex = [Math.cos(lon), Math.sin(lon) * Math.sin(lat)];
|
|
1654
|
+
const ey = [0, Math.cos(lat)];
|
|
1655
|
+
const cos = Math.cos(rev);
|
|
1656
|
+
const sin = Math.sin(rev);
|
|
1657
|
+
const turn = (v) => [cos * v[0] - sin * v[1], sin * v[0] + cos * v[1]];
|
|
1658
|
+
const [a, b] = turn(ex);
|
|
1659
|
+
const [c, d] = turn(ey);
|
|
1660
|
+
return `matrix(${[
|
|
1661
|
+
a,
|
|
1662
|
+
b,
|
|
1663
|
+
c,
|
|
1664
|
+
d,
|
|
1665
|
+
cx - a * cx - c * cy,
|
|
1666
|
+
cy - b * cx - d * cy
|
|
1667
|
+
].map((n) => n.toFixed(6)).join(" ")})`;
|
|
1668
|
+
};
|
|
1669
|
+
/**
|
|
1670
|
+
* The `<filter>` body that shades a top bevel onto whatever the shape painted
|
|
1671
|
+
* (picture, fill and border alike): a lit height map built from the blurred
|
|
1672
|
+
* outline, multiplied in so flat areas keep their color and slopes facing
|
|
1673
|
+
* away from the light darken, plus a specular highlight on the lit slopes.
|
|
1674
|
+
* `null` when the shape has no top bevel.
|
|
1675
|
+
*/
|
|
1676
|
+
const bevelFilterPrimitives = (shape3d) => {
|
|
1677
|
+
const bevel = shape3d?.bevelTop;
|
|
1678
|
+
if (!bevel) return null;
|
|
1679
|
+
const widthPx = (bevel.widthEmu ?? DEFAULT_BEVEL_EMU) / EMU_PER_PX$1;
|
|
1680
|
+
const heightPx = (bevel.heightEmu ?? DEFAULT_BEVEL_EMU) / EMU_PER_PX$1;
|
|
1681
|
+
if (widthPx <= 0 || heightPx <= 0) return null;
|
|
1682
|
+
const blur = widthPx / 2;
|
|
1683
|
+
const surfaceScale = Math.min(10, Math.max(1, heightPx / widthPx * 6));
|
|
1684
|
+
const diffuse = 1 / Math.sin(radians(LIGHT_ELEVATION_DEG));
|
|
1685
|
+
const light = `<feDistantLight azimuth="${LIGHT_AZIMUTH_DEG}" elevation="${LIGHT_ELEVATION_DEG}"/>`;
|
|
1686
|
+
return `<feGaussianBlur in="SourceAlpha" stdDeviation="${blur.toFixed(2)}" result="bevelHeight"/><feDiffuseLighting in="bevelHeight" surfaceScale="${surfaceScale.toFixed(2)}" diffuseConstant="${diffuse.toFixed(4)}" lighting-color="#fff" result="bevelShade">${light}</feDiffuseLighting><feComposite in="SourceGraphic" in2="bevelShade" operator="arithmetic" k1="1" result="bevelLit"/><feSpecularLighting in="bevelHeight" surfaceScale="${surfaceScale.toFixed(2)}" specularConstant="0.6" specularExponent="20" lighting-color="#fff" result="bevelSpec">${light}</feSpecularLighting><feComposite in="bevelSpec" in2="SourceAlpha" operator="in" result="bevelGloss"/><feComposite in="bevelLit" in2="bevelGloss" operator="arithmetic" k2="1" k3="1"/>`;
|
|
1687
|
+
};
|
|
1688
|
+
//#endregion
|
|
1476
1689
|
//#region src/render-slide.ts
|
|
1477
1690
|
const clickActionHref = (pres, action) => {
|
|
1478
1691
|
if (!action) return void 0;
|
|
@@ -1619,20 +1832,64 @@ const renderPicture = (shape, pres, x, y, w, h, transform, textOverlay, bytes, f
|
|
|
1619
1832
|
}
|
|
1620
1833
|
const opacityAttr = opacity !== 1 ? ` opacity="${opacity.toFixed(3)}"` : "";
|
|
1621
1834
|
const border = outline.stroke !== "none" && outline.strokeWidth > 0 ? `<g${transform} fill="none" stroke="${outline.stroke}" stroke-width="${E(outline.strokeWidth)}"${outline.strokeAttrs ? ` ${outline.strokeAttrs}` : ""}>${pictureClipGeometry(shape, preset, x, y, w, h)}</g>` : "";
|
|
1835
|
+
const under = outline.fill !== "none" ? `${outline.defs}<g${transform} fill="${outline.fill}"${outline.fillAttrs}>${pictureClipGeometry(shape, preset, x, y, w, h)}</g>` : "";
|
|
1622
1836
|
if (layout?.mode === "tile") {
|
|
1623
1837
|
const intrinsic = getShapeImageIntrinsicSize(shape);
|
|
1624
1838
|
if (intrinsic) {
|
|
1625
1839
|
const pattern = imageTilePattern(dataUrl, layout, intrinsic, x, y, w, h, cropL, cropT, cropR, cropB);
|
|
1626
1840
|
const geometry = pictureClipGeometry(shape, preset, x, y, w, h);
|
|
1627
|
-
return `${clipDef}${pattern.defs}
|
|
1841
|
+
return `${clipDef}${pattern.defs}${pictureEffects(pres, shape, {
|
|
1842
|
+
x,
|
|
1843
|
+
y,
|
|
1844
|
+
w,
|
|
1845
|
+
h
|
|
1846
|
+
}, `${under}<g${transform} fill="${pattern.fill}"${filterAttr}${opacityAttr}>${geometry}</g>${border}`)}<g${transform}>${textOverlay}</g>`;
|
|
1628
1847
|
}
|
|
1629
1848
|
}
|
|
1630
|
-
return `${clipDef}
|
|
1849
|
+
return `${clipDef}${pictureEffects(pres, shape, {
|
|
1850
|
+
x,
|
|
1851
|
+
y,
|
|
1852
|
+
w,
|
|
1853
|
+
h
|
|
1854
|
+
}, `${under}<g${transform}${clipAttr}><image x="${E(imgX)}" y="${E(imgY)}" width="${E(imgW)}" height="${E(imgH)}" href="${dataUrl}" xlink:href="${dataUrl}" preserveAspectRatio="none"${filterAttr}${opacityAttr}/></g>${border}`)}<g${transform}>${textOverlay}</g>`;
|
|
1631
1855
|
}
|
|
1632
1856
|
const linkUrl = getShapeImageLinkUrl(shape);
|
|
1633
1857
|
const label = !bytes ? linkUrl ? `picture (link: ${linkUrl.length > 48 ? linkUrl.slice(0, 45) + "…" : linkUrl})` : "picture (no bytes)" : `picture (${format ?? "unknown"}${bytes ? `, ${bytes.byteLength} B` : ""})`;
|
|
1634
1858
|
return `<g data-pptx-fallback="image"${transform}><rect x="${E(x)}" y="${E(y)}" width="${E(w)}" height="${E(h)}" fill="#F3F4F6" stroke="#9CA3AF" stroke-width="${E(9525)}" stroke-dasharray="${E(5e4)},${E(3e4)}"/>${renderPicturePlaceholderLabel(x, y, w, h, label)}${textOverlay}</g>`;
|
|
1635
1859
|
};
|
|
1860
|
+
/**
|
|
1861
|
+
* Wraps a picture's markup in its 3-D approximation (bevel lighting, then the
|
|
1862
|
+
* camera rotation) and its `<a:effectLst>` (shadows, glow, soft edge and the
|
|
1863
|
+
* reflection), the same effects a shape gets.
|
|
1864
|
+
*/
|
|
1865
|
+
const pictureEffects = (pres, shape, box, markup) => {
|
|
1866
|
+
const shape3d = getShape3D(shape);
|
|
1867
|
+
let defs = "";
|
|
1868
|
+
let content = markup;
|
|
1869
|
+
let mirrored = markup;
|
|
1870
|
+
const bevel = bevelFilterPrimitives(shape3d);
|
|
1871
|
+
if (bevel) {
|
|
1872
|
+
const id = mintId();
|
|
1873
|
+
defs += `<defs><filter id="${id}" x="-10%" y="-10%" width="120%" height="120%" color-interpolation-filters="sRGB">${bevel}</filter></defs>`;
|
|
1874
|
+
content = `<g filter="url(#${id})">${content}</g>`;
|
|
1875
|
+
}
|
|
1876
|
+
const camera = cameraTransform(shape3d, (box.x + box.w / 2) / EMU_PER_PX, (box.y + box.h / 2) / EMU_PER_PX);
|
|
1877
|
+
if (camera) {
|
|
1878
|
+
content = `<g transform="${camera}">${content}</g>`;
|
|
1879
|
+
mirrored = `<g transform="${camera}">${mirrored}</g>`;
|
|
1880
|
+
}
|
|
1881
|
+
const reflection = buildReflection(pres, shape, mirrored, box);
|
|
1882
|
+
const fx = buildEffectsFilter(pres, shape);
|
|
1883
|
+
if (fx) {
|
|
1884
|
+
defs += fx.defs;
|
|
1885
|
+
content = `<g filter="url(#${fx.id})">${content}</g>`;
|
|
1886
|
+
}
|
|
1887
|
+
if (reflection) {
|
|
1888
|
+
defs += reflection.defs;
|
|
1889
|
+
content = reflection.svg + content;
|
|
1890
|
+
}
|
|
1891
|
+
return defs + content;
|
|
1892
|
+
};
|
|
1636
1893
|
const imageTilePattern = (dataUrl, layout, intrinsic, x, y, w, h, cropL = 0, cropT = 0, cropR = 0, cropB = 0) => {
|
|
1637
1894
|
const sourceW = intrinsic.width * (layout.scaleX ?? 1);
|
|
1638
1895
|
const sourceH = intrinsic.height * (layout.scaleY ?? 1);
|
|
@@ -1677,15 +1934,11 @@ const imageTilePattern = (dataUrl, layout, intrinsic, x, y, w, h, cropL = 0, cro
|
|
|
1677
1934
|
};
|
|
1678
1935
|
};
|
|
1679
1936
|
const pictureClipGeometry = (shape, preset, x, y, w, h) => {
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
}
|
|
1685
|
-
const path = PRESET_PATHS[preset];
|
|
1686
|
-
if (path) return `<path d="${path(x / EMU_PER_PX, y / EMU_PER_PX, w / EMU_PER_PX, h / EMU_PER_PX)}" clip-rule="evenodd"/>`;
|
|
1687
|
-
const points = PRESET_POINTS[preset];
|
|
1688
|
-
if (points) return `<polygon points="${points(w / EMU_PER_PX, h / EMU_PER_PX).map(([nx, ny]) => `${E(x + nx * w)},${E(y + ny * h)}`).join(" ")}"/>`;
|
|
1937
|
+
const d = ((preset === "rect" ? null : getPresetGeometry(preset, {
|
|
1938
|
+
w: emu(w),
|
|
1939
|
+
h: emu(h)
|
|
1940
|
+
}, getShapeAdjustValues(shape)))?.paths ?? []).filter((path) => path.fill !== "none").map((path) => geometryPathData(path, x, y, w, h)).filter((data) => data !== "").join(" ");
|
|
1941
|
+
if (d !== "") return `<path d="${d}" clip-rule="evenodd"/>`;
|
|
1689
1942
|
return `<rect x="${E(x)}" y="${E(y)}" width="${E(w)}" height="${E(h)}"/>`;
|
|
1690
1943
|
};
|
|
1691
1944
|
const renderPicturePlaceholderLabel = (x, y, w, h, text) => {
|
|
@@ -1938,7 +2191,22 @@ const patternDef = (pat) => {
|
|
|
1938
2191
|
fillAttr: `url(#${id})`
|
|
1939
2192
|
};
|
|
1940
2193
|
};
|
|
1941
|
-
const textFillPaint = (fill, theme) => (box) => {
|
|
2194
|
+
const textFillPaint = (fill, theme, solid) => (box) => {
|
|
2195
|
+
if (fill.kind === "none") return {
|
|
2196
|
+
defs: "",
|
|
2197
|
+
fill: "none"
|
|
2198
|
+
};
|
|
2199
|
+
if (fill.kind === "image") {
|
|
2200
|
+
if (!fill.bytes) return {
|
|
2201
|
+
defs: "",
|
|
2202
|
+
fill: solid
|
|
2203
|
+
};
|
|
2204
|
+
const id = mintId();
|
|
2205
|
+
return {
|
|
2206
|
+
defs: `<defs><pattern id="${id}" patternUnits="userSpaceOnUse" x="${box.x.toFixed(2)}" y="${box.y.toFixed(2)}" width="${box.w.toFixed(2)}" height="${box.h.toFixed(2)}"><image href="${bytesToDataUrl(fill.bytes)}" width="${box.w.toFixed(2)}" height="${box.h.toFixed(2)}" preserveAspectRatio="none"/></pattern></defs>`,
|
|
2207
|
+
fill: `url(#${id})`
|
|
2208
|
+
};
|
|
2209
|
+
}
|
|
1942
2210
|
if (fill.kind === "pattern") {
|
|
1943
2211
|
const built = patternDef({
|
|
1944
2212
|
preset: fill.preset,
|
|
@@ -1996,6 +2264,32 @@ const buildArrowMarker = (type, width, length, color, orient) => {
|
|
|
1996
2264
|
def: `<defs><marker id="${id}" viewBox="0 0 ${w} ${h}" refX="${w}" refY="${h / 2}" markerWidth="${w}" markerHeight="${h}" orient="${orient}">${body}</marker></defs>`
|
|
1997
2265
|
};
|
|
1998
2266
|
};
|
|
2267
|
+
const unrotatedGradientTransform = (grad, shape, pres) => {
|
|
2268
|
+
const bounds = shape && (pres ? getShapeBoundsResolved(pres, shape) : getShapeBounds(shape));
|
|
2269
|
+
if (grad.rotateWithShape !== false || !shape || !bounds || bounds.w <= 0 || bounds.h <= 0) return "";
|
|
2270
|
+
const angle = getShapeRotation(shape) * Math.PI / 180;
|
|
2271
|
+
const cos = Math.cos(angle);
|
|
2272
|
+
const sin = Math.sin(angle);
|
|
2273
|
+
const w = bounds.w;
|
|
2274
|
+
const h = bounds.h;
|
|
2275
|
+
const rotatedW = Math.abs(cos) * w + Math.abs(sin) * h;
|
|
2276
|
+
const rotatedH = Math.abs(sin) * w + Math.abs(cos) * h;
|
|
2277
|
+
const flip = getShapeFlip(shape);
|
|
2278
|
+
const sx = flip?.horizontal ? -1 : 1;
|
|
2279
|
+
const sy = flip?.vertical ? -1 : 1;
|
|
2280
|
+
const a = sx * cos * rotatedW / w;
|
|
2281
|
+
const b = -sy * sin * rotatedW / h;
|
|
2282
|
+
const c = sx * sin * rotatedH / w;
|
|
2283
|
+
const d = sy * cos * rotatedH / h;
|
|
2284
|
+
return ` gradientTransform="matrix(${[
|
|
2285
|
+
a,
|
|
2286
|
+
b,
|
|
2287
|
+
c,
|
|
2288
|
+
d,
|
|
2289
|
+
(1 - a - c) / 2,
|
|
2290
|
+
(1 - b - d) / 2
|
|
2291
|
+
].map((value) => value.toFixed(6)).join(" ")})"`;
|
|
2292
|
+
};
|
|
1999
2293
|
const paint = (shape, fill, stroke, theme, isPlaceholder, pres) => {
|
|
2000
2294
|
let fillColor;
|
|
2001
2295
|
let fillAttrs = "";
|
|
@@ -2010,33 +2304,7 @@ const paint = (shape, fill, stroke, theme, isPlaceholder, pres) => {
|
|
|
2010
2304
|
else if (fill.kind === "gradient") {
|
|
2011
2305
|
const grad = shape ? pres ? getShapeGradientFillEffective(pres, shape) : getShapeGradientFill(shape) : null;
|
|
2012
2306
|
if (grad) {
|
|
2013
|
-
|
|
2014
|
-
const bounds = shape && (pres ? getShapeBoundsResolved(pres, shape) : getShapeBounds(shape));
|
|
2015
|
-
if (grad.rotateWithShape === false && shape && bounds && bounds.w > 0 && bounds.h > 0) {
|
|
2016
|
-
const angle = getShapeRotation(shape) * Math.PI / 180;
|
|
2017
|
-
const cos = Math.cos(angle);
|
|
2018
|
-
const sin = Math.sin(angle);
|
|
2019
|
-
const w = bounds.w;
|
|
2020
|
-
const h = bounds.h;
|
|
2021
|
-
const rotatedW = Math.abs(cos) * w + Math.abs(sin) * h;
|
|
2022
|
-
const rotatedH = Math.abs(sin) * w + Math.abs(cos) * h;
|
|
2023
|
-
const flip = getShapeFlip(shape);
|
|
2024
|
-
const sx = flip?.horizontal ? -1 : 1;
|
|
2025
|
-
const sy = flip?.vertical ? -1 : 1;
|
|
2026
|
-
const a = sx * cos * rotatedW / w;
|
|
2027
|
-
const b = -sy * sin * rotatedW / h;
|
|
2028
|
-
const c = sx * sin * rotatedH / w;
|
|
2029
|
-
const d = sy * cos * rotatedH / h;
|
|
2030
|
-
transform = ` gradientTransform="matrix(${[
|
|
2031
|
-
a,
|
|
2032
|
-
b,
|
|
2033
|
-
c,
|
|
2034
|
-
d,
|
|
2035
|
-
(1 - a - c) / 2,
|
|
2036
|
-
(1 - b - d) / 2
|
|
2037
|
-
].map((value) => value.toFixed(6)).join(" ")})"`;
|
|
2038
|
-
}
|
|
2039
|
-
const built = gradientDef(grad, theme, transform);
|
|
2307
|
+
const built = gradientDef(grad, theme, unrotatedGradientTransform(grad, shape, pres));
|
|
2040
2308
|
defs = built.defs;
|
|
2041
2309
|
fillColor = built.fillAttr;
|
|
2042
2310
|
} else fillColor = (shape && pres ? getShapeFillColorResolved(pres, shape) : null) ?? "none";
|
|
@@ -2053,10 +2321,34 @@ const paint = (shape, fill, stroke, theme, isPlaceholder, pres) => {
|
|
|
2053
2321
|
let strokeWidth = 0;
|
|
2054
2322
|
const strokeAttrParts = [];
|
|
2055
2323
|
let markerAttrs = "";
|
|
2324
|
+
let headColor = strokeColor;
|
|
2325
|
+
let tailColor = strokeColor;
|
|
2056
2326
|
if (stroke.kind === "solid") {
|
|
2057
2327
|
let resolved = null;
|
|
2058
2328
|
if (shape && pres) resolved = getShapeStrokeColorResolved(pres, shape);
|
|
2059
2329
|
strokeColor = resolved ?? resolveColor(stroke.color, theme, "#9CA3AF");
|
|
2330
|
+
headColor = strokeColor;
|
|
2331
|
+
tailColor = strokeColor;
|
|
2332
|
+
} else if (stroke.kind === "gradient") {
|
|
2333
|
+
const grad = shape ? getShapeStrokeGradient(shape, pres) : null;
|
|
2334
|
+
const bounds = shape && (pres ? getShapeBoundsResolved(pres, shape) : getShapeBounds(shape));
|
|
2335
|
+
if (grad && bounds) {
|
|
2336
|
+
const stopColor = (stop) => stop ? stop.resolvedColor ?? resolveColor(stop.color, theme, "#9CA3AF") : "#9CA3AF";
|
|
2337
|
+
const ordered = [...grad.stops].sort((a, b) => a.offset - b.offset);
|
|
2338
|
+
headColor = stopColor(ordered[0]);
|
|
2339
|
+
tailColor = stopColor(ordered[ordered.length - 1]);
|
|
2340
|
+
const widthEmu = stroke.widthEmu ?? 9525;
|
|
2341
|
+
const built = bounds.w > 0 && bounds.h > 0 ? gradientDef(grad, theme, unrotatedGradientTransform(grad, shape, pres)) : gradientDef(grad, theme, "", {
|
|
2342
|
+
x: (bounds.w > 0 ? bounds.x : bounds.x - widthEmu / 2) / EMU_PER_PX,
|
|
2343
|
+
y: (bounds.h > 0 ? bounds.y : bounds.y - widthEmu / 2) / EMU_PER_PX,
|
|
2344
|
+
w: Math.max(bounds.w, widthEmu) / EMU_PER_PX,
|
|
2345
|
+
h: Math.max(bounds.h, widthEmu) / EMU_PER_PX
|
|
2346
|
+
});
|
|
2347
|
+
defs += built.defs;
|
|
2348
|
+
strokeColor = built.fillAttr;
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
if (strokeColor !== "none" && (stroke.kind === "solid" || stroke.kind === "gradient")) {
|
|
2060
2352
|
strokeWidth = stroke.widthEmu ?? 9525;
|
|
2061
2353
|
if (shape) {
|
|
2062
2354
|
const opacity = getShapeStrokeOpacity(shape, pres);
|
|
@@ -2082,12 +2374,12 @@ const paint = (shape, fill, stroke, theme, isPlaceholder, pres) => {
|
|
|
2082
2374
|
const head = getShapeStrokeArrow(shape, "head", pres);
|
|
2083
2375
|
const tail = getShapeStrokeArrow(shape, "tail", pres);
|
|
2084
2376
|
if (head && head.type !== "none") {
|
|
2085
|
-
const m = buildArrowMarker(head.type, head.width, head.length,
|
|
2377
|
+
const m = buildArrowMarker(head.type, head.width, head.length, headColor, "auto-start-reverse");
|
|
2086
2378
|
defs += m.def;
|
|
2087
2379
|
markerAttrs += ` marker-start="url(#${m.id})"`;
|
|
2088
2380
|
}
|
|
2089
2381
|
if (tail && tail.type !== "none") {
|
|
2090
|
-
const m = buildArrowMarker(tail.type, tail.width, tail.length,
|
|
2382
|
+
const m = buildArrowMarker(tail.type, tail.width, tail.length, tailColor, "auto");
|
|
2091
2383
|
defs += m.def;
|
|
2092
2384
|
markerAttrs += ` marker-end="url(#${m.id})"`;
|
|
2093
2385
|
}
|
|
@@ -2103,904 +2395,6 @@ const paint = (shape, fill, stroke, theme, isPlaceholder, pres) => {
|
|
|
2103
2395
|
markerAttrs
|
|
2104
2396
|
};
|
|
2105
2397
|
};
|
|
2106
|
-
const polygon = (n, rotation = -Math.PI / 2) => {
|
|
2107
|
-
const out = [];
|
|
2108
|
-
for (let i = 0; i < n; i++) {
|
|
2109
|
-
const a = rotation + i * 2 * Math.PI / n;
|
|
2110
|
-
out.push([.5 + .5 * Math.cos(a), .5 + .5 * Math.sin(a)]);
|
|
2111
|
-
}
|
|
2112
|
-
return out;
|
|
2113
|
-
};
|
|
2114
|
-
const star = (points, innerRatio = .42) => {
|
|
2115
|
-
const out = [];
|
|
2116
|
-
const rotation = -Math.PI / 2;
|
|
2117
|
-
for (let i = 0; i < points * 2; i++) {
|
|
2118
|
-
const a = rotation + i * Math.PI / points;
|
|
2119
|
-
const r = i % 2 === 0 ? .5 : .5 * innerRatio;
|
|
2120
|
-
out.push([.5 + r * Math.cos(a), .5 + r * Math.sin(a)]);
|
|
2121
|
-
}
|
|
2122
|
-
return out;
|
|
2123
|
-
};
|
|
2124
|
-
const PRESET_POINTS = {
|
|
2125
|
-
triangle: () => [
|
|
2126
|
-
[.5, 0],
|
|
2127
|
-
[1, 1],
|
|
2128
|
-
[0, 1]
|
|
2129
|
-
],
|
|
2130
|
-
rtTriangle: () => [
|
|
2131
|
-
[0, 0],
|
|
2132
|
-
[1, 1],
|
|
2133
|
-
[0, 1]
|
|
2134
|
-
],
|
|
2135
|
-
diamond: () => [
|
|
2136
|
-
[.5, 0],
|
|
2137
|
-
[1, .5],
|
|
2138
|
-
[.5, 1],
|
|
2139
|
-
[0, .5]
|
|
2140
|
-
],
|
|
2141
|
-
parallelogram: () => [
|
|
2142
|
-
[.25, 0],
|
|
2143
|
-
[1, 0],
|
|
2144
|
-
[.75, 1],
|
|
2145
|
-
[0, 1]
|
|
2146
|
-
],
|
|
2147
|
-
trapezoid: () => [
|
|
2148
|
-
[.25, 0],
|
|
2149
|
-
[.75, 0],
|
|
2150
|
-
[1, 1],
|
|
2151
|
-
[0, 1]
|
|
2152
|
-
],
|
|
2153
|
-
pentagon: () => polygon(5),
|
|
2154
|
-
hexagon: () => polygon(6),
|
|
2155
|
-
heptagon: () => polygon(7),
|
|
2156
|
-
octagon: () => polygon(8),
|
|
2157
|
-
decagon: () => polygon(10),
|
|
2158
|
-
dodecagon: () => polygon(12),
|
|
2159
|
-
star4: () => star(4),
|
|
2160
|
-
star5: () => star(5),
|
|
2161
|
-
star6: () => star(6),
|
|
2162
|
-
star7: () => star(7),
|
|
2163
|
-
star8: () => star(8),
|
|
2164
|
-
star10: () => star(10),
|
|
2165
|
-
star12: () => star(12),
|
|
2166
|
-
star16: () => star(16),
|
|
2167
|
-
star24: () => star(24),
|
|
2168
|
-
star32: () => star(32),
|
|
2169
|
-
rightArrow: (w, h) => {
|
|
2170
|
-
const bx = 1 - Math.min(1, .5 * Math.min(w, h) / w);
|
|
2171
|
-
return [
|
|
2172
|
-
[0, .25],
|
|
2173
|
-
[bx, .25],
|
|
2174
|
-
[bx, 0],
|
|
2175
|
-
[1, .5],
|
|
2176
|
-
[bx, 1],
|
|
2177
|
-
[bx, .75],
|
|
2178
|
-
[0, .75]
|
|
2179
|
-
];
|
|
2180
|
-
},
|
|
2181
|
-
leftArrow: (w, h) => {
|
|
2182
|
-
const bx = Math.min(1, .5 * Math.min(w, h) / w);
|
|
2183
|
-
return [
|
|
2184
|
-
[1, .25],
|
|
2185
|
-
[bx, .25],
|
|
2186
|
-
[bx, 0],
|
|
2187
|
-
[0, .5],
|
|
2188
|
-
[bx, 1],
|
|
2189
|
-
[bx, .75],
|
|
2190
|
-
[1, .75]
|
|
2191
|
-
];
|
|
2192
|
-
},
|
|
2193
|
-
upArrow: (w, h) => {
|
|
2194
|
-
const by = Math.min(1, .5 * Math.min(w, h) / h);
|
|
2195
|
-
return [
|
|
2196
|
-
[.25, 1],
|
|
2197
|
-
[.25, by],
|
|
2198
|
-
[0, by],
|
|
2199
|
-
[.5, 0],
|
|
2200
|
-
[1, by],
|
|
2201
|
-
[.75, by],
|
|
2202
|
-
[.75, 1]
|
|
2203
|
-
];
|
|
2204
|
-
},
|
|
2205
|
-
downArrow: (w, h) => {
|
|
2206
|
-
const by = 1 - Math.min(1, .5 * Math.min(w, h) / h);
|
|
2207
|
-
return [
|
|
2208
|
-
[.25, 0],
|
|
2209
|
-
[.25, by],
|
|
2210
|
-
[0, by],
|
|
2211
|
-
[.5, 1],
|
|
2212
|
-
[1, by],
|
|
2213
|
-
[.75, by],
|
|
2214
|
-
[.75, 0]
|
|
2215
|
-
];
|
|
2216
|
-
},
|
|
2217
|
-
leftRightArrow: () => [
|
|
2218
|
-
[0, .5],
|
|
2219
|
-
[.18, .2],
|
|
2220
|
-
[.18, .35],
|
|
2221
|
-
[.82, .35],
|
|
2222
|
-
[.82, .2],
|
|
2223
|
-
[1, .5],
|
|
2224
|
-
[.82, .8],
|
|
2225
|
-
[.82, .65],
|
|
2226
|
-
[.18, .65],
|
|
2227
|
-
[.18, .8]
|
|
2228
|
-
],
|
|
2229
|
-
upDownArrow: () => [
|
|
2230
|
-
[.5, 0],
|
|
2231
|
-
[.2, .18],
|
|
2232
|
-
[.35, .18],
|
|
2233
|
-
[.35, .82],
|
|
2234
|
-
[.2, .82],
|
|
2235
|
-
[.5, 1],
|
|
2236
|
-
[.8, .82],
|
|
2237
|
-
[.65, .82],
|
|
2238
|
-
[.65, .18],
|
|
2239
|
-
[.8, .18]
|
|
2240
|
-
],
|
|
2241
|
-
chevron: () => [
|
|
2242
|
-
[0, 0],
|
|
2243
|
-
[.7, 0],
|
|
2244
|
-
[1, .5],
|
|
2245
|
-
[.7, 1],
|
|
2246
|
-
[0, 1],
|
|
2247
|
-
[.3, .5]
|
|
2248
|
-
],
|
|
2249
|
-
bentArrow: () => [
|
|
2250
|
-
[0, .45],
|
|
2251
|
-
[.55, .45],
|
|
2252
|
-
[.55, .25],
|
|
2253
|
-
[.55, .05],
|
|
2254
|
-
[.95, .05],
|
|
2255
|
-
[.95, .55],
|
|
2256
|
-
[.8, .55],
|
|
2257
|
-
[.8, .85],
|
|
2258
|
-
[0, .85]
|
|
2259
|
-
],
|
|
2260
|
-
homePlate: () => [
|
|
2261
|
-
[0, 0],
|
|
2262
|
-
[.75, 0],
|
|
2263
|
-
[1, .5],
|
|
2264
|
-
[.75, 1],
|
|
2265
|
-
[0, 1]
|
|
2266
|
-
]
|
|
2267
|
-
};
|
|
2268
|
-
const PRESET_PATHS = {
|
|
2269
|
-
wedgeRectCallout: (x, y, w, h) => {
|
|
2270
|
-
const bodyH = h * .78;
|
|
2271
|
-
const tailTipX = x + w * .12;
|
|
2272
|
-
const tailTipY = y + h;
|
|
2273
|
-
const tailBaseLeft = x + w * .18;
|
|
2274
|
-
const tailBaseRight = x + w * .32;
|
|
2275
|
-
const bodyB = y + bodyH;
|
|
2276
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${bodyB} L${tailBaseRight},${bodyB} L${tailTipX},${tailTipY} L${tailBaseLeft},${bodyB} L${x},${bodyB} Z`;
|
|
2277
|
-
},
|
|
2278
|
-
wedgeRoundRectCallout: (x, y, w, h) => {
|
|
2279
|
-
const r = Math.min(w, h) * .08;
|
|
2280
|
-
const bodyH = h * .78;
|
|
2281
|
-
const tailTipX = x + w * .12;
|
|
2282
|
-
const tailTipY = y + h;
|
|
2283
|
-
const tailBaseLeft = x + w * .18;
|
|
2284
|
-
const tailBaseRight = x + w * .32;
|
|
2285
|
-
const bodyB = y + bodyH;
|
|
2286
|
-
return `M${x + r},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w},${y + r} L${x + w},${bodyB - r} A${r},${r} 0 0 1 ${x + w - r},${bodyB} L${tailBaseRight},${bodyB} L${tailTipX},${tailTipY} L${tailBaseLeft},${bodyB} L${x + r},${bodyB} A${r},${r} 0 0 1 ${x},${bodyB - r} L${x},${y + r} A${r},${r} 0 0 1 ${x + r},${y} Z`;
|
|
2287
|
-
},
|
|
2288
|
-
wedgeEllipseCallout: (x, y, w, h) => {
|
|
2289
|
-
const bodyCy = y + h * .39;
|
|
2290
|
-
const bodyRy = h * .39;
|
|
2291
|
-
const cx = x + w / 2;
|
|
2292
|
-
const bodyRx = w / 2;
|
|
2293
|
-
const tailTipX = x + w * .12;
|
|
2294
|
-
const tailTipY = y + h;
|
|
2295
|
-
const tailBaseAngle = 1.5;
|
|
2296
|
-
return `M${cx + bodyRx * Math.cos(tailBaseAngle - .18)},${bodyCy + bodyRy * Math.sin(tailBaseAngle - .18)} A${bodyRx},${bodyRy} 0 1 0 ${cx + bodyRx * Math.cos(1.68)},${bodyCy + bodyRy * Math.sin(1.68)} L${tailTipX},${tailTipY} Z`;
|
|
2297
|
-
},
|
|
2298
|
-
cloudCallout: (x, y, w, h) => {
|
|
2299
|
-
const bodyH = h * .78;
|
|
2300
|
-
const cx = x + w / 2;
|
|
2301
|
-
const cy = y + bodyH / 2;
|
|
2302
|
-
const rx = w / 2 * .92;
|
|
2303
|
-
const ry = bodyH / 2 * .85;
|
|
2304
|
-
const lobes = 10;
|
|
2305
|
-
const path = [];
|
|
2306
|
-
for (let i = 0; i < lobes; i++) {
|
|
2307
|
-
const a = i / lobes * 2 * Math.PI - Math.PI / 2;
|
|
2308
|
-
const lobeRx = rx * .32;
|
|
2309
|
-
const lobeRy = ry * .32;
|
|
2310
|
-
const px0 = cx + rx * Math.cos(a);
|
|
2311
|
-
const py0 = cy + ry * Math.sin(a);
|
|
2312
|
-
if (i === 0) path.push(`M${px0 - lobeRx},${py0}`);
|
|
2313
|
-
path.push(`A${lobeRx},${lobeRy} 0 1 1 ${px0 + lobeRx},${py0}`);
|
|
2314
|
-
const nextA = (i + 1) / lobes * 2 * Math.PI - Math.PI / 2;
|
|
2315
|
-
const nextX = cx + rx * Math.cos(nextA) - lobeRx;
|
|
2316
|
-
const nextY = cy + ry * Math.sin(nextA);
|
|
2317
|
-
path.push(`L${nextX},${nextY}`);
|
|
2318
|
-
}
|
|
2319
|
-
path.push("Z");
|
|
2320
|
-
const tailX = x + w * .18;
|
|
2321
|
-
const tailY = y + h * .95;
|
|
2322
|
-
return `${path.join(" ")} M${tailX - 6},${tailY - 14} a4,3 0 1 0 1,0 Z M${tailX},${tailY} a6,4 0 1 0 1,0 Z`;
|
|
2323
|
-
},
|
|
2324
|
-
heart: (x, y, w, h) => {
|
|
2325
|
-
const cx = x + w / 2;
|
|
2326
|
-
const top = y + h * .27;
|
|
2327
|
-
return `M${cx},${y + h} C${x},${y + h * .55} ${x},${top} ${cx},${y + h * .4} C${x + w},${top} ${x + w},${y + h * .55} ${cx},${y + h} Z`;
|
|
2328
|
-
},
|
|
2329
|
-
sun: (x, y, w, h) => {
|
|
2330
|
-
const cx = x + w / 2;
|
|
2331
|
-
const cy = y + h / 2;
|
|
2332
|
-
const innerR = Math.min(w, h) * .25;
|
|
2333
|
-
const outerR = Math.min(w, h) * .5;
|
|
2334
|
-
const rays = 12;
|
|
2335
|
-
const path = [];
|
|
2336
|
-
for (let i = 0; i < rays * 2; i++) {
|
|
2337
|
-
const r = i % 2 === 0 ? outerR : innerR;
|
|
2338
|
-
const a = i / (rays * 2) * 2 * Math.PI - Math.PI / 2;
|
|
2339
|
-
const px0 = cx + r * Math.cos(a);
|
|
2340
|
-
const py0 = cy + r * Math.sin(a);
|
|
2341
|
-
path.push(`${i === 0 ? "M" : "L"}${px0},${py0}`);
|
|
2342
|
-
}
|
|
2343
|
-
path.push("Z");
|
|
2344
|
-
return path.join(" ");
|
|
2345
|
-
},
|
|
2346
|
-
smileyFace: (x, y, w, h) => {
|
|
2347
|
-
const cx = x + w / 2;
|
|
2348
|
-
const cy = y + h / 2;
|
|
2349
|
-
const r = Math.min(w, h) / 2 - 1;
|
|
2350
|
-
const eyeR = r * .07;
|
|
2351
|
-
const eyeOff = r * .32;
|
|
2352
|
-
const mouthW = r * .5;
|
|
2353
|
-
const mouthY = cy + r * .18;
|
|
2354
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 0 ${cx - r},${cy} A${r},${r} 0 1 0 ${cx + r},${cy} Z M${cx - eyeOff + eyeR},${cy - eyeOff} A${eyeR},${eyeR} 0 1 1 ${cx - eyeOff - eyeR},${cy - eyeOff} A${eyeR},${eyeR} 0 1 1 ${cx - eyeOff + eyeR},${cy - eyeOff} Z M${cx + eyeOff + eyeR},${cy - eyeOff} A${eyeR},${eyeR} 0 1 1 ${cx + eyeOff - eyeR},${cy - eyeOff} A${eyeR},${eyeR} 0 1 1 ${cx + eyeOff + eyeR},${cy - eyeOff} Z M${cx - mouthW},${mouthY} Q${cx},${mouthY + r * .32} ${cx + mouthW},${mouthY}`;
|
|
2355
|
-
},
|
|
2356
|
-
lightningBolt: (x, y, w, h) => {
|
|
2357
|
-
return `M${x + w * .5},${y} L${x + w * .15},${y + h * .55} L${x + w * .45},${y + h * .55} L${x + w * .3},${y + h} L${x + w * .85},${y + h * .4} L${x + w * .55},${y + h * .4} L${x + w * .7},${y} Z`;
|
|
2358
|
-
},
|
|
2359
|
-
flowChartProcess: (x, y, w, h) => `M${x},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} Z`,
|
|
2360
|
-
flowChartAlternateProcess: (x, y, w, h) => {
|
|
2361
|
-
const r = Math.min(w, h) * .18;
|
|
2362
|
-
return `M${x + r},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w},${y + r} L${x + w},${y + h - r} A${r},${r} 0 0 1 ${x + w - r},${y + h} L${x + r},${y + h} A${r},${r} 0 0 1 ${x},${y + h - r} L${x},${y + r} A${r},${r} 0 0 1 ${x + r},${y} Z`;
|
|
2363
|
-
},
|
|
2364
|
-
flowChartDecision: (x, y, w, h) => {
|
|
2365
|
-
const cx = x + w / 2;
|
|
2366
|
-
const cy = y + h / 2;
|
|
2367
|
-
return `M${cx},${y} L${x + w},${cy} L${cx},${y + h} L${x},${cy} Z`;
|
|
2368
|
-
},
|
|
2369
|
-
flowChartTerminator: (x, y, w, h) => {
|
|
2370
|
-
const r = h / 2;
|
|
2371
|
-
return `M${x + r},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w - r},${y + h} L${x + r},${y + h} A${r},${r} 0 0 1 ${x + r},${y} Z`;
|
|
2372
|
-
},
|
|
2373
|
-
flowChartConnector: (x, y, w, h) => {
|
|
2374
|
-
const cx = x + w / 2;
|
|
2375
|
-
const cy = y + h / 2;
|
|
2376
|
-
const r = Math.min(w, h) / 2;
|
|
2377
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 1 ${cx - r},${cy} A${r},${r} 0 1 1 ${cx + r},${cy} Z`;
|
|
2378
|
-
},
|
|
2379
|
-
flowChartDocument: (x, y, w, h) => {
|
|
2380
|
-
const wave = h * .18;
|
|
2381
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${y + h - wave} C${x + w * .75},${y + h + wave * .5} ${x + w * .25},${y + h - wave * 2} ${x},${y + h - wave * .5} Z`;
|
|
2382
|
-
},
|
|
2383
|
-
flowChartMultidocument: (x, y, w, h) => {
|
|
2384
|
-
const inset = w * .06;
|
|
2385
|
-
return `${`M${x + inset},${y + inset * .6} L${x + w},${y + inset * .6} L${x + w},${y + h - inset * .6} L${x + w - inset},${y + h - inset * .6} L${x + w - inset},${y + inset * .6}`} Z ${`M${x},${y + inset * 1.2} L${x + w - inset},${y + inset * 1.2} L${x + w - inset},${y + h * .85} C${x + (w - inset) * .75},${y + h + 6} ${x + (w - inset) * .25},${y + h * .75} ${x},${y + h * .95} Z`}`;
|
|
2386
|
-
},
|
|
2387
|
-
flowChartPredefinedProcess: (x, y, w, h) => {
|
|
2388
|
-
const inset = w * .1;
|
|
2389
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} Z M${x + inset},${y} L${x + inset},${y + h} M${x + w - inset},${y} L${x + w - inset},${y + h}`;
|
|
2390
|
-
},
|
|
2391
|
-
flowChartInternalStorage: (x, y, w, h) => {
|
|
2392
|
-
const inset = Math.min(w, h) * .1;
|
|
2393
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} Z M${x + inset},${y} L${x + inset},${y + h} M${x},${y + inset} L${x + w},${y + inset}`;
|
|
2394
|
-
},
|
|
2395
|
-
flowChartManualInput: (x, y, w, h) => {
|
|
2396
|
-
return `M${x},${y + h * .35} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} Z`;
|
|
2397
|
-
},
|
|
2398
|
-
flowChartManualOperation: (x, y, w, h) => {
|
|
2399
|
-
return `M${x},${y} L${x + w},${y} L${x + w * .8},${y + h} L${x + w * .2},${y + h} Z`;
|
|
2400
|
-
},
|
|
2401
|
-
flowChartInputOutput: (x, y, w, h) => {
|
|
2402
|
-
const skew = w * .18;
|
|
2403
|
-
return `M${x + skew},${y} L${x + w},${y} L${x + w - skew},${y + h} L${x},${y + h} Z`;
|
|
2404
|
-
},
|
|
2405
|
-
flowChartPunchedTape: (x, y, w, h) => {
|
|
2406
|
-
const wave = h * .12;
|
|
2407
|
-
return `M${x},${y + wave} C${x + w * .25},${y - wave} ${x + w * .75},${y + wave * 2} ${x + w},${y + wave} L${x + w},${y + h - wave} C${x + w * .75},${y + h + wave} ${x + w * .25},${y + h - wave * 2} ${x},${y + h - wave} Z`;
|
|
2408
|
-
},
|
|
2409
|
-
flowChartCard: (x, y, w, h) => {
|
|
2410
|
-
const cut = h * .3;
|
|
2411
|
-
return `M${x + cut},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} L${x},${y + cut} Z`;
|
|
2412
|
-
},
|
|
2413
|
-
flowChartPunchedCard: (x, y, w, h) => {
|
|
2414
|
-
const cut = h * .2;
|
|
2415
|
-
return `M${x + cut},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} L${x},${y + cut} Z`;
|
|
2416
|
-
},
|
|
2417
|
-
flowChartOnlineStorage: (x, y, w, h) => {
|
|
2418
|
-
const cap = w * .12;
|
|
2419
|
-
return `M${x + cap},${y} L${x + w},${y} L${x + w},${y + h} L${x + cap},${y + h} A${cap},${h / 2} 0 0 1 ${x + cap},${y} Z`;
|
|
2420
|
-
},
|
|
2421
|
-
flowChartMagneticDisk: (x, y, w, h) => {
|
|
2422
|
-
const er = h * .12;
|
|
2423
|
-
return `M${x},${y + er} A${w / 2},${er} 0 0 1 ${x + w},${y + er} L${x + w},${y + h - er} A${w / 2},${er} 0 0 1 ${x},${y + h - er} Z M${x},${y + er} A${w / 2},${er} 0 0 0 ${x + w},${y + er}`;
|
|
2424
|
-
},
|
|
2425
|
-
flowChartMagneticDrum: (x, y, w, h) => {
|
|
2426
|
-
const er = w * .12;
|
|
2427
|
-
return `M${x + er},${y} L${x + w - er},${y} A${er},${h / 2} 0 0 1 ${x + w - er},${y + h} L${x + er},${y + h} A${er},${h / 2} 0 0 1 ${x + er},${y} Z M${x + w - er},${y} A${er},${h / 2} 0 0 0 ${x + w - er},${y + h}`;
|
|
2428
|
-
},
|
|
2429
|
-
flowChartMagneticTape: (x, y, w, h) => {
|
|
2430
|
-
const cx = x + w / 2;
|
|
2431
|
-
const cy = y + h / 2;
|
|
2432
|
-
const r = Math.min(w, h) / 2;
|
|
2433
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 0 ${cx - r * .7},${cy + r * .7} L${x + w},${y + h} L${cx + r},${cy} Z`;
|
|
2434
|
-
},
|
|
2435
|
-
flowChartSummingJunction: (x, y, w, h) => {
|
|
2436
|
-
const cx = x + w / 2;
|
|
2437
|
-
const cy = y + h / 2;
|
|
2438
|
-
const r = Math.min(w, h) / 2;
|
|
2439
|
-
const off = r * Math.SQRT1_2;
|
|
2440
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 0 ${cx - r},${cy} A${r},${r} 0 1 0 ${cx + r},${cy} Z M${cx - off},${cy - off} L${cx + off},${cy + off} M${cx - off},${cy + off} L${cx + off},${cy - off}`;
|
|
2441
|
-
},
|
|
2442
|
-
flowChartOr: (x, y, w, h) => {
|
|
2443
|
-
const cx = x + w / 2;
|
|
2444
|
-
const cy = y + h / 2;
|
|
2445
|
-
const r = Math.min(w, h) / 2;
|
|
2446
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 0 ${cx - r},${cy} A${r},${r} 0 1 0 ${cx + r},${cy} Z M${cx - r},${cy} L${cx + r},${cy} M${cx},${cy - r} L${cx},${cy + r}`;
|
|
2447
|
-
},
|
|
2448
|
-
flowChartCollate: (x, y, w, h) => {
|
|
2449
|
-
return `M${x},${y} L${x + w},${y} L${x},${y + h} L${x + w},${y + h} Z`;
|
|
2450
|
-
},
|
|
2451
|
-
flowChartSort: (x, y, w, h) => {
|
|
2452
|
-
const cx = x + w / 2;
|
|
2453
|
-
const cy = y + h / 2;
|
|
2454
|
-
return `M${cx},${y} L${x + w},${cy} L${cx},${y + h} L${x},${cy} Z M${x},${cy} L${x + w},${cy}`;
|
|
2455
|
-
},
|
|
2456
|
-
flowChartExtract: (x, y, w, h) => {
|
|
2457
|
-
return `M${x + w / 2},${y} L${x + w},${y + h} L${x},${y + h} Z`;
|
|
2458
|
-
},
|
|
2459
|
-
flowChartMerge: (x, y, w, h) => {
|
|
2460
|
-
return `M${x},${y} L${x + w},${y} L${x + w / 2},${y + h} Z`;
|
|
2461
|
-
},
|
|
2462
|
-
flowChartOfflineStorage: (x, y, w, h) => {
|
|
2463
|
-
return `M${x + w / 2},${y} L${x + w},${y + h} L${x},${y + h} Z M${x + w * .25},${y + h * .75} L${x + w * .75},${y + h * .75}`;
|
|
2464
|
-
},
|
|
2465
|
-
flowChartDelay: (x, y, w, h) => {
|
|
2466
|
-
const r = h / 2;
|
|
2467
|
-
return `M${x},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w - r},${y + h} L${x},${y + h} Z`;
|
|
2468
|
-
},
|
|
2469
|
-
flowChartDisplay: (x, y, w, h) => {
|
|
2470
|
-
const r = h / 2;
|
|
2471
|
-
return `M${x + r * .5},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w - r},${y + h} L${x + r * .5},${y + h} L${x},${y + h / 2} Z`;
|
|
2472
|
-
},
|
|
2473
|
-
flowChartPreparation: (x, y, w, h) => {
|
|
2474
|
-
const cut = w * .18;
|
|
2475
|
-
return `M${x + cut},${y} L${x + w - cut},${y} L${x + w},${y + h / 2} L${x + w - cut},${y + h} L${x + cut},${y + h} L${x},${y + h / 2} Z`;
|
|
2476
|
-
},
|
|
2477
|
-
notchedRightArrow: (x, y, w, h) => {
|
|
2478
|
-
return `M${x},${y + h * .3} L${x + w * .65},${y + h * .3} L${x + w * .65},${y} L${x + w},${y + h / 2} L${x + w * .65},${y + h} L${x + w * .65},${y + h * .7} L${x},${y + h * .7} L${x + w * .15},${y + h / 2} Z`;
|
|
2479
|
-
},
|
|
2480
|
-
stripedRightArrow: (x, y, w, h) => {
|
|
2481
|
-
const stripe = w * .04;
|
|
2482
|
-
return `M${x},${y + h * .3} L${x + stripe},${y + h * .3} L${x + stripe},${y + h * .7} L${x},${y + h * .7} Z M${x + stripe * 2.5},${y + h * .3} L${x + stripe * 3.5},${y + h * .3} L${x + stripe * 3.5},${y + h * .7} L${x + stripe * 2.5},${y + h * .7} Z M${x + stripe * 5},${y + h * .3} L${x + w * .65},${y + h * .3} L${x + w * .65},${y} L${x + w},${y + h / 2} L${x + w * .65},${y + h} L${x + w * .65},${y + h * .7} L${x + stripe * 5},${y + h * .7} Z`;
|
|
2483
|
-
},
|
|
2484
|
-
curvedRightArrow: (x, y, w, h) => {
|
|
2485
|
-
return `M${x},${y + h * .6} Q${x + w * .5},${y} ${x + w * .85},${y + h * .25} L${x + w},${y + h * .45} L${x + w * .85},${y + h * .55} L${x + w * .7},${y + h * .35} Q${x + w * .45},${y + h * .18} ${x + w * .15},${y + h * .75} Z`;
|
|
2486
|
-
},
|
|
2487
|
-
uturnArrow: (x, y, w, h) => {
|
|
2488
|
-
return `M${x},${y + h} L${x},${y + h / 2} A${w * .4},${h * .4} 0 0 1 ${x + w * .8},${y + h / 2} L${x + w * .8},${y + h * .25} L${x + w},${y + h * .45} L${x + w * .8},${y + h * .65} L${x + w * .8},${y + h / 2} A${w * .2},${h * .25} 0 0 0 ${x + w * .2},${y + h / 2} L${x + w * .2},${y + h} Z`;
|
|
2489
|
-
},
|
|
2490
|
-
leftBracket: (x, y, w, h) => {
|
|
2491
|
-
return `M${x + w},${y} L${x},${y} L${x},${y + h} L${x + w},${y + h}`;
|
|
2492
|
-
},
|
|
2493
|
-
rightBracket: (x, y, w, h) => {
|
|
2494
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h}`;
|
|
2495
|
-
},
|
|
2496
|
-
bracketPair: (x, y, w, h) => {
|
|
2497
|
-
return `M${x + w * .1},${y} L${x},${y} L${x},${y + h} L${x + w * .1},${y + h} M${x + w * .9},${y} L${x + w},${y} L${x + w},${y + h} L${x + w * .9},${y + h}`;
|
|
2498
|
-
},
|
|
2499
|
-
leftBrace: (x, y, w, h) => {
|
|
2500
|
-
const mid = y + h / 2;
|
|
2501
|
-
return `M${x + w},${y} Q${x},${y} ${x},${mid - 8} Q${x},${mid} ${x - 4},${mid} Q${x},${mid} ${x},${mid + 8} Q${x},${y + h} ${x + w},${y + h}`;
|
|
2502
|
-
},
|
|
2503
|
-
rightBrace: (x, y, w, h) => {
|
|
2504
|
-
const mid = y + h / 2;
|
|
2505
|
-
return `M${x},${y} Q${x + w},${y} ${x + w},${mid - 8} Q${x + w},${mid} ${x + w + 4},${mid} Q${x + w},${mid} ${x + w},${mid + 8} Q${x + w},${y + h} ${x},${y + h}`;
|
|
2506
|
-
},
|
|
2507
|
-
bracePair: (x, y, w, h) => {
|
|
2508
|
-
const mid = y + h / 2;
|
|
2509
|
-
return `M${x + w * .12},${y} Q${x},${y} ${x},${mid - 8} Q${x},${mid} ${x - 4},${mid} Q${x},${mid} ${x},${mid + 8} Q${x},${y + h} ${x + w * .12},${y + h} M${x + w * .88},${y} Q${x + w},${y} ${x + w},${mid - 8} Q${x + w},${mid} ${x + w + 4},${mid} Q${x + w},${mid} ${x + w},${mid + 8} Q${x + w},${y + h} ${x + w * .88},${y + h}`;
|
|
2510
|
-
},
|
|
2511
|
-
snip1Rect: (x, y, w, h) => {
|
|
2512
|
-
const c = Math.min(w, h) * .18;
|
|
2513
|
-
return `M${x},${y} L${x + w - c},${y} L${x + w},${y + c} L${x + w},${y + h} L${x},${y + h} Z`;
|
|
2514
|
-
},
|
|
2515
|
-
snip2SameRect: (x, y, w, h) => {
|
|
2516
|
-
const c = Math.min(w, h) * .18;
|
|
2517
|
-
return `M${x + c},${y} L${x + w - c},${y} L${x + w},${y + c} L${x + w},${y + h} L${x},${y + h} L${x},${y + c} Z`;
|
|
2518
|
-
},
|
|
2519
|
-
snip2DiagRect: (x, y, w, h) => {
|
|
2520
|
-
const c = Math.min(w, h) * .18;
|
|
2521
|
-
return `M${x},${y} L${x + w - c},${y} L${x + w},${y + c} L${x + w},${y + h} L${x + c},${y + h} L${x},${y + h - c} Z`;
|
|
2522
|
-
},
|
|
2523
|
-
snipRoundRect: (x, y, w, h) => {
|
|
2524
|
-
const c = Math.min(w, h) * .18;
|
|
2525
|
-
return `M${x + c},${y} A${c},${c} 0 0 0 ${x},${y + c} L${x},${y + h} L${x + w},${y + h} L${x + w},${y + c} L${x + w - c},${y} Z`;
|
|
2526
|
-
},
|
|
2527
|
-
round1Rect: (x, y, w, h) => {
|
|
2528
|
-
const r = Math.min(w, h) * .18;
|
|
2529
|
-
return `M${x},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w},${y + r} L${x + w},${y + h} L${x},${y + h} Z`;
|
|
2530
|
-
},
|
|
2531
|
-
round2SameRect: (x, y, w, h) => {
|
|
2532
|
-
const r = Math.min(w, h) * .18;
|
|
2533
|
-
return `M${x + r},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w},${y + r} L${x + w},${y + h} L${x},${y + h} L${x},${y + r} A${r},${r} 0 0 1 ${x + r},${y} Z`;
|
|
2534
|
-
},
|
|
2535
|
-
round2DiagRect: (x, y, w, h) => {
|
|
2536
|
-
const r = Math.min(w, h) * .18;
|
|
2537
|
-
return `M${x},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w},${y + r} L${x + w},${y + h} L${x + r},${y + h} A${r},${r} 0 0 1 ${x},${y + h - r} Z`;
|
|
2538
|
-
},
|
|
2539
|
-
ribbon: (x, y, w, h) => {
|
|
2540
|
-
const notch = w * .06;
|
|
2541
|
-
const bodyTop = y + h * .2;
|
|
2542
|
-
const bodyBot = y + h * .8;
|
|
2543
|
-
return `M${x},${bodyTop} L${x + notch * 2},${y} L${x + w - notch * 2},${y} L${x + w},${bodyTop} L${x + w * .85},${bodyTop + (bodyBot - bodyTop) / 2} L${x + w},${bodyBot} L${x + w - notch * 2},${y + h} L${x + w - notch * 4},${bodyBot} L${x + notch * 4},${bodyBot} L${x + notch * 2},${y + h} L${x},${bodyBot} L${x + w * .15},${bodyTop + (bodyBot - bodyTop) / 2} Z`;
|
|
2544
|
-
},
|
|
2545
|
-
ribbon2: (x, y, w, h) => {
|
|
2546
|
-
const notch = w * .06;
|
|
2547
|
-
const bodyTop = y + h * .2;
|
|
2548
|
-
const bodyBot = y + h * .8;
|
|
2549
|
-
return `M${x},${bodyBot} L${x + notch * 2},${y + h} L${x + w - notch * 2},${y + h} L${x + w},${bodyBot} L${x + w * .85},${bodyTop + (bodyBot - bodyTop) / 2} L${x + w},${bodyTop} L${x + w - notch * 2},${y} L${x + w - notch * 4},${bodyTop} L${x + notch * 4},${bodyTop} L${x + notch * 2},${y} L${x},${bodyTop} L${x + w * .15},${bodyTop + (bodyBot - bodyTop) / 2} Z`;
|
|
2550
|
-
},
|
|
2551
|
-
verticalScroll: (x, y, w, h) => {
|
|
2552
|
-
const r = w * .08;
|
|
2553
|
-
return `M${x + r},${y + r} A${r},${r} 0 0 1 ${x + r * 2},${y} L${x + w},${y} L${x + w},${y + h - r} A${r},${r} 0 0 1 ${x + w - r * 2},${y + h} L${x},${y + h} L${x},${y + r} A${r},${r} 0 0 1 ${x + r},${y + r} Z`;
|
|
2554
|
-
},
|
|
2555
|
-
horizontalScroll: (x, y, w, h) => {
|
|
2556
|
-
const r = h * .08;
|
|
2557
|
-
return `M${x + r},${y + r} A${r},${r} 0 0 1 ${x},${y + r * 2} L${x},${y + h} L${x + w - r},${y + h} A${r},${r} 0 0 1 ${x + w},${y + h - r * 2} L${x + w},${y} L${x + r},${y} A${r},${r} 0 0 1 ${x + r},${y + r} Z`;
|
|
2558
|
-
},
|
|
2559
|
-
wave: (x, y, w, h) => {
|
|
2560
|
-
return `M${x},${y + h * .5} C${x + w * .25},${y - h * .1} ${x + w * .5},${y + h * .85} ${x + w * .75},${y + h * .3} C${x + w * .85},${y + h * .05} ${x + w * .95},${y + h * .4} ${x + w},${y + h * .5} L${x + w},${y + h} C${x + w * .75},${y + h * .4} ${x + w * .5},${y + h * 1.1} ${x + w * .25},${y + h * .55} C${x + w * .15},${y + h * .3} ${x + w * .05},${y + h * .6} ${x},${y + h * .55} Z`;
|
|
2561
|
-
},
|
|
2562
|
-
doubleWave: (x, y, w, h) => {
|
|
2563
|
-
return `M${x},${y + h * .4} C${x + w * .15},${y - h * .05} ${x + w * .35},${y + h * .65} ${x + w * .5},${y + h * .3} C${x + w * .65},${y - h * .05} ${x + w * .85},${y + h * .65} ${x + w},${y + h * .4} L${x + w},${y + h} C${x + w * .85},${y + h * .4} ${x + w * .65},${y + h * 1.05} ${x + w * .5},${y + h * .7} C${x + w * .35},${y + h * 1.05} ${x + w * .15},${y + h * .4} ${x},${y + h} Z`;
|
|
2564
|
-
},
|
|
2565
|
-
mathPlus: (x, y, w, h) => {
|
|
2566
|
-
const t = Math.min(w, h) * .2;
|
|
2567
|
-
const cx = x + w / 2;
|
|
2568
|
-
const cy = y + h / 2;
|
|
2569
|
-
return `M${cx - t / 2},${y} L${cx + t / 2},${y} L${cx + t / 2},${cy - t / 2} L${x + w},${cy - t / 2} L${x + w},${cy + t / 2} L${cx + t / 2},${cy + t / 2} L${cx + t / 2},${y + h} L${cx - t / 2},${y + h} L${cx - t / 2},${cy + t / 2} L${x},${cy + t / 2} L${x},${cy - t / 2} L${cx - t / 2},${cy - t / 2} Z`;
|
|
2570
|
-
},
|
|
2571
|
-
mathMinus: (x, y, w, h) => {
|
|
2572
|
-
const t = h * .3;
|
|
2573
|
-
const cy = y + h / 2;
|
|
2574
|
-
return `M${x},${cy - t / 2} L${x + w},${cy - t / 2} L${x + w},${cy + t / 2} L${x},${cy + t / 2} Z`;
|
|
2575
|
-
},
|
|
2576
|
-
mathMultiply: (x, y, w, h) => {
|
|
2577
|
-
const t = Math.min(w, h) * .16;
|
|
2578
|
-
const cx = x + w / 2;
|
|
2579
|
-
const cy = y + h / 2;
|
|
2580
|
-
return `M${x},${y + t} L${x + t},${y} L${cx},${cy - t} L${x + w - t},${y} L${x + w},${y + t} L${cx + t},${cy} L${x + w},${y + h - t} L${x + w - t},${y + h} L${cx},${cy + t} L${x + t},${y + h} L${x},${y + h - t} L${cx - t},${cy} Z`;
|
|
2581
|
-
},
|
|
2582
|
-
mathDivide: (x, y, w, h) => {
|
|
2583
|
-
const dot = Math.min(w, h) * .1;
|
|
2584
|
-
const cx = x + w / 2;
|
|
2585
|
-
const cy = y + h / 2;
|
|
2586
|
-
return `M${x},${cy - dot * .4} L${x + w},${cy - dot * .4} L${x + w},${cy + dot * .4} L${x},${cy + dot * .4} Z M${cx - dot},${y + h * .18} A${dot},${dot} 0 1 0 ${cx + dot},${y + h * .18} A${dot},${dot} 0 1 0 ${cx - dot},${y + h * .18} Z M${cx - dot},${y + h * .82} A${dot},${dot} 0 1 0 ${cx + dot},${y + h * .82} A${dot},${dot} 0 1 0 ${cx - dot},${y + h * .82} Z`;
|
|
2587
|
-
},
|
|
2588
|
-
mathEqual: (x, y, w, h) => {
|
|
2589
|
-
const t = h * .2;
|
|
2590
|
-
return `M${x},${y + h * .3 - t / 2} L${x + w},${y + h * .3 - t / 2} L${x + w},${y + h * .3 + t / 2} L${x},${y + h * .3 + t / 2} Z M${x},${y + h * .7 - t / 2} L${x + w},${y + h * .7 - t / 2} L${x + w},${y + h * .7 + t / 2} L${x},${y + h * .7 + t / 2} Z`;
|
|
2591
|
-
},
|
|
2592
|
-
mathNotEqual: (x, y, w, h) => {
|
|
2593
|
-
const t = h * .15;
|
|
2594
|
-
const cy = y + h / 2;
|
|
2595
|
-
return `M${x},${cy - h * .18 - t / 2} L${x + w},${cy - h * .18 - t / 2} L${x + w},${cy - h * .18 + t / 2} L${x},${cy - h * .18 + t / 2} Z M${x},${cy + h * .18 - t / 2} L${x + w},${cy + h * .18 - t / 2} L${x + w},${cy + h * .18 + t / 2} L${x},${cy + h * .18 + t / 2} Z M${x + w * .7},${y} L${x + w * .85},${y} L${x + w * .3},${y + h} L${x + w * .15},${y + h} Z`;
|
|
2596
|
-
},
|
|
2597
|
-
actionButtonBlank: (x, y, w, h) => {
|
|
2598
|
-
const r = Math.min(w, h) * .06;
|
|
2599
|
-
return `M${x + r},${y} L${x + w - r},${y} A${r},${r} 0 0 1 ${x + w},${y + r} L${x + w},${y + h - r} A${r},${r} 0 0 1 ${x + w - r},${y + h} L${x + r},${y + h} A${r},${r} 0 0 1 ${x},${y + h - r} L${x},${y + r} A${r},${r} 0 0 1 ${x + r},${y} Z`;
|
|
2600
|
-
},
|
|
2601
|
-
irregularSeal1: (x, y, w, h) => {
|
|
2602
|
-
const cx = x + w / 2;
|
|
2603
|
-
const cy = y + h / 2;
|
|
2604
|
-
const rx = w / 2;
|
|
2605
|
-
const ry = h / 2;
|
|
2606
|
-
const offsets = [
|
|
2607
|
-
1,
|
|
2608
|
-
.45,
|
|
2609
|
-
.95,
|
|
2610
|
-
.5,
|
|
2611
|
-
1,
|
|
2612
|
-
.4,
|
|
2613
|
-
.9,
|
|
2614
|
-
.55,
|
|
2615
|
-
1,
|
|
2616
|
-
.45,
|
|
2617
|
-
.95,
|
|
2618
|
-
.5,
|
|
2619
|
-
1,
|
|
2620
|
-
.4,
|
|
2621
|
-
.9,
|
|
2622
|
-
.55
|
|
2623
|
-
];
|
|
2624
|
-
const points = [];
|
|
2625
|
-
for (let i = 0; i < offsets.length; i++) {
|
|
2626
|
-
const a = i / offsets.length * 2 * Math.PI - Math.PI / 2;
|
|
2627
|
-
const r = offsets[i] ?? 1;
|
|
2628
|
-
const px0 = cx + rx * r * Math.cos(a);
|
|
2629
|
-
const py0 = cy + ry * r * Math.sin(a);
|
|
2630
|
-
points.push(`${i === 0 ? "M" : "L"}${px0},${py0}`);
|
|
2631
|
-
}
|
|
2632
|
-
points.push("Z");
|
|
2633
|
-
return points.join(" ");
|
|
2634
|
-
},
|
|
2635
|
-
irregularSeal2: (x, y, w, h) => {
|
|
2636
|
-
const cx = x + w / 2;
|
|
2637
|
-
const cy = y + h / 2;
|
|
2638
|
-
const rx = w / 2;
|
|
2639
|
-
const ry = h / 2;
|
|
2640
|
-
const offsets = [
|
|
2641
|
-
1,
|
|
2642
|
-
.4,
|
|
2643
|
-
.95,
|
|
2644
|
-
.5,
|
|
2645
|
-
.9,
|
|
2646
|
-
.35,
|
|
2647
|
-
.85,
|
|
2648
|
-
.45,
|
|
2649
|
-
1,
|
|
2650
|
-
.4,
|
|
2651
|
-
.95,
|
|
2652
|
-
.5,
|
|
2653
|
-
.9,
|
|
2654
|
-
.35,
|
|
2655
|
-
.85,
|
|
2656
|
-
.45,
|
|
2657
|
-
1,
|
|
2658
|
-
.4,
|
|
2659
|
-
.95,
|
|
2660
|
-
.5,
|
|
2661
|
-
.9,
|
|
2662
|
-
.35,
|
|
2663
|
-
.85,
|
|
2664
|
-
.45
|
|
2665
|
-
];
|
|
2666
|
-
const points = [];
|
|
2667
|
-
for (let i = 0; i < offsets.length; i++) {
|
|
2668
|
-
const a = i / offsets.length * 2 * Math.PI - Math.PI / 2;
|
|
2669
|
-
const r = offsets[i] ?? 1;
|
|
2670
|
-
const px0 = cx + rx * r * Math.cos(a);
|
|
2671
|
-
const py0 = cy + ry * r * Math.sin(a);
|
|
2672
|
-
points.push(`${i === 0 ? "M" : "L"}${px0},${py0}`);
|
|
2673
|
-
}
|
|
2674
|
-
points.push("Z");
|
|
2675
|
-
return points.join(" ");
|
|
2676
|
-
},
|
|
2677
|
-
cloud: (x, y, w, h) => {
|
|
2678
|
-
const cx = x + w / 2;
|
|
2679
|
-
const cy = y + h / 2;
|
|
2680
|
-
const rx = w / 2 * .92;
|
|
2681
|
-
const ry = h / 2 * .85;
|
|
2682
|
-
const lobes = 10;
|
|
2683
|
-
const path = [];
|
|
2684
|
-
for (let i = 0; i < lobes; i++) {
|
|
2685
|
-
const a = i / lobes * 2 * Math.PI - Math.PI / 2;
|
|
2686
|
-
const lobeRx = rx * .32;
|
|
2687
|
-
const lobeRy = ry * .32;
|
|
2688
|
-
const px0 = cx + rx * Math.cos(a);
|
|
2689
|
-
const py0 = cy + ry * Math.sin(a);
|
|
2690
|
-
if (i === 0) path.push(`M${px0 - lobeRx},${py0}`);
|
|
2691
|
-
path.push(`A${lobeRx},${lobeRy} 0 1 1 ${px0 + lobeRx},${py0}`);
|
|
2692
|
-
const nextA = (i + 1) / lobes * 2 * Math.PI - Math.PI / 2;
|
|
2693
|
-
const nextX = cx + rx * Math.cos(nextA) - lobeRx;
|
|
2694
|
-
const nextY = cy + ry * Math.sin(nextA);
|
|
2695
|
-
path.push(`L${nextX},${nextY}`);
|
|
2696
|
-
}
|
|
2697
|
-
path.push("Z");
|
|
2698
|
-
return path.join(" ");
|
|
2699
|
-
},
|
|
2700
|
-
pie: (x, y, w, h) => {
|
|
2701
|
-
const cx = x + w / 2;
|
|
2702
|
-
const cy = y + h / 2;
|
|
2703
|
-
const r = Math.min(w, h) / 2;
|
|
2704
|
-
return `M${cx},${cy} L${cx + r},${cy} A${r},${r} 0 1 1 ${cx},${cy - r} Z`;
|
|
2705
|
-
},
|
|
2706
|
-
chord: (x, y, w, h) => {
|
|
2707
|
-
const cx = x + w / 2;
|
|
2708
|
-
const cy = y + h / 2;
|
|
2709
|
-
const rx = w / 2;
|
|
2710
|
-
const ry = h / 2;
|
|
2711
|
-
return `M${cx + rx},${cy} A${rx},${ry} 0 1 1 ${cx - rx},${cy} L${cx + rx},${cy} Z`;
|
|
2712
|
-
},
|
|
2713
|
-
teardrop: (x, y, w, h) => {
|
|
2714
|
-
const cx = x + w / 2;
|
|
2715
|
-
const cy = y + h / 2;
|
|
2716
|
-
const rx = w / 2;
|
|
2717
|
-
const ry = h / 2;
|
|
2718
|
-
return `M${cx},${y} L${x + w},${y} L${x + w},${cy} A${rx},${ry} 0 1 1 ${cx - rx},${cy} A${rx},${ry} 0 0 1 ${cx},${y} Z`;
|
|
2719
|
-
},
|
|
2720
|
-
arc: (x, y, w, h) => {
|
|
2721
|
-
const cx = x + w / 2;
|
|
2722
|
-
const cy = y + h / 2;
|
|
2723
|
-
const rx = w / 2;
|
|
2724
|
-
const ry = h / 2;
|
|
2725
|
-
return `M${cx + rx},${cy} A${rx},${ry} 0 1 1 ${cx},${cy + ry}`;
|
|
2726
|
-
},
|
|
2727
|
-
blockArc: (x, y, w, h) => {
|
|
2728
|
-
const cx = x + w / 2;
|
|
2729
|
-
const cy = y + h / 2;
|
|
2730
|
-
const outerR = Math.min(w, h) / 2;
|
|
2731
|
-
const innerR = outerR * .6;
|
|
2732
|
-
return `M${cx + outerR},${cy} A${outerR},${outerR} 0 1 1 ${cx},${cy - outerR} L${cx},${cy - innerR} A${innerR},${innerR} 0 1 0 ${cx + innerR},${cy} Z`;
|
|
2733
|
-
},
|
|
2734
|
-
moon: (x, y, w, h) => {
|
|
2735
|
-
const cx = x + w / 2;
|
|
2736
|
-
const cy = y + h / 2;
|
|
2737
|
-
const rx = w / 2;
|
|
2738
|
-
const ry = h / 2;
|
|
2739
|
-
const innerRx = rx * .78;
|
|
2740
|
-
const offsetX = rx * .32;
|
|
2741
|
-
return `M${cx + rx},${cy} A${rx},${ry} 0 1 1 ${cx - rx},${cy} A${rx},${ry} 0 1 1 ${cx + rx},${cy} M${cx - rx + offsetX + innerRx},${cy} A${innerRx},${ry * .95} 0 1 1 ${cx - rx + offsetX - innerRx},${cy} A${innerRx},${ry * .95} 0 1 1 ${cx - rx + offsetX + innerRx},${cy}`;
|
|
2742
|
-
},
|
|
2743
|
-
plus: (x, y, w, h) => {
|
|
2744
|
-
const t = Math.min(w, h) * .3;
|
|
2745
|
-
const cx = x + w / 2;
|
|
2746
|
-
const cy = y + h / 2;
|
|
2747
|
-
return `M${cx - t / 2},${y} L${cx + t / 2},${y} L${cx + t / 2},${cy - t / 2} L${x + w},${cy - t / 2} L${x + w},${cy + t / 2} L${cx + t / 2},${cy + t / 2} L${cx + t / 2},${y + h} L${cx - t / 2},${y + h} L${cx - t / 2},${cy + t / 2} L${x},${cy + t / 2} L${x},${cy - t / 2} L${cx - t / 2},${cy - t / 2} Z`;
|
|
2748
|
-
},
|
|
2749
|
-
plaque: (x, y, w, h) => {
|
|
2750
|
-
const r = Math.min(w, h) * .18;
|
|
2751
|
-
return `M${x + r},${y} L${x + w - r},${y} A${r},${r} 0 0 0 ${x + w},${y + r} L${x + w},${y + h - r} A${r},${r} 0 0 0 ${x + w - r},${y + h} L${x + r},${y + h} A${r},${r} 0 0 0 ${x},${y + h - r} L${x},${y + r} A${r},${r} 0 0 0 ${x + r},${y} Z`;
|
|
2752
|
-
},
|
|
2753
|
-
can: (x, y, w, h) => {
|
|
2754
|
-
const er = h * .12;
|
|
2755
|
-
return `M${x},${y + er} A${w / 2},${er} 0 0 1 ${x + w},${y + er} L${x + w},${y + h - er} A${w / 2},${er} 0 0 1 ${x},${y + h - er} Z M${x},${y + er} A${w / 2},${er} 0 0 0 ${x + w},${y + er}`;
|
|
2756
|
-
},
|
|
2757
|
-
cube: (x, y, w, h) => {
|
|
2758
|
-
const d = Math.min(w, h) * .2;
|
|
2759
|
-
return `M${x},${y + d} L${x + d},${y} L${x + w},${y} L${x + w},${y + h - d} L${x + w - d},${y + h} L${x},${y + h} Z M${x},${y + d} L${x + w - d},${y + d} L${x + w},${y} M${x + w - d},${y + d} L${x + w - d},${y + h}`;
|
|
2760
|
-
},
|
|
2761
|
-
bevel: (x, y, w, h) => {
|
|
2762
|
-
const d = Math.min(w, h) * .12;
|
|
2763
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} Z M${x + d},${y + d} L${x + w - d},${y + d} L${x + w - d},${y + h - d} L${x + d},${y + h - d} Z M${x},${y} L${x + d},${y + d} M${x + w},${y} L${x + w - d},${y + d} M${x},${y + h} L${x + d},${y + h - d} M${x + w},${y + h} L${x + w - d},${y + h - d}`;
|
|
2764
|
-
},
|
|
2765
|
-
donut: (x, y, w, h) => {
|
|
2766
|
-
const cx = x + w / 2;
|
|
2767
|
-
const cy = y + h / 2;
|
|
2768
|
-
const r = Math.min(w, h) / 2;
|
|
2769
|
-
const innerR = r * .65;
|
|
2770
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 0 ${cx - r},${cy} A${r},${r} 0 1 0 ${cx + r},${cy} Z M${cx + innerR},${cy} A${innerR},${innerR} 0 1 1 ${cx - innerR},${cy} A${innerR},${innerR} 0 1 1 ${cx + innerR},${cy} Z`;
|
|
2771
|
-
},
|
|
2772
|
-
noSmoking: (x, y, w, h) => {
|
|
2773
|
-
const cx = x + w / 2;
|
|
2774
|
-
const cy = y + h / 2;
|
|
2775
|
-
const r = Math.min(w, h) / 2;
|
|
2776
|
-
const innerR = r * .78;
|
|
2777
|
-
const t = r * .12;
|
|
2778
|
-
return `M${cx + r},${cy} A${r},${r} 0 1 0 ${cx - r},${cy} A${r},${r} 0 1 0 ${cx + r},${cy} Z M${cx + innerR},${cy} A${innerR},${innerR} 0 1 1 ${cx - innerR},${cy} A${innerR},${innerR} 0 1 1 ${cx + innerR},${cy} Z M${cx - r * .71 - t},${cy - r * .71 + t} L${cx - r * .71 + t},${cy - r * .71 - t} L${cx + r * .71 + t},${cy + r * .71 - t} L${cx + r * .71 - t},${cy + r * .71 + t} Z`;
|
|
2779
|
-
},
|
|
2780
|
-
frame: (x, y, w, h) => {
|
|
2781
|
-
const f = Math.min(w, h) * .1;
|
|
2782
|
-
return `M${x},${y} L${x + w},${y} L${x + w},${y + h} L${x},${y + h} Z M${x + f},${y + f} L${x + f},${y + h - f} L${x + w - f},${y + h - f} L${x + w - f},${y + f} Z`;
|
|
2783
|
-
},
|
|
2784
|
-
halfFrame: (x, y, w, h) => {
|
|
2785
|
-
const f = Math.min(w, h) * .15;
|
|
2786
|
-
return `M${x},${y} L${x + w},${y} L${x + w - f},${y + f} L${x + f},${y + f} L${x + f},${y + h - f} L${x},${y + h} Z`;
|
|
2787
|
-
},
|
|
2788
|
-
corner: (x, y, w, h) => {
|
|
2789
|
-
const tx = w * .4;
|
|
2790
|
-
const ty = h * .4;
|
|
2791
|
-
return `M${x},${y} L${x + tx},${y} L${x + tx},${y + h - ty} L${x + w},${y + h - ty} L${x + w},${y + h} L${x},${y + h} Z`;
|
|
2792
|
-
},
|
|
2793
|
-
diagStripe: (x, y, w, h) => {
|
|
2794
|
-
return `M${x},${y} L${x + w * .6},${y} L${x},${y + h * .6} Z`;
|
|
2795
|
-
},
|
|
2796
|
-
ellipseRibbon: (x, y, w, h) => {
|
|
2797
|
-
const notch = w * .08;
|
|
2798
|
-
const bodyTop = y + h * .2;
|
|
2799
|
-
const bodyBot = y + h * .85;
|
|
2800
|
-
const arcDip = h * .15;
|
|
2801
|
-
return `M${x},${bodyTop} C${x + w * .3},${bodyTop - arcDip} ${x + w * .7},${bodyTop - arcDip} ${x + w},${bodyTop} L${x + w * .85},${bodyTop + (bodyBot - bodyTop) / 2} L${x + w},${bodyBot} L${x + w - notch * 2},${y + h} L${x + w - notch * 4},${bodyBot} C${x + w * .7},${bodyBot + arcDip * .4} ${x + w * .3},${bodyBot + arcDip * .4} L${x + notch * 4},${bodyBot} L${x + notch * 2},${y + h} L${x},${bodyBot} L${x + w * .15},${bodyTop + (bodyBot - bodyTop) / 2} Z`;
|
|
2802
|
-
},
|
|
2803
|
-
ellipseRibbon2: (x, y, w, h) => {
|
|
2804
|
-
const notch = w * .08;
|
|
2805
|
-
const bodyTop = y + h * .15;
|
|
2806
|
-
const bodyBot = y + h * .8;
|
|
2807
|
-
const arcRise = h * .15;
|
|
2808
|
-
return `M${x},${bodyBot} C${x + w * .3},${bodyBot + arcRise} ${x + w * .7},${bodyBot + arcRise} ${x + w},${bodyBot} L${x + w * .85},${bodyTop + (bodyBot - bodyTop) / 2} L${x + w},${bodyTop} L${x + w - notch * 2},${y} L${x + w - notch * 4},${bodyTop} C${x + w * .7},${bodyTop - arcRise * .4} ${x + w * .3},${bodyTop - arcRise * .4} L${x + notch * 4},${bodyTop} L${x + notch * 2},${y} L${x},${bodyTop} L${x + w * .15},${bodyTop + (bodyBot - bodyTop) / 2} Z`;
|
|
2809
|
-
},
|
|
2810
|
-
quadArrow: (x, y, w, h) => {
|
|
2811
|
-
const cx = x + w / 2;
|
|
2812
|
-
const cy = y + h / 2;
|
|
2813
|
-
const tip = .2;
|
|
2814
|
-
const stem = .15;
|
|
2815
|
-
const headW = .35;
|
|
2816
|
-
return `M${cx},${y} L${cx + headW * w},${y + tip * h} L${cx + stem * w},${y + tip * h} L${cx + stem * w},${cy - stem * h} L${x + w - tip * w},${cy - stem * h} L${x + w - tip * w},${cy - headW * h} L${x + w},${cy} L${x + w - tip * w},${cy + headW * h} L${x + w - tip * w},${cy + stem * h} L${cx + stem * w},${cy + stem * h} L${cx + stem * w},${y + h - tip * h} L${cx + headW * w},${y + h - tip * h} L${cx},${y + h} L${cx - headW * w},${y + h - tip * h} L${cx - stem * w},${y + h - tip * h} L${cx - stem * w},${cy + stem * h} L${x + tip * w},${cy + stem * h} L${x + tip * w},${cy + headW * h} L${x},${cy} L${x + tip * w},${cy - headW * h} L${x + tip * w},${cy - stem * h} L${cx - stem * w},${cy - stem * h} L${cx - stem * w},${y + tip * h} L${cx - headW * w},${y + tip * h} Z`;
|
|
2817
|
-
},
|
|
2818
|
-
leftRightUpArrow: (x, y, w, h) => {
|
|
2819
|
-
const cx = x + w / 2;
|
|
2820
|
-
const tip = .2;
|
|
2821
|
-
const stem = .15;
|
|
2822
|
-
const headW = .35;
|
|
2823
|
-
return `M${cx},${y} L${cx + headW * w},${y + tip * h} L${cx + stem * w},${y + tip * h} L${cx + stem * w},${y + h - tip * h} L${x + w - tip * w},${y + h - tip * h} L${x + w - tip * w},${y + h - headW * h} L${x + w},${y + h} L${x + w - tip * w},${y + h + headW * h} L${x + w - tip * w},${y + h - tip * h} L${cx - stem * w},${y + h - tip * h} L${cx - stem * w},${y + tip * h} L${cx - headW * w},${y + tip * h} Z`;
|
|
2824
|
-
},
|
|
2825
|
-
bentUpArrow: (x, y, w, h) => {
|
|
2826
|
-
const stem = .3;
|
|
2827
|
-
const tip = .25;
|
|
2828
|
-
return `M${x},${y + h * .55} L${x + w * .5},${y + h * .55} L${x + w * .5},${y + tip * h} L${x + w * (.5 - stem * .5)},${y + tip * h} L${x + w * .75},${y} L${x + w},${y + tip * h} L${x + w * .65},${y + tip * h} L${x + w * .65},${y + h * .55 + h * .4} L${x},${y + h * .55 + h * .4} Z`;
|
|
2829
|
-
},
|
|
2830
|
-
curvedLeftArrow: (x, y, w, h) => {
|
|
2831
|
-
return `M${x + w},${y + h * .6} Q${x + w * .5},${y} ${x + w * .15},${y + h * .25} L${x},${y + h * .45} L${x + w * .15},${y + h * .55} L${x + w * .3},${y + h * .35} Q${x + w * .55},${y + h * .18} ${x + w * .85},${y + h * .75} Z`;
|
|
2832
|
-
},
|
|
2833
|
-
curvedUpArrow: (x, y, w, h) => {
|
|
2834
|
-
return `M${x + w * .4},${y + h} Q${x},${y + h * .5} ${x + w * .25},${y + h * .15} L${x + w * .45},${y} L${x + w * .55},${y + h * .15} L${x + w * .35},${y + h * .3} Q${x + w * .18},${y + h * .55} ${x + w * .75},${y + h * .85} Z`;
|
|
2835
|
-
},
|
|
2836
|
-
curvedDownArrow: (x, y, w, h) => {
|
|
2837
|
-
return `M${x + w * .4},${y} Q${x},${y + h * .5} ${x + w * .25},${y + h * .85} L${x + w * .45},${y + h} L${x + w * .55},${y + h * .85} L${x + w * .35},${y + h * .7} Q${x + w * .18},${y + h * .45} ${x + w * .75},${y + h * .15} Z`;
|
|
2838
|
-
},
|
|
2839
|
-
swooshArrow: (x, y, w, h) => {
|
|
2840
|
-
return `M${x},${y + h * .75} C${x + w * .35},${y + h} ${x + w * .65},${y + h * .3} ${x + w * .75},${y + h * .2} L${x + w * .65},${y + h * .05} L${x + w},${y + h * .18} L${x + w * .78},${y + h * .45} L${x + w * .7},${y + h * .3} C${x + w * .55},${y + h * .6} ${x + w * .35},${y + h * .9} ${x},${y + h * .85} Z`;
|
|
2841
|
-
},
|
|
2842
|
-
circularArrow: (x, y, w, h) => {
|
|
2843
|
-
const cx = x + w / 2;
|
|
2844
|
-
const cy = y + h / 2;
|
|
2845
|
-
const outerR = Math.min(w, h) / 2;
|
|
2846
|
-
const innerR = outerR * .62;
|
|
2847
|
-
const midR = (outerR + innerR) / 2;
|
|
2848
|
-
return `M${cx},${cy - outerR} A${outerR},${outerR} 0 1 1 ${cx - outerR},${cy} L${cx - midR - midR * .25},${cy + outerR * .15} L${cx - midR + midR * .25},${cy + outerR * .3} L${cx - innerR},${cy} A${innerR},${innerR} 0 1 0 ${cx},${cy - innerR} Z`;
|
|
2849
|
-
},
|
|
2850
|
-
leftCircularArrow: (x, y, w, h) => {
|
|
2851
|
-
const cx = x + w / 2;
|
|
2852
|
-
const cy = y + h / 2;
|
|
2853
|
-
const outerR = Math.min(w, h) / 2;
|
|
2854
|
-
const innerR = outerR * .62;
|
|
2855
|
-
return `M${cx},${cy - outerR} A${outerR},${outerR} 0 1 0 ${cx + outerR},${cy} L${cx + (outerR + innerR) / 2 + (outerR + innerR) / 2 * .25},${cy + outerR * .15} L${cx + (outerR + innerR) / 2 - (outerR + innerR) / 2 * .25},${cy + outerR * .3} L${cx + innerR},${cy} A${innerR},${innerR} 0 1 1 ${cx},${cy - innerR} Z`;
|
|
2856
|
-
},
|
|
2857
|
-
leftRightCircularArrow: (x, y, w, h) => {
|
|
2858
|
-
const cx = x + w / 2;
|
|
2859
|
-
const cy = y + h / 2;
|
|
2860
|
-
const outerR = Math.min(w, h) / 2;
|
|
2861
|
-
const innerR = outerR * .62;
|
|
2862
|
-
return `M${cx - outerR * .15},${cy - outerR * 1.05} L${cx + outerR * .15},${cy - outerR * 1.05} L${cx + outerR * .1},${cy - outerR * .85} A${outerR},${outerR} 0 1 1 ${cx - outerR * .1},${cy - outerR * .85} Z M${cx},${cy - innerR} A${innerR},${innerR} 0 1 0 ${cx},${cy + innerR}`;
|
|
2863
|
-
},
|
|
2864
|
-
rightArrowCallout: (x, y, w, h) => {
|
|
2865
|
-
const headW = w * .25;
|
|
2866
|
-
return `M${x},${y + h * .3} L${x + w - headW},${y + h * .3} L${x + w - headW},${y} L${x + w},${y + h / 2} L${x + w - headW},${y + h} L${x + w - headW},${y + h * .7} L${x},${y + h * .7} Z`;
|
|
2867
|
-
},
|
|
2868
|
-
leftArrowCallout: (x, y, w, h) => {
|
|
2869
|
-
const headW = w * .25;
|
|
2870
|
-
return `M${x + headW},${y + h * .3} L${x + w},${y + h * .3} L${x + w},${y + h * .7} L${x + headW},${y + h * .7} L${x + headW},${y + h} L${x},${y + h / 2} L${x + headW},${y} Z`;
|
|
2871
|
-
},
|
|
2872
|
-
upArrowCallout: (x, y, w, h) => {
|
|
2873
|
-
const headH = h * .25;
|
|
2874
|
-
return `M${x + w * .3},${y + headH} L${x + w * .3},${y + h} L${x + w * .7},${y + h} L${x + w * .7},${y + headH} L${x + w},${y + headH} L${x + w / 2},${y} L${x},${y + headH} Z`;
|
|
2875
|
-
},
|
|
2876
|
-
downArrowCallout: (x, y, w, h) => {
|
|
2877
|
-
const headH = h * .25;
|
|
2878
|
-
return `M${x + w * .3},${y} L${x + w * .7},${y} L${x + w * .7},${y + h - headH} L${x + w},${y + h - headH} L${x + w / 2},${y + h} L${x},${y + h - headH} L${x + w * .3},${y + h - headH} Z`;
|
|
2879
|
-
},
|
|
2880
|
-
leftRightArrowCallout: (x, y, w, h) => {
|
|
2881
|
-
const headW = w * .2;
|
|
2882
|
-
return `M${x},${y + h / 2} L${x + headW},${y} L${x + headW},${y + h * .3} L${x + w - headW},${y + h * .3} L${x + w - headW},${y} L${x + w},${y + h / 2} L${x + w - headW},${y + h} L${x + w - headW},${y + h * .7} L${x + headW},${y + h * .7} L${x + headW},${y + h} Z`;
|
|
2883
|
-
},
|
|
2884
|
-
upDownArrowCallout: (x, y, w, h) => {
|
|
2885
|
-
const headH = h * .2;
|
|
2886
|
-
return `M${x + w / 2},${y} L${x},${y + headH} L${x + w * .3},${y + headH} L${x + w * .3},${y + h - headH} L${x},${y + h - headH} L${x + w / 2},${y + h} L${x + w},${y + h - headH} L${x + w * .7},${y + h - headH} L${x + w * .7},${y + headH} L${x + w},${y + headH} Z`;
|
|
2887
|
-
},
|
|
2888
|
-
quadArrowCallout: (x, y, w, h) => {
|
|
2889
|
-
const cx = x + w / 2;
|
|
2890
|
-
const cy = y + h / 2;
|
|
2891
|
-
const tip = .16;
|
|
2892
|
-
const stem = .18;
|
|
2893
|
-
const headW = .32;
|
|
2894
|
-
const txt = .28;
|
|
2895
|
-
return `M${cx - txt * w},${cy - txt * h} L${cx - txt * w},${cy - stem * h} L${cx - stem * w},${cy - stem * h} L${cx - stem * w},${y + tip * h} L${cx - headW * w},${y + tip * h} L${cx},${y} L${cx + headW * w},${y + tip * h} L${cx + stem * w},${y + tip * h} L${cx + stem * w},${cy - stem * h} L${cx + txt * w},${cy - stem * h} L${cx + txt * w},${cy - txt * h} L${x + w - tip * w},${cy - txt * h} L${x + w - tip * w},${cy - headW * h} L${x + w},${cy} L${x + w - tip * w},${cy + headW * h} L${x + w - tip * w},${cy + txt * h} L${cx + txt * w},${cy + txt * h} L${cx + txt * w},${cy + stem * h} L${cx + stem * w},${cy + stem * h} L${cx + stem * w},${y + h - tip * h} L${cx + headW * w},${y + h - tip * h} L${cx},${y + h} L${cx - headW * w},${y + h - tip * h} L${cx - stem * w},${y + h - tip * h} L${cx - stem * w},${cy + stem * h} L${cx - txt * w},${cy + stem * h} L${cx - txt * w},${cy + txt * h} L${x + tip * w},${cy + txt * h} L${x + tip * w},${cy + headW * h} L${x},${cy} L${x + tip * w},${cy - headW * h} L${x + tip * w},${cy - txt * h} Z`;
|
|
2896
|
-
},
|
|
2897
|
-
actionButtonHome: (x, y, w, h) => {
|
|
2898
|
-
const cx = x + w / 2;
|
|
2899
|
-
const cy = y + h / 2;
|
|
2900
|
-
const s = Math.min(w, h) * .3;
|
|
2901
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s},${cy + s * .6} L${cx - s},${cy - s * .1} L${cx},${cy - s * .7} L${cx + s},${cy - s * .1} L${cx + s},${cy + s * .6} L${cx + s * .3},${cy + s * .6} L${cx + s * .3},${cy + s * .1} L${cx - s * .3},${cy + s * .1} L${cx - s * .3},${cy + s * .6} Z`;
|
|
2902
|
-
},
|
|
2903
|
-
actionButtonForwardNext: (x, y, w, h) => {
|
|
2904
|
-
const cx = x + w / 2;
|
|
2905
|
-
const cy = y + h / 2;
|
|
2906
|
-
const s = Math.min(w, h) * .3;
|
|
2907
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s * .7},${cy - s} L${cx + s * .7},${cy} L${cx - s * .7},${cy + s} Z`;
|
|
2908
|
-
},
|
|
2909
|
-
actionButtonBackPrevious: (x, y, w, h) => {
|
|
2910
|
-
const cx = x + w / 2;
|
|
2911
|
-
const cy = y + h / 2;
|
|
2912
|
-
const s = Math.min(w, h) * .3;
|
|
2913
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx + s * .7},${cy - s} L${cx - s * .7},${cy} L${cx + s * .7},${cy + s} Z`;
|
|
2914
|
-
},
|
|
2915
|
-
actionButtonEnd: (x, y, w, h) => {
|
|
2916
|
-
const cx = x + w / 2;
|
|
2917
|
-
const cy = y + h / 2;
|
|
2918
|
-
const s = Math.min(w, h) * .3;
|
|
2919
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s},${cy - s} L${cx + s * .4},${cy} L${cx - s},${cy + s} Z M${cx + s * .5},${cy - s} L${cx + s},${cy - s} L${cx + s},${cy + s} L${cx + s * .5},${cy + s} Z`;
|
|
2920
|
-
},
|
|
2921
|
-
actionButtonBeginning: (x, y, w, h) => {
|
|
2922
|
-
const cx = x + w / 2;
|
|
2923
|
-
const cy = y + h / 2;
|
|
2924
|
-
const s = Math.min(w, h) * .3;
|
|
2925
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx + s},${cy - s} L${cx - s * .4},${cy} L${cx + s},${cy + s} Z M${cx - s * .5},${cy - s} L${cx - s},${cy - s} L${cx - s},${cy + s} L${cx - s * .5},${cy + s} Z`;
|
|
2926
|
-
},
|
|
2927
|
-
actionButtonReturn: (x, y, w, h) => {
|
|
2928
|
-
const cx = x + w / 2;
|
|
2929
|
-
const cy = y + h / 2;
|
|
2930
|
-
const s = Math.min(w, h) * .28;
|
|
2931
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx + s},${cy - s} L${cx + s * .4},${cy - s} L${cx + s * .4},${cy + s * .2} L${cx - s * .2},${cy + s * .2} L${cx - s * .2},${cy - s * .2} L${cx - s},${cy + s * .2} L${cx - s * .2},${cy + s} L${cx - s * .2},${cy + s * .5} L${cx + s},${cy + s * .5} Z`;
|
|
2932
|
-
},
|
|
2933
|
-
actionButtonHelp: (x, y, w, h) => {
|
|
2934
|
-
const cx = x + w / 2;
|
|
2935
|
-
const cy = y + h / 2;
|
|
2936
|
-
const s = Math.min(w, h) * .3;
|
|
2937
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s * .4},${cy - s * .4} Q${cx - s * .4},${cy - s} ${cx},${cy - s} Q${cx + s * .4},${cy - s} ${cx + s * .4},${cy - s * .4} Q${cx + s * .4},${cy} ${cx},${cy} L${cx},${cy + s * .4} M${cx - s * .18},${cy + s * .8} L${cx + s * .18},${cy + s * .8} L${cx + s * .18},${cy + s} L${cx - s * .18},${cy + s} Z`;
|
|
2938
|
-
},
|
|
2939
|
-
actionButtonInformation: (x, y, w, h) => {
|
|
2940
|
-
const cx = x + w / 2;
|
|
2941
|
-
const cy = y + h / 2;
|
|
2942
|
-
const s = Math.min(w, h) * .3;
|
|
2943
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s * .2},${cy - s * .7} L${cx + s * .2},${cy - s * .7} L${cx + s * .2},${cy - s * .35} L${cx - s * .2},${cy - s * .35} Z M${cx - s * .2},${cy - s * .1} L${cx + s * .2},${cy - s * .1} L${cx + s * .2},${cy + s} L${cx - s * .2},${cy + s} Z`;
|
|
2944
|
-
},
|
|
2945
|
-
actionButtonDocument: (x, y, w, h) => {
|
|
2946
|
-
const cx = x + w / 2;
|
|
2947
|
-
const cy = y + h / 2;
|
|
2948
|
-
const s = Math.min(w, h) * .3;
|
|
2949
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s * .6},${cy - s} L${cx + s * .3},${cy - s} L${cx + s * .6},${cy - s * .7} L${cx + s * .6},${cy + s} L${cx - s * .6},${cy + s} Z M${cx + s * .3},${cy - s} L${cx + s * .3},${cy - s * .7} L${cx + s * .6},${cy - s * .7}`;
|
|
2950
|
-
},
|
|
2951
|
-
actionButtonSound: (x, y, w, h) => {
|
|
2952
|
-
const cx = x + w / 2;
|
|
2953
|
-
const cy = y + h / 2;
|
|
2954
|
-
const s = Math.min(w, h) * .3;
|
|
2955
|
-
return `${PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""} M${cx - s},${cy - s * .4} L${cx - s * .3},${cy - s * .4} L${cx + s * .3},${cy - s} L${cx + s * .3},${cy + s} L${cx - s * .3},${cy + s * .4} L${cx - s},${cy + s * .4} Z M${cx + s * .55},${cy - s * .4} Q${cx + s * .95},${cy} ${cx + s * .55},${cy + s * .4}`;
|
|
2956
|
-
},
|
|
2957
|
-
actionButtonMovie: (x, y, w, h) => {
|
|
2958
|
-
const cx = x + w / 2;
|
|
2959
|
-
const cy = y + h / 2;
|
|
2960
|
-
const s = Math.min(w, h) * .3;
|
|
2961
|
-
const out = [PRESET_PATHS.actionButtonBlank?.(x, y, w, h) ?? ""];
|
|
2962
|
-
out.push(`M${cx - s},${cy - s * .6} L${cx + s},${cy - s * .6} L${cx + s},${cy + s * .6} L${cx - s},${cy + s * .6} Z`);
|
|
2963
|
-
for (let i = 0; i < 4; i++) {
|
|
2964
|
-
const px0 = cx - s + (i + .5) * (s * 2 / 4);
|
|
2965
|
-
out.push(`M${px0 - s * .08},${cy - s * .45} L${px0 + s * .08},${cy - s * .45} L${px0 + s * .08},${cy - s * .3} L${px0 - s * .08},${cy - s * .3} Z`);
|
|
2966
|
-
out.push(`M${px0 - s * .08},${cy + s * .3} L${px0 + s * .08},${cy + s * .3} L${px0 + s * .08},${cy + s * .45} L${px0 - s * .08},${cy + s * .45} Z`);
|
|
2967
|
-
}
|
|
2968
|
-
return out.join(" ");
|
|
2969
|
-
},
|
|
2970
|
-
borderCallout1: (x, y, w, h) => {
|
|
2971
|
-
return `M${x},${y} L${x + w * .6},${y} L${x + w * .6},${y + h * .5} L${x},${y + h * .5} Z M${x + w * .6},${y + h * .5} L${x + w},${y + h}`;
|
|
2972
|
-
},
|
|
2973
|
-
borderCallout2: (x, y, w, h) => {
|
|
2974
|
-
return `M${x},${y} L${x + w * .6},${y} L${x + w * .6},${y + h * .5} L${x},${y + h * .5} Z M${x + w * .6},${y + h * .5} L${x + w * .85},${y + h * .75} L${x + w},${y + h}`;
|
|
2975
|
-
},
|
|
2976
|
-
borderCallout3: (x, y, w, h) => {
|
|
2977
|
-
return `M${x},${y} L${x + w * .6},${y} L${x + w * .6},${y + h * .5} L${x},${y + h * .5} Z M${x + w * .6},${y + h * .5} L${x + w * .75},${y + h * .65} L${x + w * .9},${y + h * .65} L${x + w},${y + h}`;
|
|
2978
|
-
},
|
|
2979
|
-
accentCallout1: (x, y, w, h) => {
|
|
2980
|
-
return `M${x},${y} L${x + w * .6},${y} L${x + w * .6},${y + h * .5} L${x},${y + h * .5} Z M${x + w * .58},${y} L${x + w * .58},${y + h * .5} M${x + w * .6},${y + h * .5} L${x + w},${y + h}`;
|
|
2981
|
-
},
|
|
2982
|
-
accentBorderCallout1: (x, y, w, h) => {
|
|
2983
|
-
return PRESET_PATHS.accentCallout1?.(x, y, w, h) ?? "";
|
|
2984
|
-
},
|
|
2985
|
-
callout1: (x, y, w, h) => {
|
|
2986
|
-
return `M${x},${y + h * .5} L${x + w},${y + h}`;
|
|
2987
|
-
},
|
|
2988
|
-
callout2: (x, y, w, h) => {
|
|
2989
|
-
return `M${x},${y + h * .5} L${x + w * .6},${y + h * .7} L${x + w},${y + h}`;
|
|
2990
|
-
},
|
|
2991
|
-
callout3: (x, y, w, h) => {
|
|
2992
|
-
return `M${x},${y + h * .5} L${x + w * .4},${y + h * .55} L${x + w * .7},${y + h * .8} L${x + w},${y + h}`;
|
|
2993
|
-
},
|
|
2994
|
-
straightConnector1: (x, y, w, h) => `M${x},${y} L${x + w},${y + h}`,
|
|
2995
|
-
bentConnector2: (x, y, w, h) => `M${x},${y} L${x + w},${y} L${x + w},${y + h}`,
|
|
2996
|
-
bentConnector3: (x, y, w, h) => `M${x},${y} L${x + w / 2},${y} L${x + w / 2},${y + h} L${x + w},${y + h}`,
|
|
2997
|
-
bentConnector4: (x, y, w, h) => `M${x},${y} L${x + w * .33},${y} L${x + w * .33},${y + h * .5} L${x + w * .66},${y + h * .5} L${x + w * .66},${y + h} L${x + w},${y + h}`,
|
|
2998
|
-
bentConnector5: (x, y, w, h) => `M${x},${y} L${x + w * .25},${y} L${x + w * .25},${y + h * .5} L${x + w * .75},${y + h * .5} L${x + w * .75},${y + h} L${x + w},${y + h}`,
|
|
2999
|
-
curvedConnector2: (x, y, w, h) => `M${x},${y} Q${x + w},${y} ${x + w},${y + h}`,
|
|
3000
|
-
curvedConnector3: (x, y, w, h) => `M${x},${y} C${x + w * .5},${y} ${x + w * .5},${y + h} ${x + w},${y + h}`,
|
|
3001
|
-
curvedConnector4: (x, y, w, h) => `M${x},${y} C${x + w * .33},${y} ${x + w * .33},${y + h * .5} ${x + w * .5},${y + h * .5} C${x + w * .66},${y + h * .5} ${x + w * .66},${y + h} ${x + w},${y + h}`,
|
|
3002
|
-
curvedConnector5: (x, y, w, h) => `M${x},${y} C${x + w * .25},${y} ${x + w * .25},${y + h * .25} ${x + w * .5},${y + h * .5} C${x + w * .75},${y + h * .75} ${x + w * .75},${y + h} ${x + w},${y + h}`
|
|
3003
|
-
};
|
|
3004
2398
|
const ALIGNMENT_TO_CSS = {
|
|
3005
2399
|
left: "left",
|
|
3006
2400
|
center: "center",
|
|
@@ -3032,7 +2426,7 @@ const cssColorWithOpacity = (hex, opacity) => {
|
|
|
3032
2426
|
};
|
|
3033
2427
|
const renderRun = (text, format, theme, effectivePt, defaultColor, _wasDefault = false, suppressLineHeight = false, lineHeightOverride = void 0) => {
|
|
3034
2428
|
if (text === "") return "";
|
|
3035
|
-
if (format?.textFill) {
|
|
2429
|
+
if (format?.textFill || format?.outline?.fill) {
|
|
3036
2430
|
const { textFill: _fill, outline: _outline, shadow: _shadow, glow: _glow, underline: _underline, strike: _strike, ...layout } = format;
|
|
3037
2431
|
return renderRun(text, {
|
|
3038
2432
|
...layout,
|
|
@@ -3092,6 +2486,10 @@ const renderRun = (text, format, theme, effectivePt, defaultColor, _wasDefault =
|
|
|
3092
2486
|
const LINE_HEIGHT = 1.05;
|
|
3093
2487
|
const AUTOFIT_FLOOR = .25;
|
|
3094
2488
|
const AUTOFIT_STEP = .05;
|
|
2489
|
+
const decimalSeparatorField = (lang) => {
|
|
2490
|
+
const separator = decimalSeparatorOf(lang);
|
|
2491
|
+
return separator === "." ? {} : { decimalSeparator: separator };
|
|
2492
|
+
};
|
|
3095
2493
|
const underlineStyleOf = (fmt) => {
|
|
3096
2494
|
const u = fmt?.underline;
|
|
3097
2495
|
if (u === void 0 || u === false || u === "none") return "none";
|
|
@@ -3121,7 +2519,7 @@ const strikeStyleOf = (fmt) => {
|
|
|
3121
2519
|
if (s === "dblStrike") return "double";
|
|
3122
2520
|
return s !== void 0 && s !== false && s !== "noStrike";
|
|
3123
2521
|
};
|
|
3124
|
-
const hasPaintedTextFill = (run) => !!run.fmt?.textFill && !run.href;
|
|
2522
|
+
const hasPaintedTextFill = (run) => !!(run.fmt?.textFill || run.fmt?.outline?.fill) && !run.href;
|
|
3125
2523
|
const alignOf = (a) => a === "center" || a === "right" || a === "justify" ? a : "left";
|
|
3126
2524
|
const verticalLayoutOf = (vert) => {
|
|
3127
2525
|
switch (vert) {
|
|
@@ -3199,7 +2597,10 @@ const buildSvgTextInput = (a) => {
|
|
|
3199
2597
|
letterSpacingPx,
|
|
3200
2598
|
kerning,
|
|
3201
2599
|
fillHex,
|
|
3202
|
-
...
|
|
2600
|
+
...hasPaintedTextFill(run) ? { fillPaint: fmt?.textFill ? textFillPaint(fmt.textFill, a.theme, fillHex) : () => ({
|
|
2601
|
+
defs: "",
|
|
2602
|
+
fill: fillHex
|
|
2603
|
+
}) } : {},
|
|
3203
2604
|
...fmt?.underlineColor !== void 0 && fmt.underlineColor !== null ? { underlineHex: resolveColor(fmt.underlineColor, a.theme, fillHex) } : {},
|
|
3204
2605
|
underline: underlineStyleOf(fmt),
|
|
3205
2606
|
strike: strikeStyleOf(fmt),
|
|
@@ -3208,6 +2609,21 @@ const buildSvgTextInput = (a) => {
|
|
|
3208
2609
|
outlineHex: resolveColor(fmt.outline.color, a.theme, "#000000"),
|
|
3209
2610
|
outlineWidthPx: (fmt.outline.widthEmu ?? 9525) / EMU_PER_PX
|
|
3210
2611
|
} : {},
|
|
2612
|
+
...fmt?.outline?.fill && !run.href ? (() => {
|
|
2613
|
+
const fill = fmt.outline.fill;
|
|
2614
|
+
const first = fill.stops[0];
|
|
2615
|
+
return {
|
|
2616
|
+
outlineHex: first ? first.resolvedColor ?? resolveColor(first.color, a.theme, "#000000") : "#000000",
|
|
2617
|
+
outlinePaint: (box) => {
|
|
2618
|
+
const built = gradientDef(fill, a.theme, "", box);
|
|
2619
|
+
return {
|
|
2620
|
+
defs: built.defs,
|
|
2621
|
+
fill: built.fillAttr
|
|
2622
|
+
};
|
|
2623
|
+
},
|
|
2624
|
+
outlineWidthPx: (fmt.outline.widthEmu ?? 9525) / EMU_PER_PX
|
|
2625
|
+
};
|
|
2626
|
+
})() : {},
|
|
3211
2627
|
...fmt?.shadow ? { shadow: {
|
|
3212
2628
|
...fmt.shadow,
|
|
3213
2629
|
...fmt.shadow.color ? { color: resolveColor(fmt.shadow.color, a.theme, "#000000") } : {}
|
|
@@ -3222,8 +2638,10 @@ const buildSvgTextInput = (a) => {
|
|
|
3222
2638
|
...fmt.innerShadow,
|
|
3223
2639
|
...fmt.innerShadow.color ? { color: resolveColor(fmt.innerShadow.color, a.theme, "#000000") } : {}
|
|
3224
2640
|
} } : {},
|
|
2641
|
+
...a.bevel ? { bevel: a.bevel } : {},
|
|
3225
2642
|
href: run.href ?? null,
|
|
3226
|
-
...run.hrefTip !== void 0 ? { hrefTip: run.hrefTip } : {}
|
|
2643
|
+
...run.hrefTip !== void 0 ? { hrefTip: run.hrefTip } : {},
|
|
2644
|
+
...run.decimalSeparator !== void 0 ? { decimalSeparator: run.decimalSeparator } : {}
|
|
3227
2645
|
};
|
|
3228
2646
|
const segs = run.text.split("\n");
|
|
3229
2647
|
segs.forEach((seg, i) => {
|
|
@@ -3373,12 +2791,12 @@ const resolveTextBodyModel = (pres, shape, bounds, theme, phType, measure, defau
|
|
|
3373
2791
|
const tIns = margins.top ?? DEFAULT_INSET_Y;
|
|
3374
2792
|
const rIns = margins.right ?? DEFAULT_INSET_X;
|
|
3375
2793
|
const bIns = margins.bottom ?? DEFAULT_INSET_Y;
|
|
3376
|
-
const { x: innerX, y: innerY, w: innerW, h: innerH } = resolveTextBodyRect(
|
|
2794
|
+
const { x: innerX, y: innerY, w: innerW, h: innerH } = resolveTextBodyRect(bounds, {
|
|
3377
2795
|
left: lIns,
|
|
3378
2796
|
top: tIns,
|
|
3379
2797
|
right: rIns,
|
|
3380
2798
|
bottom: bIns
|
|
3381
|
-
},
|
|
2799
|
+
}, shapeTextRect(shape));
|
|
3382
2800
|
if (innerW <= 0 || innerH <= 0) return null;
|
|
3383
2801
|
const svgTextRect = (v) => useSvgTextRect && v !== "none" && v !== "upright" ? {
|
|
3384
2802
|
x: bounds.x + tIns,
|
|
@@ -3455,10 +2873,11 @@ const resolveTextBodyModel = (pres, shape, bounds, theme, phType, measure, defau
|
|
|
3455
2873
|
} catch {
|
|
3456
2874
|
elements = [];
|
|
3457
2875
|
}
|
|
2876
|
+
const languages = elements.length ? getParagraphElementLanguages(shape, p) : [];
|
|
3458
2877
|
let rIdx = 0;
|
|
3459
2878
|
let fieldIndex = 0;
|
|
3460
2879
|
let breakIndex = 0;
|
|
3461
|
-
for (const el of elements) {
|
|
2880
|
+
for (const [elementIndex, el] of elements.entries()) {
|
|
3462
2881
|
if (el.kind === "br") {
|
|
3463
2882
|
const fmt = getShapeRunFormatEffective(pres, shape, p, { breakIndex: breakIndex++ });
|
|
3464
2883
|
runs.push({
|
|
@@ -3493,6 +2912,7 @@ const resolveTextBodyModel = (pres, shape, bounds, theme, phType, measure, defau
|
|
|
3493
2912
|
text: txt,
|
|
3494
2913
|
fmt,
|
|
3495
2914
|
sizePt,
|
|
2915
|
+
...decimalSeparatorField(languages[elementIndex]),
|
|
3496
2916
|
...href !== void 0 ? { href } : {},
|
|
3497
2917
|
...hrefTip !== void 0 ? { hrefTip } : {}
|
|
3498
2918
|
});
|
|
@@ -3632,9 +3052,15 @@ const renderHtmlParagraphs = (paraData, numberLabels, theme, autoFitScale, defau
|
|
|
3632
3052
|
let runFmt = run.fmt;
|
|
3633
3053
|
if (run.href) {
|
|
3634
3054
|
const hlinkColor = theme ? normalizeHex(theme.hyperlink) : "#0563C1";
|
|
3635
|
-
const { textFill: _linkFill, ...linkFmt } = runFmt ?? {};
|
|
3055
|
+
const { textFill: _linkFill, outline: linkOutline, ...linkFmt } = runFmt ?? {};
|
|
3056
|
+
const { fill: outlineFill, ...solidOutline } = linkOutline ?? {};
|
|
3057
|
+
const outlineColor = outlineFill?.stops[0]?.color ?? solidOutline.color;
|
|
3636
3058
|
runFmt = {
|
|
3637
3059
|
...linkFmt,
|
|
3060
|
+
...linkOutline ? { outline: {
|
|
3061
|
+
...solidOutline,
|
|
3062
|
+
...outlineColor !== void 0 ? { color: outlineColor } : {}
|
|
3063
|
+
} } : {},
|
|
3638
3064
|
color: hlinkColor,
|
|
3639
3065
|
underline: runFmt?.underline ?? true
|
|
3640
3066
|
};
|
|
@@ -3665,8 +3091,8 @@ const renderHtmlParagraphs = (paraData, numberLabels, theme, autoFitScale, defau
|
|
|
3665
3091
|
"padding:0",
|
|
3666
3092
|
`text-align:${ALIGNMENT_TO_CSS[para.align] ?? "left"}`,
|
|
3667
3093
|
lineHeightCss,
|
|
3668
|
-
leftPx > 0 ? `padding-
|
|
3669
|
-
rightPx > 0 ? `padding-
|
|
3094
|
+
leftPx > 0 ? `padding-inline-start:${leftPx.toFixed(2)}px` : "",
|
|
3095
|
+
rightPx > 0 ? `padding-inline-end:${rightPx.toFixed(2)}px` : "",
|
|
3670
3096
|
firstLinePx !== 0 ? `text-indent:${firstLinePx.toFixed(2)}px` : ""
|
|
3671
3097
|
].filter(Boolean);
|
|
3672
3098
|
let prefix = "";
|
|
@@ -3702,6 +3128,7 @@ const renderHtmlParagraphs = (paraData, numberLabels, theme, autoFitScale, defau
|
|
|
3702
3128
|
const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body") => {
|
|
3703
3129
|
const model = resolveTextBodyModel(pres, shape, bounds, theme, phType, ctx.measure, activeDeckTextColor, ctx.mode === "svg" && output === "body");
|
|
3704
3130
|
if (model === null) return "";
|
|
3131
|
+
const bevel = textBevelOf(getShapeText3D(shape));
|
|
3705
3132
|
const { paraData, numberLabels, authoredAutofit, autoFitScale, defaultPt, themeFace, effectiveDefaultFont, effectiveBody, anchor, innerX, innerY, innerW, innerH, svgTextRect } = model;
|
|
3706
3133
|
const defaultColor = activeDeckTextColor;
|
|
3707
3134
|
const paragraphs = renderHtmlParagraphs(paraData, numberLabels, theme, autoFitScale, defaultPt, defaultColor, effectiveBody.wrap !== "none");
|
|
@@ -3737,7 +3164,8 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
|
|
|
3737
3164
|
measure: ctx.mode === "svg" ? ctx.measure : browserTextMeasurer() ?? ctx.measure,
|
|
3738
3165
|
...ctx.mode === "foreignObject" ? { resolveFamily: browserFontFamily } : {},
|
|
3739
3166
|
vert: svgVert,
|
|
3740
|
-
columns: svgColumns
|
|
3167
|
+
columns: svgColumns,
|
|
3168
|
+
bevel
|
|
3741
3169
|
};
|
|
3742
3170
|
if (output === "effects") {
|
|
3743
3171
|
const effectArgs = {
|
|
@@ -3755,6 +3183,10 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
|
|
|
3755
3183
|
...effectArgs,
|
|
3756
3184
|
effectKind: "fill"
|
|
3757
3185
|
}) : "",
|
|
3186
|
+
bevel ? buildAndLayoutSvgText({
|
|
3187
|
+
...effectArgs,
|
|
3188
|
+
effectKind: "bevel"
|
|
3189
|
+
}) : "",
|
|
3758
3190
|
paraData.some((para) => para.runs.some((run) => run.fmt?.innerShadow != null)) ? buildAndLayoutSvgText({
|
|
3759
3191
|
...effectArgs,
|
|
3760
3192
|
effectKind: "innerShadow"
|
|
@@ -3791,10 +3223,11 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
|
|
|
3791
3223
|
const content = paragraphs.join("");
|
|
3792
3224
|
const body = `<div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:visible;font-family:${effectiveDefaultFont};color:${defaultColor};${`translate:${model.anchorOffset.x}px ${model.anchorOffset.y}px;`}${wrapStyle}${vertStyles}">${content}</div>`;
|
|
3793
3225
|
const foreign = `<foreignObject x="${E(innerX)}" y="${E(innerY)}" width="${E(innerW)}" height="${E(innerH)}" overflow="visible">${body}</foreignObject>`;
|
|
3794
|
-
const hasCharacterEffect = paraData.some((para) => para.runs.some((run) => run.fmt?.reflection !== void 0 && run.fmt.reflection !== null || run.fmt?.innerShadow !== void 0 && run.fmt.innerShadow !== null || hasPaintedTextFill(run)));
|
|
3226
|
+
const hasCharacterEffect = bevel !== null || paraData.some((para) => para.runs.some((run) => run.fmt?.reflection !== void 0 && run.fmt.reflection !== null || run.fmt?.innerShadow !== void 0 && run.fmt.innerShadow !== null || hasPaintedTextFill(run)));
|
|
3795
3227
|
let reflectionOverlay = "";
|
|
3796
3228
|
let fillOverlay = "";
|
|
3797
3229
|
let innerShadowOverlay = "";
|
|
3230
|
+
let bevelOverlay = "";
|
|
3798
3231
|
if (hasCharacterEffect) {
|
|
3799
3232
|
const svgVert = verticalLayoutOf(effectiveBody.vert ?? getShapeTextDirection(shape));
|
|
3800
3233
|
const { x: rX, y: rY, w: rW, h: rH } = svgTextRect(svgVert);
|
|
@@ -3820,7 +3253,8 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
|
|
|
3820
3253
|
vert: svgVert,
|
|
3821
3254
|
columns: null,
|
|
3822
3255
|
effectsOnly: true,
|
|
3823
|
-
resolveFamily: browserFontFamily
|
|
3256
|
+
resolveFamily: browserFontFamily,
|
|
3257
|
+
bevel
|
|
3824
3258
|
};
|
|
3825
3259
|
const hasCharacterReflection = paraData.some((para) => para.runs.some((run) => run.fmt?.reflection !== void 0 && run.fmt.reflection !== null));
|
|
3826
3260
|
const hasCharacterInnerShadow = paraData.some((para) => para.runs.some((run) => run.fmt?.innerShadow !== void 0 && run.fmt.innerShadow !== null));
|
|
@@ -3832,6 +3266,10 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
|
|
|
3832
3266
|
...effectArgs,
|
|
3833
3267
|
effectKind: "fill"
|
|
3834
3268
|
});
|
|
3269
|
+
if (bevel) bevelOverlay = buildAndLayoutSvgText({
|
|
3270
|
+
...effectArgs,
|
|
3271
|
+
effectKind: "bevel"
|
|
3272
|
+
});
|
|
3835
3273
|
if (hasCharacterInnerShadow) innerShadowOverlay = buildAndLayoutSvgText({
|
|
3836
3274
|
...effectArgs,
|
|
3837
3275
|
effectKind: "innerShadow"
|
|
@@ -3841,10 +3279,10 @@ const renderTextBody = (pres, shape, bounds, theme, phType, ctx, output = "body"
|
|
|
3841
3279
|
if (bodyRotDeg !== null && bodyRotDeg !== 0) {
|
|
3842
3280
|
const pivotX = innerX + innerW / 2;
|
|
3843
3281
|
const pivotY = innerY + innerH / 2;
|
|
3844
|
-
const content = output === "effects" ? `${reflectionOverlay}${fillOverlay}${innerShadowOverlay}` : `${reflectionOverlay}${foreign}${fillOverlay}${innerShadowOverlay}`;
|
|
3282
|
+
const content = output === "effects" ? `${reflectionOverlay}${fillOverlay}${bevelOverlay}${innerShadowOverlay}` : `${reflectionOverlay}${foreign}${fillOverlay}${bevelOverlay}${innerShadowOverlay}`;
|
|
3845
3283
|
return `<g transform="rotate(${bodyRotDeg} ${E(pivotX)} ${E(pivotY)})">${content}</g>`;
|
|
3846
3284
|
}
|
|
3847
|
-
return output === "effects" ? reflectionOverlay + fillOverlay + innerShadowOverlay : reflectionOverlay + foreign + fillOverlay + innerShadowOverlay;
|
|
3285
|
+
return output === "effects" ? reflectionOverlay + fillOverlay + bevelOverlay + innerShadowOverlay : reflectionOverlay + foreign + fillOverlay + bevelOverlay + innerShadowOverlay;
|
|
3848
3286
|
};
|
|
3849
3287
|
/**
|
|
3850
3288
|
* Paint only character reflection/inner-shadow effects for an editable text
|
|
@@ -5313,10 +4751,11 @@ const cellParaData = (paragraphs, cell, pres) => {
|
|
|
5313
4751
|
const bulletIsPicture = isParagraphBulletPicture(cell, index);
|
|
5314
4752
|
const bulletImageBytes = bulletIsPicture ? getParagraphBulletImageBytes(cell, index) : null;
|
|
5315
4753
|
const runs = [];
|
|
4754
|
+
const languages = getParagraphElementLanguages(cell, index);
|
|
5316
4755
|
let rIdx = 0;
|
|
5317
4756
|
let fieldIndex = 0;
|
|
5318
4757
|
let breakIndex = 0;
|
|
5319
|
-
for (const el of para.elements) {
|
|
4758
|
+
for (const [elementIndex, el] of para.elements.entries()) {
|
|
5320
4759
|
if (el.kind === "br") {
|
|
5321
4760
|
const fmt = getTableCellRunFormatEffective(pres, cell, index, { breakIndex: breakIndex++ });
|
|
5322
4761
|
runs.push({
|
|
@@ -5333,6 +4772,7 @@ const cellParaData = (paragraphs, cell, pres) => {
|
|
|
5333
4772
|
text: el.text,
|
|
5334
4773
|
fmt,
|
|
5335
4774
|
sizePt: fmt?.size ?? DEFAULT_BODY_PT,
|
|
4775
|
+
...decimalSeparatorField(languages[elementIndex]),
|
|
5336
4776
|
...href ? {
|
|
5337
4777
|
href,
|
|
5338
4778
|
...el.tooltip !== void 0 ? { hrefTip: el.tooltip } : {}
|
|
@@ -5404,13 +4844,19 @@ const renderTableCellText = (cell, paragraphs, cx, cy, cw, ch, color, pres, shap
|
|
|
5404
4844
|
...ctx.mode === "foreignObject" ? { resolveFamily: browserFontFamily } : {},
|
|
5405
4845
|
vert: verticalLayoutOf(getTableCellTextDirection(cell)),
|
|
5406
4846
|
columns: null,
|
|
5407
|
-
...effectsOnly ? { effectsOnly: true } : {}
|
|
4847
|
+
...effectsOnly ? { effectsOnly: true } : {},
|
|
4848
|
+
bevel: textBevelOf(getTableCellText3D(cell))
|
|
5408
4849
|
};
|
|
5409
4850
|
const fillOverlay = () => paraData.some((para) => para.runs.some(hasPaintedTextFill)) ? buildAndLayoutSvgText({
|
|
5410
4851
|
...svgArgs,
|
|
5411
4852
|
effectsOnly: true,
|
|
5412
4853
|
effectKind: "fill"
|
|
5413
4854
|
}) : "";
|
|
4855
|
+
const bevelOverlay = () => svgArgs.bevel ? buildAndLayoutSvgText({
|
|
4856
|
+
...svgArgs,
|
|
4857
|
+
effectsOnly: true,
|
|
4858
|
+
effectKind: "bevel"
|
|
4859
|
+
}) : "";
|
|
5414
4860
|
if (ctx.mode === "svg" || customTabs || effectsOnly) {
|
|
5415
4861
|
if (effectsOnly) {
|
|
5416
4862
|
const reflection = paraData.some((para) => para.runs.some((run) => run.fmt?.reflection != null)) ? buildAndLayoutSvgText({
|
|
@@ -5421,7 +4867,7 @@ const renderTableCellText = (cell, paragraphs, cx, cy, cw, ch, color, pres, shap
|
|
|
5421
4867
|
...svgArgs,
|
|
5422
4868
|
effectKind: "innerShadow"
|
|
5423
4869
|
}) : "";
|
|
5424
|
-
return reflection + fillOverlay() + innerShadow;
|
|
4870
|
+
return reflection + fillOverlay() + bevelOverlay() + innerShadow;
|
|
5425
4871
|
}
|
|
5426
4872
|
return buildAndLayoutSvgText(svgArgs);
|
|
5427
4873
|
}
|
|
@@ -5430,7 +4876,34 @@ const renderTableCellText = (cell, paragraphs, cx, cy, cw, ch, color, pres, shap
|
|
|
5430
4876
|
const justify = vAnchor === "top" ? "flex-start" : vAnchor === "bottom" ? "flex-end" : "center";
|
|
5431
4877
|
const familyFont = themeFace ? `${escapeXml(themeFace)}, ${DEFAULT_FONT}` : DEFAULT_FONT;
|
|
5432
4878
|
const body = renderHtmlParagraphs(paraData, numberLabels, theme, 1, DEFAULT_BODY_PT, color).join("");
|
|
5433
|
-
return `<foreignObject x="${px(innerX)}" y="${px(innerY)}" width="${px(innerW)}" height="${px(innerH)}"><div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:hidden;line-height:${LINE_HEIGHT};font-family:${familyFont};color:${color};word-break:break-word;${directionStyle}">${body}</div></foreignObject>${fillOverlay()}`;
|
|
4879
|
+
return `<foreignObject x="${px(innerX)}" y="${px(innerY)}" width="${px(innerW)}" height="${px(innerH)}"><div xmlns="http://www.w3.org/1999/xhtml" style="display:flex;flex-direction:column;justify-content:${justify};width:100%;height:100%;box-sizing:border-box;overflow:hidden;line-height:${LINE_HEIGHT};font-family:${familyFont};color:${color};word-break:break-word;${directionStyle}">${body}</div></foreignObject>${fillOverlay()}${bevelOverlay()}`;
|
|
4880
|
+
};
|
|
4881
|
+
const TWO_STOP_TABLE_GRADIENT_EXPONENT = 1.85;
|
|
4882
|
+
const TWO_STOP_TABLE_GRADIENT_SAMPLES = 16;
|
|
4883
|
+
const twoStopTableGradient = (grad, theme) => {
|
|
4884
|
+
if (grad.path !== void 0 || grad.stops.length !== 2) return grad;
|
|
4885
|
+
const [start, end] = [...grad.stops].sort((a, b) => a.offset - b.offset);
|
|
4886
|
+
if (!start || !end || end.offset <= start.offset) return grad;
|
|
4887
|
+
const span = end.offset - start.offset;
|
|
4888
|
+
const colorOf = (stop) => stop.resolvedColor ?? resolveColor(stop.color, theme, "#E5E7EB");
|
|
4889
|
+
const startColor = colorOf(start);
|
|
4890
|
+
const endColor = colorOf(end);
|
|
4891
|
+
const stops = Array.from({ length: 17 }, (_, i) => {
|
|
4892
|
+
const along = i / TWO_STOP_TABLE_GRADIENT_SAMPLES;
|
|
4893
|
+
const startWeight = (1 - along) ** TWO_STOP_TABLE_GRADIENT_EXPONENT;
|
|
4894
|
+
const color = mixHex(startColor, endColor, startWeight);
|
|
4895
|
+
const opacity = start.opacity === void 0 && end.opacity === void 0 ? void 0 : (start.opacity ?? 1) * startWeight + (end.opacity ?? 1) * (1 - startWeight);
|
|
4896
|
+
return {
|
|
4897
|
+
offset: start.offset + along * span,
|
|
4898
|
+
color,
|
|
4899
|
+
resolvedColor: color,
|
|
4900
|
+
...opacity === void 0 ? {} : { opacity }
|
|
4901
|
+
};
|
|
4902
|
+
});
|
|
4903
|
+
return {
|
|
4904
|
+
...grad,
|
|
4905
|
+
stops
|
|
4906
|
+
};
|
|
5434
4907
|
};
|
|
5435
4908
|
const renderTable = (shape, pres, x, y, w, h, transform, theme, ctx) => {
|
|
5436
4909
|
let dims;
|
|
@@ -5464,6 +4937,16 @@ const renderTable = (shape, pres, x, y, w, h, transform, theme, ctx) => {
|
|
|
5464
4937
|
const tableThemeFace = getPresentationFonts(pres)?.minorLatin ?? null;
|
|
5465
4938
|
const out = [];
|
|
5466
4939
|
out.push(`<g${transform}>`);
|
|
4940
|
+
const background = getTableBackgroundEffective(pres, shape);
|
|
4941
|
+
const tableW = (colXs[dims.cols] ?? xPx) - xPx;
|
|
4942
|
+
const tableH = (rowYs[dims.rows] ?? yPx) - yPx;
|
|
4943
|
+
if (background?.fill.kind === "solid") {
|
|
4944
|
+
const opacity = background.fillOpacity !== void 0 && background.fillOpacity < 1 ? ` fill-opacity="${background.fillOpacity.toFixed(3)}"` : "";
|
|
4945
|
+
out.push(`<rect x="${px(xPx)}" y="${px(yPx)}" width="${px(tableW)}" height="${px(tableH)}" fill="${resolveColor(background.fill.color, theme, "#FFFFFF")}"${opacity}/>`);
|
|
4946
|
+
} else if (background?.gradient) {
|
|
4947
|
+
const built = gradientDef(twoStopTableGradient(background.gradient, theme), theme);
|
|
4948
|
+
out.push(`${built.defs}<rect x="${px(xPx)}" y="${px(yPx)}" width="${px(tableW)}" height="${px(tableH)}" fill="${built.fillAttr}"/>`);
|
|
4949
|
+
}
|
|
5467
4950
|
const borderEdges = [];
|
|
5468
4951
|
const borderEdgeCandidates = /* @__PURE__ */ new Map();
|
|
5469
4952
|
for (let r = 0; r < dims.rows; r++) for (let c = 0; c < dims.cols; c++) {
|
|
@@ -5486,7 +4969,8 @@ const renderTable = (shape, pres, x, y, w, h, transform, theme, ctx) => {
|
|
|
5486
4969
|
else if (fill.kind !== "inherit") resolvedFill = "none";
|
|
5487
4970
|
else resolvedFill = "none";
|
|
5488
4971
|
const cellTextColor = textColor;
|
|
5489
|
-
|
|
4972
|
+
const fillOpacity = fill.kind === "solid" && appearance.fillOpacity !== void 0 && appearance.fillOpacity < 1 ? ` fill-opacity="${appearance.fillOpacity.toFixed(3)}"` : "";
|
|
4973
|
+
out.push(`<g data-pptx-cell="${r},${c}"><rect x="${px(cx)}" y="${px(cy)}" width="${px(cw)}" height="${px(ch)}" fill="${resolvedFill}"${fillOpacity}/>`);
|
|
5490
4974
|
const borders = appearance.borders;
|
|
5491
4975
|
const dashAttr = (dash, widthPx) => {
|
|
5492
4976
|
if (!dash || dash === "solid") return "";
|
|
@@ -5547,8 +5031,12 @@ const renderTable = (shape, pres, x, y, w, h, transform, theme, ctx) => {
|
|
|
5547
5031
|
*/
|
|
5548
5032
|
const arcToCubicSegments = (startX, startY, wR, hR, stAng, swAng) => {
|
|
5549
5033
|
const toRad = (a) => a / 6e4 * (Math.PI / 180);
|
|
5550
|
-
const
|
|
5551
|
-
|
|
5034
|
+
const parametric = (visual) => {
|
|
5035
|
+
const offset = Math.atan2(wR * Math.sin(visual), hR * Math.cos(visual)) - visual;
|
|
5036
|
+
return visual + Math.atan2(Math.sin(offset), Math.cos(offset));
|
|
5037
|
+
};
|
|
5038
|
+
const st = parametric(toRad(stAng));
|
|
5039
|
+
const sw = parametric(toRad(stAng + swAng)) - st;
|
|
5552
5040
|
const cx = startX - wR * Math.cos(st);
|
|
5553
5041
|
const cy = startY - hR * Math.sin(st);
|
|
5554
5042
|
const segCount = Math.max(1, Math.ceil(Math.abs(sw) / (Math.PI / 2)));
|
|
@@ -5577,75 +5065,237 @@ const arcToCubicSegments = (startX, startY, wR, hR, stAng, swAng) => {
|
|
|
5577
5065
|
return segs;
|
|
5578
5066
|
};
|
|
5579
5067
|
/**
|
|
5580
|
-
*
|
|
5581
|
-
*
|
|
5582
|
-
* the shape
|
|
5583
|
-
* `(x, y, w, h)` in EMU. Returns `''` when nothing drawable remains, so
|
|
5584
|
-
* the caller can fall back to the labelled rect.
|
|
5585
|
-
*
|
|
5586
|
-
* Per-path `fill="none"` paints stroke-only; `stroke="0"` paints
|
|
5587
|
-
* fill-only — mirroring `ST_PathFillMode` / the path `stroke` flag.
|
|
5068
|
+
* The SVG path data of one evaluated {@link GeomPath}, scaling its coordinate
|
|
5069
|
+
* space (its own `w`/`h`, or the shape extents when those are absent) onto
|
|
5070
|
+
* the shape's slide box `(x, y, w, h)` in EMU. `''` when nothing is drawable.
|
|
5588
5071
|
*/
|
|
5589
|
-
const
|
|
5590
|
-
const
|
|
5591
|
-
|
|
5072
|
+
const geometryPathData = (path, x, y, w, h) => {
|
|
5073
|
+
const cw = path.w ?? w;
|
|
5074
|
+
const ch = path.h ?? h;
|
|
5075
|
+
if (cw === 0 || ch === 0) return "";
|
|
5076
|
+
const sx = w / cw;
|
|
5077
|
+
const sy = h / ch;
|
|
5078
|
+
const fx = (gx) => ((x + gx * sx) / EMU_PER_PX).toFixed(2);
|
|
5079
|
+
const fy = (gy) => ((y + gy * sy) / EMU_PER_PX).toFixed(2);
|
|
5080
|
+
const pt = (gx, gy) => `${fx(gx)},${fy(gy)}`;
|
|
5081
|
+
let curX = 0;
|
|
5082
|
+
let curY = 0;
|
|
5083
|
+
let startX = 0;
|
|
5084
|
+
let startY = 0;
|
|
5085
|
+
const d = [];
|
|
5086
|
+
for (const cmd of path.commands) switch (cmd.kind) {
|
|
5087
|
+
case "moveTo":
|
|
5088
|
+
curX = cmd.pt.x;
|
|
5089
|
+
curY = cmd.pt.y;
|
|
5090
|
+
startX = curX;
|
|
5091
|
+
startY = curY;
|
|
5092
|
+
d.push(`M${pt(curX, curY)}`);
|
|
5093
|
+
break;
|
|
5094
|
+
case "lnTo":
|
|
5095
|
+
curX = cmd.pt.x;
|
|
5096
|
+
curY = cmd.pt.y;
|
|
5097
|
+
d.push(`L${pt(curX, curY)}`);
|
|
5098
|
+
break;
|
|
5099
|
+
case "quadBezTo":
|
|
5100
|
+
d.push(`Q${pt(cmd.pts[0].x, cmd.pts[0].y)} ${pt(cmd.pts[1].x, cmd.pts[1].y)}`);
|
|
5101
|
+
curX = cmd.pts[1].x;
|
|
5102
|
+
curY = cmd.pts[1].y;
|
|
5103
|
+
break;
|
|
5104
|
+
case "cubicBezTo":
|
|
5105
|
+
d.push(`C${pt(cmd.pts[0].x, cmd.pts[0].y)} ${pt(cmd.pts[1].x, cmd.pts[1].y)} ${pt(cmd.pts[2].x, cmd.pts[2].y)}`);
|
|
5106
|
+
curX = cmd.pts[2].x;
|
|
5107
|
+
curY = cmd.pts[2].y;
|
|
5108
|
+
break;
|
|
5109
|
+
case "arcTo": {
|
|
5110
|
+
const segs = arcToCubicSegments(curX, curY, cmd.wR, cmd.hR, cmd.stAng, cmd.swAng);
|
|
5111
|
+
for (const s of segs) d.push(`C${pt(s.c1x, s.c1y)} ${pt(s.c2x, s.c2y)} ${pt(s.ex, s.ey)}`);
|
|
5112
|
+
const last = segs[segs.length - 1];
|
|
5113
|
+
if (last) {
|
|
5114
|
+
curX = last.ex;
|
|
5115
|
+
curY = last.ey;
|
|
5116
|
+
}
|
|
5117
|
+
break;
|
|
5118
|
+
}
|
|
5119
|
+
case "close":
|
|
5120
|
+
d.push("Z");
|
|
5121
|
+
curX = startX;
|
|
5122
|
+
curY = startY;
|
|
5123
|
+
break;
|
|
5124
|
+
}
|
|
5125
|
+
return d.join(" ");
|
|
5126
|
+
};
|
|
5127
|
+
const PATH_SHADE = {
|
|
5128
|
+
darken: "fill=\"#000\" fill-opacity=\"0.4\"",
|
|
5129
|
+
darkenLess: "fill=\"#000\" fill-opacity=\"0.2\"",
|
|
5130
|
+
lighten: "fill=\"#fff\" fill-opacity=\"0.4\"",
|
|
5131
|
+
lightenLess: "fill=\"#fff\" fill-opacity=\"0.2\""
|
|
5132
|
+
};
|
|
5133
|
+
const SKETCH_AMPLITUDE = {
|
|
5134
|
+
curved: .008,
|
|
5135
|
+
freehand: .014,
|
|
5136
|
+
scribble: .022
|
|
5137
|
+
};
|
|
5138
|
+
const SKETCH_STEP = .12;
|
|
5139
|
+
const seededRandom = (seed) => {
|
|
5140
|
+
let state = seed >>> 0;
|
|
5141
|
+
return () => {
|
|
5142
|
+
state = state + 1831565813 >>> 0;
|
|
5143
|
+
let t = state;
|
|
5144
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
5145
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
5146
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
5147
|
+
};
|
|
5148
|
+
};
|
|
5149
|
+
/**
|
|
5150
|
+
* An approximation of a sketched outline (`ask:lineSketchStyleProps`): every
|
|
5151
|
+
* edge of `geom` is redrawn as a seeded hand-drawn wobble. Only used for a
|
|
5152
|
+
* preset geometry the writer left crisp; sketches the reference desktop app wrote already
|
|
5153
|
+
* carry their hand-drawn path as custom geometry.
|
|
5154
|
+
*/
|
|
5155
|
+
const sketchGeometry = (geom, sketch, w, h, seed) => {
|
|
5156
|
+
const random = seededRandom(seed);
|
|
5157
|
+
const jitter = (amp) => (random() * 2 - 1) * amp;
|
|
5158
|
+
const paths = geom.paths.map((path) => {
|
|
5592
5159
|
const cw = path.w ?? w;
|
|
5593
5160
|
const ch = path.h ?? h;
|
|
5594
|
-
|
|
5595
|
-
const
|
|
5596
|
-
const
|
|
5597
|
-
const
|
|
5598
|
-
|
|
5599
|
-
|
|
5161
|
+
const size = Math.max(Math.min(cw, ch), Math.max(cw, ch) / 4);
|
|
5162
|
+
const amp = SKETCH_AMPLITUDE[sketch] * size;
|
|
5163
|
+
const step = SKETCH_STEP * Math.max(cw, ch);
|
|
5164
|
+
const nudge = (pt) => ({
|
|
5165
|
+
x: pt.x + jitter(amp),
|
|
5166
|
+
y: pt.y + jitter(amp)
|
|
5167
|
+
});
|
|
5168
|
+
const commands = [];
|
|
5600
5169
|
let curX = 0;
|
|
5601
5170
|
let curY = 0;
|
|
5602
5171
|
let startX = 0;
|
|
5603
5172
|
let startY = 0;
|
|
5604
|
-
const
|
|
5173
|
+
const wobbleTo = (x, y) => {
|
|
5174
|
+
const dx = x - curX;
|
|
5175
|
+
const dy = y - curY;
|
|
5176
|
+
const len = Math.hypot(dx, dy);
|
|
5177
|
+
const count = step > 0 ? Math.max(1, Math.round(len / step)) : 1;
|
|
5178
|
+
const nx = len > 0 ? -dy / len : 0;
|
|
5179
|
+
const ny = len > 0 ? dx / len : 0;
|
|
5180
|
+
let px = curX;
|
|
5181
|
+
let py = curY;
|
|
5182
|
+
for (let i = 1; i <= count; i++) {
|
|
5183
|
+
const last = i === count;
|
|
5184
|
+
const ex = curX + dx * i / count + (last ? 0 : jitter(amp / 2));
|
|
5185
|
+
const ey = curY + dy * i / count + (last ? 0 : jitter(amp / 2));
|
|
5186
|
+
const bend = jitter(amp);
|
|
5187
|
+
const control = {
|
|
5188
|
+
x: (px + ex) / 2 + nx * bend,
|
|
5189
|
+
y: (py + ey) / 2 + ny * bend
|
|
5190
|
+
};
|
|
5191
|
+
commands.push({
|
|
5192
|
+
kind: "quadBezTo",
|
|
5193
|
+
pts: [control, {
|
|
5194
|
+
x: ex,
|
|
5195
|
+
y: ey
|
|
5196
|
+
}]
|
|
5197
|
+
});
|
|
5198
|
+
px = ex;
|
|
5199
|
+
py = ey;
|
|
5200
|
+
}
|
|
5201
|
+
curX = x;
|
|
5202
|
+
curY = y;
|
|
5203
|
+
};
|
|
5605
5204
|
for (const cmd of path.commands) switch (cmd.kind) {
|
|
5606
5205
|
case "moveTo":
|
|
5607
5206
|
curX = cmd.pt.x;
|
|
5608
5207
|
curY = cmd.pt.y;
|
|
5609
5208
|
startX = curX;
|
|
5610
5209
|
startY = curY;
|
|
5611
|
-
|
|
5210
|
+
commands.push(cmd);
|
|
5612
5211
|
break;
|
|
5613
5212
|
case "lnTo":
|
|
5614
|
-
|
|
5615
|
-
curY = cmd.pt.y;
|
|
5616
|
-
d.push(`L${pt(curX, curY)}`);
|
|
5213
|
+
wobbleTo(cmd.pt.x, cmd.pt.y);
|
|
5617
5214
|
break;
|
|
5618
5215
|
case "quadBezTo":
|
|
5619
|
-
|
|
5216
|
+
commands.push({
|
|
5217
|
+
kind: "quadBezTo",
|
|
5218
|
+
pts: [nudge(cmd.pts[0]), cmd.pts[1]]
|
|
5219
|
+
});
|
|
5620
5220
|
curX = cmd.pts[1].x;
|
|
5621
5221
|
curY = cmd.pts[1].y;
|
|
5622
5222
|
break;
|
|
5623
5223
|
case "cubicBezTo":
|
|
5624
|
-
|
|
5224
|
+
commands.push({
|
|
5225
|
+
kind: "cubicBezTo",
|
|
5226
|
+
pts: [
|
|
5227
|
+
nudge(cmd.pts[0]),
|
|
5228
|
+
nudge(cmd.pts[1]),
|
|
5229
|
+
cmd.pts[2]
|
|
5230
|
+
]
|
|
5231
|
+
});
|
|
5625
5232
|
curX = cmd.pts[2].x;
|
|
5626
5233
|
curY = cmd.pts[2].y;
|
|
5627
5234
|
break;
|
|
5628
|
-
case "arcTo":
|
|
5629
|
-
const
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5235
|
+
case "arcTo":
|
|
5236
|
+
for (const s of arcToCubicSegments(curX, curY, cmd.wR, cmd.hR, cmd.stAng, cmd.swAng)) {
|
|
5237
|
+
commands.push({
|
|
5238
|
+
kind: "cubicBezTo",
|
|
5239
|
+
pts: [
|
|
5240
|
+
nudge({
|
|
5241
|
+
x: s.c1x,
|
|
5242
|
+
y: s.c1y
|
|
5243
|
+
}),
|
|
5244
|
+
nudge({
|
|
5245
|
+
x: s.c2x,
|
|
5246
|
+
y: s.c2y
|
|
5247
|
+
}),
|
|
5248
|
+
{
|
|
5249
|
+
x: s.ex,
|
|
5250
|
+
y: s.ey
|
|
5251
|
+
}
|
|
5252
|
+
]
|
|
5253
|
+
});
|
|
5254
|
+
curX = s.ex;
|
|
5255
|
+
curY = s.ey;
|
|
5635
5256
|
}
|
|
5636
5257
|
break;
|
|
5637
|
-
}
|
|
5638
5258
|
case "close":
|
|
5639
|
-
|
|
5259
|
+
if (curX !== startX || curY !== startY) wobbleTo(startX, startY);
|
|
5260
|
+
commands.push(cmd);
|
|
5640
5261
|
curX = startX;
|
|
5641
5262
|
curY = startY;
|
|
5642
5263
|
break;
|
|
5643
5264
|
}
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5265
|
+
return {
|
|
5266
|
+
...path,
|
|
5267
|
+
commands
|
|
5268
|
+
};
|
|
5269
|
+
});
|
|
5270
|
+
return {
|
|
5271
|
+
...geom,
|
|
5272
|
+
paths
|
|
5273
|
+
};
|
|
5274
|
+
};
|
|
5275
|
+
/**
|
|
5276
|
+
* Renders an evaluated {@link CustomGeometry} (a `<a:custGeom>` or a preset
|
|
5277
|
+
* from `getPresetGeometry`) as `<path>`s in the shape's slide box. Returns
|
|
5278
|
+
* `''` when nothing drawable remains, so the caller can fall back to the
|
|
5279
|
+
* labelled rect.
|
|
5280
|
+
*
|
|
5281
|
+
* Per-path `fill="none"` paints stroke-only; `stroke="0"` paints
|
|
5282
|
+
* fill-only — mirroring `ST_PathFillMode` / the path `stroke` flag.
|
|
5283
|
+
*/
|
|
5284
|
+
const customGeometryToSvg = (geom, x, y, w, h, fill, fillExtra, stroke, strokeWidthEmu, strokeExtra, markerExtra) => {
|
|
5285
|
+
const out = [];
|
|
5286
|
+
for (const path of geom.paths) {
|
|
5287
|
+
const d = geometryPathData(path, x, y, w, h);
|
|
5288
|
+
if (d === "") continue;
|
|
5289
|
+
const filled = path.fill !== "none" && fill !== "none";
|
|
5647
5290
|
const strokeAttrs = path.stroke ? ` stroke="${stroke}" stroke-width="${E(strokeWidthEmu)}"${strokeExtra}${markerExtra}` : " stroke=\"none\"";
|
|
5648
|
-
|
|
5291
|
+
if (filled && path.fill !== "norm") {
|
|
5292
|
+
out.push(`<path d="${d}" fill="${fill}"${fillExtra} stroke="none" fill-rule="evenodd"/>`);
|
|
5293
|
+
out.push(`<path d="${d}" ${PATH_SHADE[path.fill]} stroke="none" fill-rule="evenodd"/>`);
|
|
5294
|
+
if (path.stroke) out.push(`<path d="${d}" fill="none"${strokeAttrs}/>`);
|
|
5295
|
+
continue;
|
|
5296
|
+
}
|
|
5297
|
+
const fillAttrs = filled ? `fill="${fill}"${fillExtra}` : "fill=\"none\"";
|
|
5298
|
+
out.push(`<path d="${d}" ${fillAttrs}${strokeAttrs} fill-rule="evenodd"/>`);
|
|
5649
5299
|
}
|
|
5650
5300
|
return out.join("");
|
|
5651
5301
|
};
|
|
@@ -5838,21 +5488,16 @@ const renderShapeContent = (shape, pres, theme, ctx) => {
|
|
|
5838
5488
|
const customGeom = rawPreset === null ? getShapeCustomGeometry(shape) : null;
|
|
5839
5489
|
let geomSvg = customGeom !== null ? customGeometryToSvg(customGeom, x, y, w, h, p.fill, fa, p.stroke, p.strokeWidth, sa, ma) : "";
|
|
5840
5490
|
const isCustGeom = geomSvg === "" && rawPreset === null && getShapeXmlString(shape).includes("custGeom");
|
|
5491
|
+
const sketch = rawPreset !== null ? getShapeStrokeSketch(shape) : null;
|
|
5492
|
+
if (geomSvg !== "") {} else if (sketch !== null && p.stroke !== "none") {
|
|
5493
|
+
const geometry = getPresetGeometry(preset, bounds, getShapeAdjustValues(shape));
|
|
5494
|
+
if (geometry !== null) geomSvg = customGeometryToSvg(sketchGeometry(geometry, sketch, w, h, getShapeId(shape)), x, y, w, h, p.fill, fa, p.stroke, p.strokeWidth, sa, ma);
|
|
5495
|
+
}
|
|
5841
5496
|
if (geomSvg !== "") {} else if (preset === "rect") geomSvg = `<rect x="${E(x)}" y="${E(y)}" width="${E(w)}" height="${E(h)}" fill="${p.fill}"${fa} stroke="${p.stroke}" stroke-width="${E(p.strokeWidth)}"${sa}${ma}/>`;
|
|
5842
|
-
else if (preset === "roundRect") {
|
|
5843
|
-
const adjVal = getShapeAdjustValues(shape).adj ?? 16667;
|
|
5844
|
-
const ratio = Math.max(0, Math.min(.5, adjVal / 1e5));
|
|
5845
|
-
const r = E(Math.min(w, h) * ratio);
|
|
5846
|
-
geomSvg = `<rect x="${E(x)}" y="${E(y)}" width="${E(w)}" height="${E(h)}" rx="${r}" ry="${r}" fill="${p.fill}"${fa} stroke="${p.stroke}" stroke-width="${E(p.strokeWidth)}"${sa}${ma}/>`;
|
|
5847
|
-
} else if (preset === "ellipse" || preset === "oval") geomSvg = `<ellipse cx="${E(cx)}" cy="${E(cy)}" rx="${E(w / 2)}" ry="${E(h / 2)}" fill="${p.fill}"${fa} stroke="${p.stroke}" stroke-width="${E(p.strokeWidth)}"${sa}${ma}/>`;
|
|
5848
5497
|
else {
|
|
5849
|
-
const
|
|
5850
|
-
if (
|
|
5851
|
-
|
|
5852
|
-
const pointsFn = PRESET_POINTS[preset];
|
|
5853
|
-
if (pointsFn) geomSvg = `<polygon points="${pointsFn(w / EMU_PER_PX, h / EMU_PER_PX).map(([nx, ny]) => `${E(x + nx * w)},${E(y + ny * h)}`).join(" ")}" fill="${p.fill}"${fa} stroke="${p.stroke}" stroke-width="${E(p.strokeWidth)}"${sa}${ma}/>`;
|
|
5854
|
-
else geomSvg = `<rect x="${E(x)}" y="${E(y)}" width="${E(w)}" height="${E(h)}" fill="${p.fill}"${fa} stroke="${p.stroke}" stroke-width="${E(p.strokeWidth)}"${sa}${ma} data-pptx-preset="${escapeXml(preset)}"><title>${escapeXml(`preset: ${preset}`)}</title></rect>`;
|
|
5855
|
-
}
|
|
5498
|
+
const geometry = getPresetGeometry(preset, bounds, getShapeAdjustValues(shape));
|
|
5499
|
+
if (geometry !== null) geomSvg = customGeometryToSvg(geometry, x, y, w, h, p.fill, fa, p.stroke, p.strokeWidth, sa, ma);
|
|
5500
|
+
if (geomSvg === "") geomSvg = `<rect x="${E(x)}" y="${E(y)}" width="${E(w)}" height="${E(h)}" fill="${p.fill}"${fa} stroke="${p.stroke}" stroke-width="${E(p.strokeWidth)}"${sa}${ma} data-pptx-preset="${escapeXml(preset)}"><title>${escapeXml(`preset: ${preset}`)}</title></rect>`;
|
|
5856
5501
|
}
|
|
5857
5502
|
const fx = buildEffectsFilter(pres, shape);
|
|
5858
5503
|
const filterAttr = fx ? ` filter="url(#${fx.id})"` : "";
|
|
@@ -5940,11 +5585,14 @@ const buildReflection = (pres, shape, geomRaw, box) => {
|
|
|
5940
5585
|
const f = refl.scaleY ?? -1;
|
|
5941
5586
|
const startA = refl.startOpacity ?? 1;
|
|
5942
5587
|
const endA = refl.opacity ?? 0;
|
|
5588
|
+
const startPos = refl.startPosition ?? 0;
|
|
5589
|
+
const endPos = Math.max(startPos, refl.endPosition ?? 1);
|
|
5943
5590
|
const contactPx = (box.y + box.h) / EMU_PER_PX;
|
|
5944
5591
|
const transform = `translate(0 ${(refl.distEmu / EMU_PER_PX + contactPx * (1 - f)).toFixed(2)}) scale(1 ${f})`;
|
|
5945
5592
|
const maskId = mintId();
|
|
5946
5593
|
const gradId = mintId();
|
|
5947
|
-
const
|
|
5594
|
+
const [y1, y2] = f < 0 ? [1, 0] : [0, 1];
|
|
5595
|
+
const defs = `<defs><linearGradient id="${gradId}" x1="0" y1="${y1}" x2="0" y2="${y2}"><stop offset="${startPos.toFixed(3)}" stop-color="#fff" stop-opacity="${startA.toFixed(3)}"/><stop offset="${endPos.toFixed(3)}" stop-color="#fff" stop-opacity="${endA.toFixed(3)}"/></linearGradient><mask id="${maskId}" maskContentUnits="objectBoundingBox"><rect width="1" height="1" fill="url(#${gradId})"/></mask></defs>`;
|
|
5948
5596
|
return {
|
|
5949
5597
|
svg: `<g transform="${transform}" mask="url(#${maskId})" data-pptx-reflection="1">${geomRaw}</g>`,
|
|
5950
5598
|
defs
|
|
@@ -5992,9 +5640,9 @@ const buildEffectsFilter = (pres, shape) => {
|
|
|
5992
5640
|
primitives.push(`<feMorphology in="SourceAlpha" operator="dilate" radius="${dilatePx.toFixed(2)}" result="glowExp${i}"/>`, `<feGaussianBlur in="glowExp${i}" stdDeviation="${featherPx.toFixed(2)}" result="glowBlur${i}"/>`, `<feFlood flood-color="${color}" flood-opacity="${opacity.toFixed(3)}" result="glowCol${i}"/>`, `<feComposite in="glowCol${i}" in2="glowBlur${i}" operator="in" result="glowOut${i}"/>`);
|
|
5993
5641
|
layers.push(`glowOut${i}`);
|
|
5994
5642
|
} else if (e.kind === "softEdge") {
|
|
5995
|
-
const
|
|
5643
|
+
const radiusPx = e.radiusEmu / EMU_PER_PX;
|
|
5996
5644
|
const i = primitives.length;
|
|
5997
|
-
primitives.push(`<feGaussianBlur in="
|
|
5645
|
+
primitives.push(`<feMorphology in="SourceAlpha" operator="erode" radius="${(radiusPx / 2).toFixed(2)}" result="softCore${i}"/>`, `<feGaussianBlur in="softCore${i}" stdDeviation="${(radiusPx / 4).toFixed(2)}" result="softMask${i}"/>`, `<feComposite in="SourceGraphic" in2="softMask${i}" operator="in" result="softOut${i}"/>`);
|
|
5998
5646
|
layers.length = 0;
|
|
5999
5647
|
layers.push(`softOut${i}`);
|
|
6000
5648
|
} else if (e.kind === "blur") {
|
|
@@ -6036,14 +5684,33 @@ const topLevelShapes = (shapes, opts) => {
|
|
|
6036
5684
|
}
|
|
6037
5685
|
return out;
|
|
6038
5686
|
};
|
|
6039
|
-
const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
5687
|
+
const renderSlideSvg = (pres, slide, opts = {}) => renderSurface(pres, {
|
|
5688
|
+
slide,
|
|
5689
|
+
layout: getSlideLayout(slide),
|
|
5690
|
+
master: false
|
|
5691
|
+
}, opts);
|
|
5692
|
+
/**
|
|
5693
|
+
* Draws a slide layout — or, with `master`, its slide master — the way
|
|
5694
|
+
* the reference desktop app's Slide Master view shows it behind the placeholders: the
|
|
5695
|
+
* background and the decorative (non-placeholder) shapes of the master and,
|
|
5696
|
+
* for a layout, of the layout itself. A layout that hides background graphics
|
|
5697
|
+
* leaves the master's shapes out. Placeholders are not drawn; an editor draws
|
|
5698
|
+
* them with their prompt text over this.
|
|
5699
|
+
*/
|
|
5700
|
+
const renderSlideLayoutSvg = (pres, layout, opts = {}) => renderSurface(pres, {
|
|
5701
|
+
slide: null,
|
|
5702
|
+
layout,
|
|
5703
|
+
master: opts.master ?? false
|
|
5704
|
+
}, opts);
|
|
5705
|
+
const renderSurface = (pres, surface, opts) => {
|
|
5706
|
+
const { slide, master } = surface;
|
|
6040
5707
|
const size = getSlideSize(pres) ?? DEFAULT_SIZE;
|
|
6041
5708
|
const W = size.width;
|
|
6042
5709
|
const H = size.height;
|
|
6043
5710
|
const theme = getPresentationTheme(pres);
|
|
6044
|
-
activeColorMap = getEffectiveColorMap(slide);
|
|
6045
|
-
activeDeckTextColor = resolveDeckBodyTextColor(slide) ?? "#000000";
|
|
6046
|
-
const position = getSlides(pres).indexOf(slide);
|
|
5711
|
+
activeColorMap = getEffectiveColorMap(slide ?? surface.layout);
|
|
5712
|
+
activeDeckTextColor = resolveDeckBodyTextColor(slide ?? surface.layout) ?? "#000000";
|
|
5713
|
+
const position = slide ? getSlides(pres).indexOf(slide) : 0;
|
|
6047
5714
|
activeSlideNumber = String(getPresentationFirstSlideNumber(pres) + (position < 0 ? 0 : position));
|
|
6048
5715
|
const ctx = {
|
|
6049
5716
|
groupScale: {
|
|
@@ -6061,11 +5728,11 @@ const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
|
6061
5728
|
},
|
|
6062
5729
|
inverseGroupTransform: ""
|
|
6063
5730
|
};
|
|
6064
|
-
let bg = getSlideBackground(slide);
|
|
5731
|
+
let bg = slide ? getSlideBackground(slide) : { kind: "inherit" };
|
|
6065
5732
|
if (bg.kind === "inherit") {
|
|
6066
|
-
const layout =
|
|
5733
|
+
const layout = surface.layout;
|
|
6067
5734
|
if (layout) {
|
|
6068
|
-
const layoutBg = getSlideLayoutBackground(layout);
|
|
5735
|
+
const layoutBg = master ? { kind: "inherit" } : getSlideLayoutBackground(layout);
|
|
6069
5736
|
if (layoutBg.kind !== "inherit") bg = layoutBg;
|
|
6070
5737
|
else {
|
|
6071
5738
|
const masterBg = getSlideMasterBackground(pres, layout);
|
|
@@ -6080,11 +5747,11 @@ const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
|
6080
5747
|
let bgGradientDefs = "";
|
|
6081
5748
|
if (bg.kind === "solid") bgColor = resolveColor(bg.color, theme, "#FFFFFF");
|
|
6082
5749
|
else if (bg.kind === "gradient") {
|
|
6083
|
-
let grad = getSlideBackgroundGradientFill(slide);
|
|
5750
|
+
let grad = slide ? getSlideBackgroundGradientFill(slide) : null;
|
|
6084
5751
|
if (!grad) {
|
|
6085
|
-
const layout =
|
|
5752
|
+
const layout = surface.layout;
|
|
6086
5753
|
if (layout) {
|
|
6087
|
-
grad = getSlideLayoutBackgroundGradientFill(layout);
|
|
5754
|
+
grad = master ? null : getSlideLayoutBackgroundGradientFill(layout);
|
|
6088
5755
|
if (!grad) grad = getSlideMasterBackgroundGradientFill(pres, layout);
|
|
6089
5756
|
}
|
|
6090
5757
|
}
|
|
@@ -6094,11 +5761,11 @@ const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
|
6094
5761
|
bgGradient = `<rect width="${E(W)}" height="${E(H)}" fill="${built.fillAttr}"/>`;
|
|
6095
5762
|
}
|
|
6096
5763
|
} else if (bg.kind === "pattern") {
|
|
6097
|
-
let pat = getSlideBackgroundPatternFill(pres, slide);
|
|
5764
|
+
let pat = slide ? getSlideBackgroundPatternFill(pres, slide) : null;
|
|
6098
5765
|
if (!pat) {
|
|
6099
|
-
const layout =
|
|
5766
|
+
const layout = surface.layout;
|
|
6100
5767
|
if (layout) {
|
|
6101
|
-
pat = getSlideLayoutBackgroundPatternFill(pres, layout);
|
|
5768
|
+
pat = master ? null : getSlideLayoutBackgroundPatternFill(pres, layout);
|
|
6102
5769
|
if (!pat) pat = getSlideMasterBackgroundPatternFill(pres, layout);
|
|
6103
5770
|
}
|
|
6104
5771
|
}
|
|
@@ -6110,23 +5777,23 @@ const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
|
6110
5777
|
} else if (theme && bg.kind === "inherit") bgColor = normalizeHex(theme.light1);
|
|
6111
5778
|
let bgImage = "";
|
|
6112
5779
|
if (bg.kind === "image") {
|
|
6113
|
-
let bytes = getSlideBackgroundImageBytes(slide);
|
|
5780
|
+
let bytes = slide ? getSlideBackgroundImageBytes(slide) : null;
|
|
6114
5781
|
if (!bytes && pres) {
|
|
6115
|
-
const layout =
|
|
5782
|
+
const layout = surface.layout;
|
|
6116
5783
|
if (layout) {
|
|
6117
|
-
bytes = getSlideLayoutBackgroundImageBytes(pres, layout);
|
|
5784
|
+
bytes = master ? null : getSlideLayoutBackgroundImageBytes(pres, layout);
|
|
6118
5785
|
if (!bytes) bytes = getSlideMasterBackgroundImageBytes(pres, layout);
|
|
6119
5786
|
}
|
|
6120
5787
|
}
|
|
6121
5788
|
if (bytes) {
|
|
6122
5789
|
const fmt = detectImageFormatLocal(bytes);
|
|
6123
5790
|
const dataUrl = `data:${fmt ? imageMime[fmt] ?? "image/png" : "image/png"};base64,${u8ToBase64(bytes)}`;
|
|
6124
|
-
const layout = getSlideBackgroundImageFillLayout(slide);
|
|
6125
|
-
const crop = getSlideBackgroundImageCrop(slide);
|
|
5791
|
+
const layout = slide ? getSlideBackgroundImageFillLayout(slide) : null;
|
|
5792
|
+
const crop = slide ? getSlideBackgroundImageCrop(slide) : null;
|
|
6126
5793
|
const cropLeft = crop?.left ?? 0, cropTop = crop?.top ?? 0;
|
|
6127
5794
|
const cropRight = crop?.right ?? 0, cropBottom = crop?.bottom ?? 0;
|
|
6128
|
-
const opacity = getSlideBackgroundImageOpacity(slide) ?? 1;
|
|
6129
|
-
const intrinsic = layout?.mode === "tile" ? getSlideBackgroundImageIntrinsicSize(slide) : null;
|
|
5795
|
+
const opacity = (slide && getSlideBackgroundImageOpacity(slide)) ?? 1;
|
|
5796
|
+
const intrinsic = layout?.mode === "tile" && slide ? getSlideBackgroundImageIntrinsicSize(slide) : null;
|
|
6130
5797
|
if (layout?.mode === "tile" && intrinsic) {
|
|
6131
5798
|
const pattern = imageTilePattern(dataUrl, layout, intrinsic, 0, 0, W, H, cropLeft, cropTop, cropRight, cropBottom);
|
|
6132
5799
|
bgImage = `${pattern.defs}<rect width="${E(W)}" height="${E(H)}" fill="${pattern.fill}" opacity="${opacity}"/>`;
|
|
@@ -6147,10 +5814,11 @@ const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
|
6147
5814
|
}
|
|
6148
5815
|
}
|
|
6149
5816
|
let layoutBgShapes = "";
|
|
6150
|
-
const layoutForBg =
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
const
|
|
5817
|
+
const layoutForBg = surface.layout;
|
|
5818
|
+
const paintBackground = opts.background ?? true;
|
|
5819
|
+
if (paintBackground && layoutForBg && !(slide && isSlideBackgroundGraphicsHidden(slide))) try {
|
|
5820
|
+
const masterShapes = topLevelShapes(!master && isSlideLayoutBackgroundGraphicsHidden(layoutForBg) ? [] : getSlideMasterShapes(pres, layoutForBg), { dropPlaceholders: true });
|
|
5821
|
+
const layoutShapes = topLevelShapes(master ? [] : getSlideLayoutShapes(pres, layoutForBg), { dropPlaceholders: true });
|
|
6154
5822
|
const bgCtx = {
|
|
6155
5823
|
...ctx,
|
|
6156
5824
|
ownShapes: false
|
|
@@ -6159,12 +5827,12 @@ const renderSlideSvg = (pres, slide, opts = {}) => {
|
|
|
6159
5827
|
} catch {
|
|
6160
5828
|
layoutBgShapes = "";
|
|
6161
5829
|
}
|
|
6162
|
-
const shapesSvg = topLevelShapes(getSlideShapes(slide), { dropPlaceholders: false }).map((s) => renderShape(s, pres, theme, ctx)).join("");
|
|
5830
|
+
const shapesSvg = topLevelShapes(slide ? getSlideShapes(slide) : [], { dropPlaceholders: false }).map((s) => renderShape(s, pres, theme, ctx)).join("");
|
|
6163
5831
|
const backgroundSvg = `${bgOpacity === void 0 ? "" : `<rect width="${E(W)}" height="${E(H)}" fill="#FFFFFF"/>`}<rect width="${E(W)}" height="${E(H)}" fill="${bgColor}"${bgOpacityAttr}/>${bgGradient}${bgImage}`;
|
|
6164
5832
|
return [
|
|
6165
5833
|
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 ${E(W)} ${E(H)}" preserveAspectRatio="xMidYMid meet">`,
|
|
6166
5834
|
bgGradientDefs,
|
|
6167
|
-
ctx.background.id ? `<defs><g id="${ctx.background.id}">${backgroundSvg}</g></defs
|
|
5835
|
+
ctx.background.id ? `<defs><g id="${ctx.background.id}">${backgroundSvg}</g></defs>${paintBackground ? `<use href="#${ctx.background.id}" xlink:href="#${ctx.background.id}"/>` : ""}` : paintBackground ? backgroundSvg : "",
|
|
6168
5836
|
layoutBgShapes,
|
|
6169
5837
|
shapesSvg,
|
|
6170
5838
|
"</svg>"
|
|
@@ -6340,7 +6008,7 @@ const auditTextLayout = (pres, options = {}) => {
|
|
|
6340
6008
|
*
|
|
6341
6009
|
* `1` for a shape with no `<a:normAutofit>`: `<a:noAutofit>` overflows and
|
|
6342
6010
|
* `<a:spAutoFit>` grows the box instead, so neither shrinks the text. A shape
|
|
6343
|
-
* with a baked `fontScale` reports that, unchanged — it is what
|
|
6011
|
+
* with a baked `fontScale` reports that, unchanged — it is what the reference desktop app
|
|
6344
6012
|
* itself applied.
|
|
6345
6013
|
*/
|
|
6346
6014
|
function shapeAutoFitScale(pres, shape, options = {}) {
|
|
@@ -6373,6 +6041,6 @@ function shapeTextAnchorOffset(pres, shape, options = {}) {
|
|
|
6373
6041
|
};
|
|
6374
6042
|
}
|
|
6375
6043
|
//#endregion
|
|
6376
|
-
export {
|
|
6044
|
+
export { shapeTextRect as S, paragraphNumberLabels as _, renderSlideSvg as a, verticalTextStyle as b, AVG_GLYPH_W_RATIO as c, SERIF as d, TIMES as f, decimalSeparatorOf as g, substituteFamily as h, renderSlideLayoutSvg as i, MONO as l, isCjk as m, shapeTextAnchorOffset as n, renderTextEffectsSvg as o, defaultMeasurer as p, auditTextLayout as r, ARIAL as s, shapeAutoFitScale as t, SANS as u, textUnderlineStyle as v, resolveTextBodyRect as x, textColumnsStyle as y };
|
|
6377
6045
|
|
|
6378
|
-
//# sourceMappingURL=src-
|
|
6046
|
+
//# sourceMappingURL=src-pb3C61GD.js.map
|