@hirokisakabe/pom 9.1.1 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/buildContext.js +2 -6
  2. package/dist/buildContext.js.map +1 -1
  3. package/dist/buildPptx.d.ts +2 -1
  4. package/dist/buildPptx.d.ts.map +1 -1
  5. package/dist/buildPptx.js +4 -9
  6. package/dist/buildPptx.js.map +1 -1
  7. package/dist/calcYogaLayout/calcYogaLayout.js +1 -1
  8. package/dist/calcYogaLayout/calcYogaLayout.js.map +1 -1
  9. package/dist/index.d.ts +2 -1
  10. package/dist/registry/definitions/icon.js +1 -1
  11. package/dist/registry/definitions/list.js.map +1 -1
  12. package/dist/renderPptx/nodes/chart.js +172 -47
  13. package/dist/renderPptx/nodes/chart.js.map +1 -1
  14. package/dist/renderPptx/nodes/flow.js +98 -90
  15. package/dist/renderPptx/nodes/flow.js.map +1 -1
  16. package/dist/renderPptx/nodes/icon.js +36 -24
  17. package/dist/renderPptx/nodes/icon.js.map +1 -1
  18. package/dist/renderPptx/nodes/image.js +5 -22
  19. package/dist/renderPptx/nodes/image.js.map +1 -1
  20. package/dist/renderPptx/nodes/list.js +94 -111
  21. package/dist/renderPptx/nodes/list.js.map +1 -1
  22. package/dist/renderPptx/nodes/matrix.js +95 -70
  23. package/dist/renderPptx/nodes/matrix.js.map +1 -1
  24. package/dist/renderPptx/nodes/processArrow.js +74 -35
  25. package/dist/renderPptx/nodes/processArrow.js.map +1 -1
  26. package/dist/renderPptx/nodes/pyramid.js +37 -16
  27. package/dist/renderPptx/nodes/pyramid.js.map +1 -1
  28. package/dist/renderPptx/nodes/shape.js +66 -37
  29. package/dist/renderPptx/nodes/shape.js.map +1 -1
  30. package/dist/renderPptx/nodes/svg.js +2 -5
  31. package/dist/renderPptx/nodes/svg.js.map +1 -1
  32. package/dist/renderPptx/nodes/table.js +89 -59
  33. package/dist/renderPptx/nodes/table.js.map +1 -1
  34. package/dist/renderPptx/nodes/text.js +1 -18
  35. package/dist/renderPptx/nodes/text.js.map +1 -1
  36. package/dist/renderPptx/nodes/timeline.js +114 -74
  37. package/dist/renderPptx/nodes/timeline.js.map +1 -1
  38. package/dist/renderPptx/nodes/tree.js +81 -79
  39. package/dist/renderPptx/nodes/tree.js.map +1 -1
  40. package/dist/renderPptx/pptxAuthoring.js +381 -0
  41. package/dist/renderPptx/pptxAuthoring.js.map +1 -0
  42. package/dist/renderPptx/renderPptx.js +158 -128
  43. package/dist/renderPptx/renderPptx.js.map +1 -1
  44. package/dist/renderPptx/textOptions.js +7 -8
  45. package/dist/renderPptx/textOptions.js.map +1 -1
  46. package/dist/renderPptx/units.js +3 -3
  47. package/dist/renderPptx/units.js.map +1 -1
  48. package/dist/renderPptx/utils/backgroundBorder.js +70 -48
  49. package/dist/renderPptx/utils/backgroundBorder.js.map +1 -1
  50. package/dist/renderPptx/utils/contentArea.js +1 -1
  51. package/dist/renderPptx/utils/contentArea.js.map +1 -1
  52. package/dist/renderPptx/utils/glimpsePicture.js +111 -0
  53. package/dist/renderPptx/utils/glimpsePicture.js.map +1 -0
  54. package/dist/renderPptx/utils/glimpseShape.js +71 -0
  55. package/dist/renderPptx/utils/glimpseShape.js.map +1 -0
  56. package/dist/renderPptx/utils/glimpseTextBox.js +107 -0
  57. package/dist/renderPptx/utils/glimpseTextBox.js.map +1 -0
  58. package/dist/renderPptx/utils/straightLine.js +33 -15
  59. package/dist/renderPptx/utils/straightLine.js.map +1 -1
  60. package/dist/renderPptx/utils/visualStyle.js +3 -56
  61. package/dist/renderPptx/utils/visualStyle.js.map +1 -1
  62. package/dist/renderPptx/writablePptx.d.ts +23 -0
  63. package/dist/renderPptx/writablePptx.d.ts.map +1 -0
  64. package/dist/renderPptx/writablePptx.js +74 -0
  65. package/dist/renderPptx/writablePptx.js.map +1 -0
  66. package/dist/shared/measureImage.js.map +1 -1
  67. package/package.json +4 -5
  68. package/dist/renderPptx/glimpseTextBoxes.js +0 -347
  69. package/dist/renderPptx/glimpseTextBoxes.js.map +0 -1
  70. package/dist/renderPptx/glowEffects.js +0 -157
  71. package/dist/renderPptx/glowEffects.js.map +0 -1
  72. package/dist/renderPptx/gradientFills.js +0 -154
  73. package/dist/renderPptx/gradientFills.js.map +0 -1
@@ -1,4 +1,6 @@
1
- import { pxToIn, pxToPt } from "../units.js";
1
+ import { createGlimpseParagraphs } from "../utils/glimpseTextBox.js";
2
+ import { addGlimpseShape, createShapeBoundsInput, shapeOutline, solidShapeFill } from "../utils/glimpseShape.js";
3
+ import { addStraightLine } from "../utils/straightLine.js";
2
4
  import { stripHash } from "../utils/visualStyle.js";
3
5
  import { resolveScaledContentArea } from "../utils/scaleToFit.js";
4
6
  //#region src/renderPptx/nodes/tree.ts
@@ -86,37 +88,34 @@ function renderTreeNode(node, ctx) {
86
88
  const childCenterX = ox + (child.x + child.width / 2) * sf;
87
89
  const childTopY = oy + child.y * sf;
88
90
  const midY = (parentBottomY + childTopY) / 2;
89
- ctx.slide.addShape(ctx.pptx.ShapeType.line, {
90
- x: pxToIn(parentCenterX),
91
- y: pxToIn(parentBottomY),
92
- w: 0,
93
- h: pxToIn(midY - parentBottomY),
94
- line: {
95
- color: lineColor,
96
- width: pxToPt(lineWidth * sf)
97
- }
91
+ addStraightLine(ctx, {
92
+ x1: parentCenterX,
93
+ y1: parentBottomY,
94
+ x2: parentCenterX,
95
+ y2: midY
96
+ }, {
97
+ color: lineColor,
98
+ lineWidth: lineWidth * sf
98
99
  });
99
100
  const minX = Math.min(parentCenterX, childCenterX);
100
101
  const maxX = Math.max(parentCenterX, childCenterX);
101
- if (maxX > minX) ctx.slide.addShape(ctx.pptx.ShapeType.line, {
102
- x: pxToIn(minX),
103
- y: pxToIn(midY),
104
- w: pxToIn(maxX - minX),
105
- h: 0,
106
- line: {
107
- color: lineColor,
108
- width: pxToPt(lineWidth * sf)
109
- }
102
+ if (maxX > minX) addStraightLine(ctx, {
103
+ x1: minX,
104
+ y1: midY,
105
+ x2: maxX,
106
+ y2: midY
107
+ }, {
108
+ color: lineColor,
109
+ lineWidth: lineWidth * sf
110
110
  });
111
- ctx.slide.addShape(ctx.pptx.ShapeType.line, {
112
- x: pxToIn(childCenterX),
113
- y: pxToIn(midY),
114
- w: 0,
115
- h: pxToIn(childTopY - midY),
116
- line: {
117
- color: lineColor,
118
- width: pxToPt(lineWidth * sf)
119
- }
111
+ addStraightLine(ctx, {
112
+ x1: childCenterX,
113
+ y1: midY,
114
+ x2: childCenterX,
115
+ y2: childTopY
116
+ }, {
117
+ color: lineColor,
118
+ lineWidth: lineWidth * sf
120
119
  });
121
120
  } else {
122
121
  const parentRightX = ox + (parent.x + parent.width) * sf;
@@ -124,37 +123,34 @@ function renderTreeNode(node, ctx) {
124
123
  const childLeftX = ox + child.x * sf;
125
124
  const childCenterY = oy + (child.y + child.height / 2) * sf;
126
125
  const midX = (parentRightX + childLeftX) / 2;
127
- ctx.slide.addShape(ctx.pptx.ShapeType.line, {
128
- x: pxToIn(parentRightX),
129
- y: pxToIn(parentCenterY),
130
- w: pxToIn(midX - parentRightX),
131
- h: 0,
132
- line: {
133
- color: lineColor,
134
- width: pxToPt(lineWidth * sf)
135
- }
126
+ addStraightLine(ctx, {
127
+ x1: parentRightX,
128
+ y1: parentCenterY,
129
+ x2: midX,
130
+ y2: parentCenterY
131
+ }, {
132
+ color: lineColor,
133
+ lineWidth: lineWidth * sf
136
134
  });
137
135
  const minY = Math.min(parentCenterY, childCenterY);
138
136
  const maxY = Math.max(parentCenterY, childCenterY);
139
- if (maxY > minY) ctx.slide.addShape(ctx.pptx.ShapeType.line, {
140
- x: pxToIn(midX),
141
- y: pxToIn(minY),
142
- w: 0,
143
- h: pxToIn(maxY - minY),
144
- line: {
145
- color: lineColor,
146
- width: pxToPt(lineWidth * sf)
147
- }
137
+ if (maxY > minY) addStraightLine(ctx, {
138
+ x1: midX,
139
+ y1: minY,
140
+ x2: midX,
141
+ y2: maxY
142
+ }, {
143
+ color: lineColor,
144
+ lineWidth: lineWidth * sf
148
145
  });
149
- ctx.slide.addShape(ctx.pptx.ShapeType.line, {
150
- x: pxToIn(midX),
151
- y: pxToIn(childCenterY),
152
- w: pxToIn(childLeftX - midX),
153
- h: 0,
154
- line: {
155
- color: lineColor,
156
- width: pxToPt(lineWidth * sf)
157
- }
146
+ addStraightLine(ctx, {
147
+ x1: midX,
148
+ y1: childCenterY,
149
+ x2: childLeftX,
150
+ y2: childCenterY
151
+ }, {
152
+ color: lineColor,
153
+ lineWidth: lineWidth * sf
158
154
  });
159
155
  }
160
156
  }
@@ -162,37 +158,43 @@ function renderTreeNode(node, ctx) {
162
158
  const color = layoutNode.item.color ?? defaultNodeColor;
163
159
  const shapeType = (() => {
164
160
  switch (shape) {
165
- case "rect": return ctx.pptx.ShapeType.rect;
166
- case "roundRect": return ctx.pptx.ShapeType.roundRect;
167
- case "ellipse": return ctx.pptx.ShapeType.ellipse;
161
+ case "rect": return "rect";
162
+ case "roundRect": return "roundRect";
163
+ case "ellipse": return "ellipse";
168
164
  }
169
165
  })();
170
166
  const drawX = ox + layoutNode.x * sf;
171
167
  const drawY = oy + layoutNode.y * sf;
172
168
  const drawW = layoutNode.width * sf;
173
169
  const drawH = layoutNode.height * sf;
174
- ctx.slide.addShape(shapeType, {
175
- x: pxToIn(drawX),
176
- y: pxToIn(drawY),
177
- w: pxToIn(drawW),
178
- h: pxToIn(drawH),
179
- fill: { color },
180
- line: {
170
+ addGlimpseShape(ctx, {
171
+ geometry: {
172
+ kind: "preset",
173
+ preset: shapeType
174
+ },
175
+ ...createShapeBoundsInput({
176
+ x: drawX,
177
+ y: drawY,
178
+ w: drawW,
179
+ h: drawH
180
+ }),
181
+ fill: solidShapeFill(color),
182
+ outline: shapeOutline({
181
183
  color: "333333",
182
- width: pxToPt(1 * sf)
183
- }
184
- });
185
- ctx.slide.addText(layoutNode.item.label, {
186
- x: pxToIn(drawX),
187
- y: pxToIn(drawY),
188
- w: pxToIn(drawW),
189
- h: pxToIn(drawH),
190
- fontSize: pxToPt(12 * sf),
191
- fontFace: "Noto Sans JP",
192
- color: stripHash(layoutNode.item.textColor) ?? defaultTextColor,
193
- align: "center",
194
- valign: "middle"
195
- });
184
+ width: 1 * sf
185
+ }),
186
+ body: { anchor: "middle" },
187
+ paragraphs: createGlimpseParagraphs(layoutNode.item.label, {
188
+ fontSize: 12 * sf,
189
+ fontFace: "Noto Sans JP",
190
+ color: stripHash(layoutNode.item.textColor) ?? defaultTextColor
191
+ }, { align: "center" })
192
+ }, {
193
+ x: drawX,
194
+ y: drawY,
195
+ w: drawW,
196
+ h: drawH
197
+ }, { fillColor: color });
196
198
  }
197
199
  function drawAllConnectors(layoutNode, sf, ox, oy) {
198
200
  for (const child of layoutNode.children) {
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","names":[],"sources":["../../../src/renderPptx/nodes/tree.ts"],"sourcesContent":["import type {\n PositionedNode,\n TreeDataItem,\n TreeNodeShape,\n TreeConnectorStyle,\n} from \"../../types.ts\";\nimport type { RenderContext } from \"../types.ts\";\nimport { stripHash } from \"../utils/visualStyle.ts\";\nimport { pxToIn, pxToPt } from \"../units.ts\";\nimport { resolveScaledContentArea } from \"../utils/scaleToFit.ts\";\n\ntype TreePositionedNode = Extract<PositionedNode, { type: \"tree\" }>;\n\ninterface LayoutNode {\n item: TreeDataItem;\n x: number;\n y: number;\n width: number;\n height: number;\n children: LayoutNode[];\n}\n\nexport function renderTreeNode(\n node: TreePositionedNode,\n ctx: RenderContext,\n): void {\n const layout = node.layout ?? \"vertical\";\n const nodeShape = node.nodeShape ?? \"rect\";\n const nodeWidth = node.nodeWidth ?? 120;\n const nodeHeight = node.nodeHeight ?? 40;\n const levelGap = node.levelGap ?? 60;\n const siblingGap = node.siblingGap ?? 20;\n const connectorStyle = node.connectorStyle ?? {};\n const defaultColor = \"1D4ED8\";\n const defaultTextColor = stripHash(node.textColor) ?? \"FFFFFF\";\n\n // サブツリーの幅/高さを計算\n function calculateSubtreeSize(item: TreeDataItem): {\n width: number;\n height: number;\n } {\n if (!item.children || item.children.length === 0) {\n return { width: nodeWidth, height: nodeHeight };\n }\n\n const childSizes = item.children.map(calculateSubtreeSize);\n\n if (layout === \"vertical\") {\n const childrenWidth =\n childSizes.reduce((sum, s) => sum + s.width, 0) +\n siblingGap * (childSizes.length - 1);\n const childrenHeight = Math.max(...childSizes.map((s) => s.height));\n return {\n width: Math.max(nodeWidth, childrenWidth),\n height: nodeHeight + levelGap + childrenHeight,\n };\n } else {\n const childrenHeight =\n childSizes.reduce((sum, s) => sum + s.height, 0) +\n siblingGap * (childSizes.length - 1);\n const childrenWidth = Math.max(...childSizes.map((s) => s.width));\n return {\n width: nodeWidth + levelGap + childrenWidth,\n height: Math.max(nodeHeight, childrenHeight),\n };\n }\n }\n\n // ツリーレイアウトを計算(原点(0,0)からの相対座標)\n function calculateTreeLayout(\n item: TreeDataItem,\n x: number,\n y: number,\n ): LayoutNode {\n const subtreeSize = calculateSubtreeSize(item);\n const layoutNode: LayoutNode = {\n item,\n x: 0,\n y: 0,\n width: nodeWidth,\n height: nodeHeight,\n children: [],\n };\n\n if (layout === \"vertical\") {\n // ノードを中央上部に配置\n layoutNode.x = x + subtreeSize.width / 2 - nodeWidth / 2;\n layoutNode.y = y;\n\n // 子ノードを配置\n if (item.children && item.children.length > 0) {\n const childSizes = item.children.map(calculateSubtreeSize);\n const totalChildWidth =\n childSizes.reduce((sum, s) => sum + s.width, 0) +\n siblingGap * (childSizes.length - 1);\n let childX = x + subtreeSize.width / 2 - totalChildWidth / 2;\n const childY = y + nodeHeight + levelGap;\n\n for (let i = 0; i < item.children.length; i++) {\n const child = item.children[i];\n const childLayout = calculateTreeLayout(child, childX, childY);\n layoutNode.children.push(childLayout);\n childX += childSizes[i].width + siblingGap;\n }\n }\n } else {\n // horizontal: ノードを左中央に配置\n layoutNode.x = x;\n layoutNode.y = y + subtreeSize.height / 2 - nodeHeight / 2;\n\n // 子ノードを配置\n if (item.children && item.children.length > 0) {\n const childSizes = item.children.map(calculateSubtreeSize);\n const totalChildHeight =\n childSizes.reduce((sum, s) => sum + s.height, 0) +\n siblingGap * (childSizes.length - 1);\n const childX = x + nodeWidth + levelGap;\n let childY = y + subtreeSize.height / 2 - totalChildHeight / 2;\n\n for (let i = 0; i < item.children.length; i++) {\n const child = item.children[i];\n const childLayout = calculateTreeLayout(child, childX, childY);\n layoutNode.children.push(childLayout);\n childY += childSizes[i].height + siblingGap;\n }\n }\n }\n\n return layoutNode;\n }\n\n // 接続線を描画\n function drawConnector(\n parent: LayoutNode,\n child: LayoutNode,\n style: TreeConnectorStyle,\n sf: number,\n ox: number,\n oy: number,\n ) {\n const lineColor = style.color ?? \"333333\";\n const lineWidth = style.width ?? 2;\n\n if (layout === \"vertical\") {\n // 親の下端中央から子の上端中央へ\n const parentCenterX = ox + (parent.x + parent.width / 2) * sf;\n const parentBottomY = oy + (parent.y + parent.height) * sf;\n const childCenterX = ox + (child.x + child.width / 2) * sf;\n const childTopY = oy + child.y * sf;\n const midY = (parentBottomY + childTopY) / 2;\n\n // 垂直線(親から中間点まで)\n ctx.slide.addShape(ctx.pptx.ShapeType.line, {\n x: pxToIn(parentCenterX),\n y: pxToIn(parentBottomY),\n w: 0,\n h: pxToIn(midY - parentBottomY),\n line: { color: lineColor, width: pxToPt(lineWidth * sf) },\n });\n\n // 水平線(中間点で)\n const minX = Math.min(parentCenterX, childCenterX);\n const maxX = Math.max(parentCenterX, childCenterX);\n if (maxX > minX) {\n ctx.slide.addShape(ctx.pptx.ShapeType.line, {\n x: pxToIn(minX),\n y: pxToIn(midY),\n w: pxToIn(maxX - minX),\n h: 0,\n line: { color: lineColor, width: pxToPt(lineWidth * sf) },\n });\n }\n\n // 垂直線(中間点から子まで)\n ctx.slide.addShape(ctx.pptx.ShapeType.line, {\n x: pxToIn(childCenterX),\n y: pxToIn(midY),\n w: 0,\n h: pxToIn(childTopY - midY),\n line: { color: lineColor, width: pxToPt(lineWidth * sf) },\n });\n } else {\n // 親の右端中央から子の左端中央へ\n const parentRightX = ox + (parent.x + parent.width) * sf;\n const parentCenterY = oy + (parent.y + parent.height / 2) * sf;\n const childLeftX = ox + child.x * sf;\n const childCenterY = oy + (child.y + child.height / 2) * sf;\n const midX = (parentRightX + childLeftX) / 2;\n\n // 水平線(親から中間点まで)\n ctx.slide.addShape(ctx.pptx.ShapeType.line, {\n x: pxToIn(parentRightX),\n y: pxToIn(parentCenterY),\n w: pxToIn(midX - parentRightX),\n h: 0,\n line: { color: lineColor, width: pxToPt(lineWidth * sf) },\n });\n\n // 垂直線(中間点で)\n const minY = Math.min(parentCenterY, childCenterY);\n const maxY = Math.max(parentCenterY, childCenterY);\n if (maxY > minY) {\n ctx.slide.addShape(ctx.pptx.ShapeType.line, {\n x: pxToIn(midX),\n y: pxToIn(minY),\n w: 0,\n h: pxToIn(maxY - minY),\n line: { color: lineColor, width: pxToPt(lineWidth * sf) },\n });\n }\n\n // 水平線(中間点から子まで)\n ctx.slide.addShape(ctx.pptx.ShapeType.line, {\n x: pxToIn(midX),\n y: pxToIn(childCenterY),\n w: pxToIn(childLeftX - midX),\n h: 0,\n line: { color: lineColor, width: pxToPt(lineWidth * sf) },\n });\n }\n }\n\n // ノードを描画\n function drawTreeNode(\n layoutNode: LayoutNode,\n shape: TreeNodeShape,\n defaultNodeColor: string,\n sf: number,\n ox: number,\n oy: number,\n ) {\n const color = layoutNode.item.color ?? defaultNodeColor;\n const shapeType = (() => {\n switch (shape) {\n case \"rect\":\n return ctx.pptx.ShapeType.rect;\n case \"roundRect\":\n return ctx.pptx.ShapeType.roundRect;\n case \"ellipse\":\n return ctx.pptx.ShapeType.ellipse;\n }\n })();\n\n const drawX = ox + layoutNode.x * sf;\n const drawY = oy + layoutNode.y * sf;\n const drawW = layoutNode.width * sf;\n const drawH = layoutNode.height * sf;\n\n // ノードの背景\n ctx.slide.addShape(shapeType, {\n x: pxToIn(drawX),\n y: pxToIn(drawY),\n w: pxToIn(drawW),\n h: pxToIn(drawH),\n fill: { color },\n line: { color: \"333333\", width: pxToPt(1 * sf) },\n });\n\n // ノードのラベル\n ctx.slide.addText(layoutNode.item.label, {\n x: pxToIn(drawX),\n y: pxToIn(drawY),\n w: pxToIn(drawW),\n h: pxToIn(drawH),\n fontSize: pxToPt(12 * sf),\n fontFace: \"Noto Sans JP\",\n color: stripHash(layoutNode.item.textColor) ?? defaultTextColor,\n align: \"center\",\n valign: \"middle\",\n });\n }\n\n // すべての接続線を再帰的に描画\n function drawAllConnectors(\n layoutNode: LayoutNode,\n sf: number,\n ox: number,\n oy: number,\n ) {\n for (const child of layoutNode.children) {\n drawConnector(layoutNode, child, connectorStyle, sf, ox, oy);\n drawAllConnectors(child, sf, ox, oy);\n }\n }\n\n // すべてのノードを再帰的に描画\n function drawAllNodes(\n layoutNode: LayoutNode,\n sf: number,\n ox: number,\n oy: number,\n ) {\n drawTreeNode(layoutNode, nodeShape, defaultColor, sf, ox, oy);\n for (const child of layoutNode.children) {\n drawAllNodes(child, sf, ox, oy);\n }\n }\n\n // ツリーのサイズを計算\n const treeSize = calculateSubtreeSize(node.data);\n\n // スケール係数を計算(コンテンツ領域基準)\n const { content, scaleFactor } = resolveScaledContentArea(\n node,\n treeSize,\n ctx,\n );\n\n // スケール後のサイズで中央配置オフセットを計算\n const scaledW = treeSize.width * scaleFactor;\n const scaledH = treeSize.height * scaleFactor;\n const offsetX = content.x + (content.w - scaledW) / 2;\n const offsetY = content.y + (content.h - scaledH) / 2;\n\n // レイアウト計算(原点(0,0)からの相対座標)\n const rootLayout = calculateTreeLayout(node.data, 0, 0);\n\n // 描画(接続線を先に、ノードを後に描画)\n drawAllConnectors(rootLayout, scaleFactor, offsetX, offsetY);\n drawAllNodes(rootLayout, scaleFactor, offsetX, offsetY);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tree.js","names":[],"sources":["../../../src/renderPptx/nodes/tree.ts"],"sourcesContent":["import type {\n PositionedNode,\n TreeDataItem,\n TreeNodeShape,\n TreeConnectorStyle,\n} from \"../../types.ts\";\nimport type { RenderContext } from \"../types.ts\";\nimport { stripHash } from \"../utils/visualStyle.ts\";\nimport { resolveScaledContentArea } from \"../utils/scaleToFit.ts\";\nimport { addStraightLine } from \"../utils/straightLine.ts\";\nimport {\n addGlimpseShape,\n createShapeBoundsInput,\n shapeOutline,\n solidShapeFill,\n} from \"../utils/glimpseShape.ts\";\nimport { createGlimpseParagraphs } from \"../utils/glimpseTextBox.ts\";\n\ntype TreePositionedNode = Extract<PositionedNode, { type: \"tree\" }>;\n\ninterface LayoutNode {\n item: TreeDataItem;\n x: number;\n y: number;\n width: number;\n height: number;\n children: LayoutNode[];\n}\n\nexport function renderTreeNode(\n node: TreePositionedNode,\n ctx: RenderContext,\n): void {\n const layout = node.layout ?? \"vertical\";\n const nodeShape = node.nodeShape ?? \"rect\";\n const nodeWidth = node.nodeWidth ?? 120;\n const nodeHeight = node.nodeHeight ?? 40;\n const levelGap = node.levelGap ?? 60;\n const siblingGap = node.siblingGap ?? 20;\n const connectorStyle = node.connectorStyle ?? {};\n const defaultColor = \"1D4ED8\";\n const defaultTextColor = stripHash(node.textColor) ?? \"FFFFFF\";\n\n // サブツリーの幅/高さを計算\n function calculateSubtreeSize(item: TreeDataItem): {\n width: number;\n height: number;\n } {\n if (!item.children || item.children.length === 0) {\n return { width: nodeWidth, height: nodeHeight };\n }\n\n const childSizes = item.children.map(calculateSubtreeSize);\n\n if (layout === \"vertical\") {\n const childrenWidth =\n childSizes.reduce((sum, s) => sum + s.width, 0) +\n siblingGap * (childSizes.length - 1);\n const childrenHeight = Math.max(...childSizes.map((s) => s.height));\n return {\n width: Math.max(nodeWidth, childrenWidth),\n height: nodeHeight + levelGap + childrenHeight,\n };\n } else {\n const childrenHeight =\n childSizes.reduce((sum, s) => sum + s.height, 0) +\n siblingGap * (childSizes.length - 1);\n const childrenWidth = Math.max(...childSizes.map((s) => s.width));\n return {\n width: nodeWidth + levelGap + childrenWidth,\n height: Math.max(nodeHeight, childrenHeight),\n };\n }\n }\n\n // ツリーレイアウトを計算(原点(0,0)からの相対座標)\n function calculateTreeLayout(\n item: TreeDataItem,\n x: number,\n y: number,\n ): LayoutNode {\n const subtreeSize = calculateSubtreeSize(item);\n const layoutNode: LayoutNode = {\n item,\n x: 0,\n y: 0,\n width: nodeWidth,\n height: nodeHeight,\n children: [],\n };\n\n if (layout === \"vertical\") {\n // ノードを中央上部に配置\n layoutNode.x = x + subtreeSize.width / 2 - nodeWidth / 2;\n layoutNode.y = y;\n\n // 子ノードを配置\n if (item.children && item.children.length > 0) {\n const childSizes = item.children.map(calculateSubtreeSize);\n const totalChildWidth =\n childSizes.reduce((sum, s) => sum + s.width, 0) +\n siblingGap * (childSizes.length - 1);\n let childX = x + subtreeSize.width / 2 - totalChildWidth / 2;\n const childY = y + nodeHeight + levelGap;\n\n for (let i = 0; i < item.children.length; i++) {\n const child = item.children[i];\n const childLayout = calculateTreeLayout(child, childX, childY);\n layoutNode.children.push(childLayout);\n childX += childSizes[i].width + siblingGap;\n }\n }\n } else {\n // horizontal: ノードを左中央に配置\n layoutNode.x = x;\n layoutNode.y = y + subtreeSize.height / 2 - nodeHeight / 2;\n\n // 子ノードを配置\n if (item.children && item.children.length > 0) {\n const childSizes = item.children.map(calculateSubtreeSize);\n const totalChildHeight =\n childSizes.reduce((sum, s) => sum + s.height, 0) +\n siblingGap * (childSizes.length - 1);\n const childX = x + nodeWidth + levelGap;\n let childY = y + subtreeSize.height / 2 - totalChildHeight / 2;\n\n for (let i = 0; i < item.children.length; i++) {\n const child = item.children[i];\n const childLayout = calculateTreeLayout(child, childX, childY);\n layoutNode.children.push(childLayout);\n childY += childSizes[i].height + siblingGap;\n }\n }\n }\n\n return layoutNode;\n }\n\n // 接続線を描画\n function drawConnector(\n parent: LayoutNode,\n child: LayoutNode,\n style: TreeConnectorStyle,\n sf: number,\n ox: number,\n oy: number,\n ) {\n const lineColor = style.color ?? \"333333\";\n const lineWidth = style.width ?? 2;\n\n if (layout === \"vertical\") {\n // 親の下端中央から子の上端中央へ\n const parentCenterX = ox + (parent.x + parent.width / 2) * sf;\n const parentBottomY = oy + (parent.y + parent.height) * sf;\n const childCenterX = ox + (child.x + child.width / 2) * sf;\n const childTopY = oy + child.y * sf;\n const midY = (parentBottomY + childTopY) / 2;\n\n // 垂直線(親から中間点まで)\n addStraightLine(\n ctx,\n {\n x1: parentCenterX,\n y1: parentBottomY,\n x2: parentCenterX,\n y2: midY,\n },\n { color: lineColor, lineWidth: lineWidth * sf },\n );\n\n // 水平線(中間点で)\n const minX = Math.min(parentCenterX, childCenterX);\n const maxX = Math.max(parentCenterX, childCenterX);\n if (maxX > minX) {\n addStraightLine(\n ctx,\n { x1: minX, y1: midY, x2: maxX, y2: midY },\n { color: lineColor, lineWidth: lineWidth * sf },\n );\n }\n\n // 垂直線(中間点から子まで)\n addStraightLine(\n ctx,\n { x1: childCenterX, y1: midY, x2: childCenterX, y2: childTopY },\n { color: lineColor, lineWidth: lineWidth * sf },\n );\n } else {\n // 親の右端中央から子の左端中央へ\n const parentRightX = ox + (parent.x + parent.width) * sf;\n const parentCenterY = oy + (parent.y + parent.height / 2) * sf;\n const childLeftX = ox + child.x * sf;\n const childCenterY = oy + (child.y + child.height / 2) * sf;\n const midX = (parentRightX + childLeftX) / 2;\n\n // 水平線(親から中間点まで)\n addStraightLine(\n ctx,\n { x1: parentRightX, y1: parentCenterY, x2: midX, y2: parentCenterY },\n { color: lineColor, lineWidth: lineWidth * sf },\n );\n\n // 垂直線(中間点で)\n const minY = Math.min(parentCenterY, childCenterY);\n const maxY = Math.max(parentCenterY, childCenterY);\n if (maxY > minY) {\n addStraightLine(\n ctx,\n { x1: midX, y1: minY, x2: midX, y2: maxY },\n { color: lineColor, lineWidth: lineWidth * sf },\n );\n }\n\n // 水平線(中間点から子まで)\n addStraightLine(\n ctx,\n { x1: midX, y1: childCenterY, x2: childLeftX, y2: childCenterY },\n { color: lineColor, lineWidth: lineWidth * sf },\n );\n }\n }\n\n // ノードを描画\n function drawTreeNode(\n layoutNode: LayoutNode,\n shape: TreeNodeShape,\n defaultNodeColor: string,\n sf: number,\n ox: number,\n oy: number,\n ) {\n const color = layoutNode.item.color ?? defaultNodeColor;\n const shapeType = (() => {\n switch (shape) {\n case \"rect\":\n return \"rect\";\n case \"roundRect\":\n return \"roundRect\";\n case \"ellipse\":\n return \"ellipse\";\n }\n })();\n\n const drawX = ox + layoutNode.x * sf;\n const drawY = oy + layoutNode.y * sf;\n const drawW = layoutNode.width * sf;\n const drawH = layoutNode.height * sf;\n\n addGlimpseShape(\n ctx,\n {\n geometry: { kind: \"preset\", preset: shapeType },\n ...createShapeBoundsInput({ x: drawX, y: drawY, w: drawW, h: drawH }),\n fill: solidShapeFill(color),\n outline: shapeOutline({ color: \"333333\", width: 1 * sf }),\n body: { anchor: \"middle\" },\n paragraphs: createGlimpseParagraphs(\n layoutNode.item.label,\n {\n fontSize: 12 * sf,\n fontFace: \"Noto Sans JP\",\n color: stripHash(layoutNode.item.textColor) ?? defaultTextColor,\n },\n { align: \"center\" },\n ),\n },\n { x: drawX, y: drawY, w: drawW, h: drawH },\n { fillColor: color },\n );\n }\n\n // すべての接続線を再帰的に描画\n function drawAllConnectors(\n layoutNode: LayoutNode,\n sf: number,\n ox: number,\n oy: number,\n ) {\n for (const child of layoutNode.children) {\n drawConnector(layoutNode, child, connectorStyle, sf, ox, oy);\n drawAllConnectors(child, sf, ox, oy);\n }\n }\n\n // すべてのノードを再帰的に描画\n function drawAllNodes(\n layoutNode: LayoutNode,\n sf: number,\n ox: number,\n oy: number,\n ) {\n drawTreeNode(layoutNode, nodeShape, defaultColor, sf, ox, oy);\n for (const child of layoutNode.children) {\n drawAllNodes(child, sf, ox, oy);\n }\n }\n\n // ツリーのサイズを計算\n const treeSize = calculateSubtreeSize(node.data);\n\n // スケール係数を計算(コンテンツ領域基準)\n const { content, scaleFactor } = resolveScaledContentArea(\n node,\n treeSize,\n ctx,\n );\n\n // スケール後のサイズで中央配置オフセットを計算\n const scaledW = treeSize.width * scaleFactor;\n const scaledH = treeSize.height * scaleFactor;\n const offsetX = content.x + (content.w - scaledW) / 2;\n const offsetY = content.y + (content.h - scaledH) / 2;\n\n // レイアウト計算(原点(0,0)からの相対座標)\n const rootLayout = calculateTreeLayout(node.data, 0, 0);\n\n // 描画(接続線を先に、ノードを後に描画)\n drawAllConnectors(rootLayout, scaleFactor, offsetX, offsetY);\n drawAllNodes(rootLayout, scaleFactor, offsetX, offsetY);\n}\n"],"mappings":"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"}
@@ -0,0 +1,381 @@
1
+ import { parseGradient, parseLinearGradient } from "../shared/gradient.js";
2
+ import { EMU_PER_IN, pxToEmu, pxToPt } from "./units.js";
3
+ import { createTextOptions, resolveSubSup } from "./textOptions.js";
4
+ import { addChart, addPicture, addShape, addTable, addTextBox, asEmu, asHundredthPt, asOoxmlAngle, asOoxmlPercent, asPt, createPptx, setSlideBackground } from "@pptx-glimpse/document";
5
+ //#region src/renderPptx/pptxAuthoring.ts
6
+ function cleanHex(color) {
7
+ const hex = color?.replace(/^#/, "").toUpperCase();
8
+ return hex?.length === 3 ? [...hex].map((character) => character.repeat(2)).join("") : hex;
9
+ }
10
+ function toColorInput(color, opacity) {
11
+ const hex = cleanHex(color);
12
+ if (!hex) return void 0;
13
+ return {
14
+ kind: "srgb",
15
+ hex,
16
+ transforms: opacity === void 0 ? void 0 : [{
17
+ kind: "alpha",
18
+ value: asOoxmlPercent(Math.round(opacity * 1e5))
19
+ }]
20
+ };
21
+ }
22
+ function toUnderlineInput(underline) {
23
+ if (underline === void 0 || underline === false) return void 0;
24
+ if (underline === true) return true;
25
+ return {
26
+ style: underline.style,
27
+ color: toColorInput(underline.color)
28
+ };
29
+ }
30
+ function toBaselineInput(subscript, superscript) {
31
+ if (subscript) return {
32
+ type: "percent",
33
+ value: asOoxmlPercent(-4e4)
34
+ };
35
+ if (superscript) return {
36
+ type: "percent",
37
+ value: asOoxmlPercent(3e4)
38
+ };
39
+ }
40
+ function toGlowInput(glow) {
41
+ if (!glow) return void 0;
42
+ return {
43
+ radius: asEmu(Math.round(pxToEmu(glow.size ?? 8))),
44
+ color: toColorInput(glow.color ?? "FFFFFF", glow.opacity ?? .75)
45
+ };
46
+ }
47
+ function toOutlineInput(outline) {
48
+ if (!outline) return void 0;
49
+ return {
50
+ width: asEmu(Math.round(pxToEmu(outline.size ?? 1))),
51
+ color: toColorInput(outline.color ?? "FFFFFF")
52
+ };
53
+ }
54
+ function toCharSpacing(letterSpacingPx) {
55
+ if (letterSpacingPx === void 0) return void 0;
56
+ return Math.round(pxToPt(letterSpacingPx) * 100);
57
+ }
58
+ function toTextGradientInput(value) {
59
+ if (!value) return void 0;
60
+ const linear = parseLinearGradient(value);
61
+ if (!linear) return void 0;
62
+ const dmlAngle = ((linear.angle - 90) % 360 + 360) % 360;
63
+ return {
64
+ gradientType: "linear",
65
+ angle: asOoxmlAngle(Math.round(dmlAngle * 6e4)),
66
+ stops: linear.stops.map((stop) => ({
67
+ position: asOoxmlPercent(Math.round(stop.position * 1e3)),
68
+ color: toColorInput(stop.color)
69
+ }))
70
+ };
71
+ }
72
+ function stripUndefined(value) {
73
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
74
+ }
75
+ function resolveUnderline(node, run) {
76
+ if (run?.underline !== void 0) return run.underline;
77
+ if (node.underline !== void 0) return node.underline;
78
+ return run?.href ? true : void 0;
79
+ }
80
+ function buildRunProperties(node, run, gradientFill) {
81
+ const fontSizePx = run?.fontSize ?? node.fontSize ?? 24;
82
+ const subSup = run ? resolveSubSup(run, node) : node;
83
+ return stripUndefined({
84
+ fontFace: run?.fontFamily ?? node.fontFamily ?? "Noto Sans JP",
85
+ fontSize: asPt(pxToPt(fontSizePx)),
86
+ color: gradientFill ? void 0 : toColorInput(run?.color ?? node.color),
87
+ gradientFill,
88
+ bold: run?.bold ?? node.bold,
89
+ italic: run?.italic ?? node.italic,
90
+ underline: toUnderlineInput(resolveUnderline(node, run)),
91
+ strike: run?.strike ?? node.strike,
92
+ baseline: toBaselineInput(subSup.subscript, subSup.superscript),
93
+ highlight: toColorInput(run?.highlight ?? node.highlight),
94
+ glow: toGlowInput(node.glow),
95
+ outline: toOutlineInput(node.outline),
96
+ charSpacing: toCharSpacing(run?.letterSpacing ?? node.letterSpacing)
97
+ });
98
+ }
99
+ function buildParagraphs(node) {
100
+ const gradientFill = toTextGradientInput(node.textGradient);
101
+ const sourceRuns = node.runs && node.runs.length > 0 ? node.runs.map((run) => ({
102
+ text: run.text,
103
+ properties: buildRunProperties(node, run, gradientFill),
104
+ href: run.href
105
+ })) : [{
106
+ text: node.text ?? "",
107
+ properties: buildRunProperties(node, void 0, gradientFill)
108
+ }];
109
+ const paragraphRuns = [[]];
110
+ for (const run of sourceRuns) run.text.replace(/\r*\n/g, "\n").split("\n").forEach((line, index) => {
111
+ if (index > 0) paragraphRuns.push([]);
112
+ paragraphRuns.at(-1)?.push({
113
+ ...run,
114
+ text: line
115
+ });
116
+ });
117
+ const lineHeight = node.lineHeight ?? 1.3;
118
+ const fontSizePx = node.fontSize ?? 24;
119
+ return paragraphRuns.map((runs) => ({
120
+ properties: {
121
+ align: node.textAlign,
122
+ marginLeft: asEmu(0),
123
+ indent: asEmu(0),
124
+ bullet: { type: "none" },
125
+ lineSpacing: asHundredthPt(Math.round(pxToPt(fontSizePx * lineHeight) * 100))
126
+ },
127
+ runs: runs.map((run) => ({
128
+ text: run.text,
129
+ properties: run.properties,
130
+ hyperlink: run.href
131
+ }))
132
+ }));
133
+ }
134
+ function toGradientFill(value, opacity) {
135
+ const gradient = parseGradient(value);
136
+ if (!gradient) return void 0;
137
+ const stops = gradient.value.stops.map((stop) => ({
138
+ position: asOoxmlPercent(Math.round(stop.position * 1e3)),
139
+ color: toColorInput(stop.color, opacity)
140
+ }));
141
+ if (gradient.kind === "linear") {
142
+ const dmlAngle = ((gradient.value.angle - 90) % 360 + 360) % 360;
143
+ return {
144
+ kind: "gradient",
145
+ gradientType: "linear",
146
+ angle: asOoxmlAngle(Math.round(dmlAngle * 6e4)),
147
+ stops
148
+ };
149
+ }
150
+ return {
151
+ kind: "gradient",
152
+ gradientType: "radial",
153
+ centerX: asOoxmlPercent(Math.round(gradient.value.centerX * 1e3)),
154
+ centerY: asOoxmlPercent(Math.round(gradient.value.centerY * 1e3)),
155
+ stops
156
+ };
157
+ }
158
+ function withFillOpacity(fill, opacity) {
159
+ if (!fill || opacity === void 0 || fill.kind !== "solid") return fill;
160
+ return {
161
+ ...fill,
162
+ color: toColorInput(fill.color.hex, opacity)
163
+ };
164
+ }
165
+ function toShadowEffects(shadow) {
166
+ if (!shadow) return void 0;
167
+ const common = {
168
+ blurRadius: asEmu(Math.round((shadow.blur ?? 3) * 12700)),
169
+ distance: asEmu(Math.round((shadow.offset ?? 23e3 / 12700) * 12700)),
170
+ direction: asOoxmlAngle(Math.round((shadow.angle ?? 90) * 6e4)),
171
+ color: toColorInput(shadow.color ?? "000000", shadow.opacity ?? .35)
172
+ };
173
+ return shadow.type === "inner" ? { innerShadow: common } : { outerShadow: {
174
+ ...common,
175
+ alignment: "bl",
176
+ rotateWithShape: true
177
+ } };
178
+ }
179
+ function customGeometry(input) {
180
+ const commands = [];
181
+ let moved = false;
182
+ for (const point of input.points) {
183
+ if ("close" in point) {
184
+ if (moved) commands.push({ kind: "close" });
185
+ continue;
186
+ }
187
+ commands.push({
188
+ kind: moved ? "lineTo" : "moveTo",
189
+ x: Math.round(point.x * EMU_PER_IN),
190
+ y: Math.round(point.y * EMU_PER_IN)
191
+ });
192
+ moved = true;
193
+ }
194
+ if (!moved) return void 0;
195
+ return {
196
+ kind: "custom",
197
+ paths: [{
198
+ width: Math.round(input.width * EMU_PER_IN),
199
+ height: Math.round(input.height * EMU_PER_IN),
200
+ commands
201
+ }]
202
+ };
203
+ }
204
+ function enrichShapeInput(input, options) {
205
+ const preset = input.geometry.kind === "preset" ? input.geometry.preset : "";
206
+ const geometry = options?.customGeometry ? customGeometry(options.customGeometry) ?? input.geometry : preset === "roundRect" && options?.rectRadius !== void 0 ? {
207
+ ...input.geometry,
208
+ adjustValues: { adj: Math.round(options.rectRadius * 5e4) }
209
+ } : input.geometry;
210
+ const gradientFill = options?.backgroundGradient ? toGradientFill(options.backgroundGradient, options.fillOpacity) : void 0;
211
+ const outlineGradient = options?.outlineGradient ? toGradientFill(options.outlineGradient, options.outlineOpacity ?? options.fillOpacity) : void 0;
212
+ const outline = input.outline ? {
213
+ ...input.outline,
214
+ fill: outlineGradient ?? withFillOpacity(input.outline.fill, options?.outlineOpacity),
215
+ dash: options?.dashType ?? input.outline.dash
216
+ } : outlineGradient ? { fill: outlineGradient } : void 0;
217
+ const glow = options?.glow ? {
218
+ radius: asEmu(Math.round(pxToEmu(options.glow.size ?? 8))),
219
+ color: toColorInput(options.glow.color ?? "FFFFFF", options.glow.opacity ?? .75)
220
+ } : input.effects?.glow;
221
+ const effects = {
222
+ ...input.effects,
223
+ ...toShadowEffects(options?.shadow),
224
+ ...glow ? { glow } : {}
225
+ };
226
+ const width = preset === "line" && options?.zeroWidth ? asEmu(0) : input.width;
227
+ let height = preset === "line" && options?.zeroHeight ? asEmu(0) : input.height;
228
+ if (preset === "line" && width === 0 && height === 0) height = asEmu(1);
229
+ return {
230
+ ...input,
231
+ geometry,
232
+ width,
233
+ height,
234
+ fill: gradientFill ?? withFillOpacity(input.fill, options?.fillOpacity),
235
+ outline,
236
+ effects: Object.keys(effects).length > 0 ? effects : void 0,
237
+ flipHorizontal: options?.flipH ?? input.flipHorizontal,
238
+ flipVertical: options?.flipV ?? input.flipVertical
239
+ };
240
+ }
241
+ function applyHyperlinks(input, hyperlinks) {
242
+ if (!hyperlinks?.some(Boolean) || !input.paragraphs) return input;
243
+ let index = 0;
244
+ return {
245
+ ...input,
246
+ paragraphs: input.paragraphs.map((paragraph) => ({
247
+ ...paragraph,
248
+ runs: paragraph.runs.map((run) => ({
249
+ ...run,
250
+ hyperlink: hyperlinks[index++]
251
+ }))
252
+ }))
253
+ };
254
+ }
255
+ var PptxAuthoringRegistry = class {
256
+ currentSource;
257
+ currentSlideHandle;
258
+ useLayoutTextMargins = false;
259
+ textCount = 0;
260
+ shapeCount = 0;
261
+ pictureCount = 0;
262
+ tableCount = 0;
263
+ chartCount = 0;
264
+ constructor() {
265
+ const source = createPptx();
266
+ this.currentSource = source;
267
+ this.currentSlideHandle = source.slides[0]?.handle;
268
+ }
269
+ initialize(source, useLayoutTextMargins = false) {
270
+ this.currentSource = source;
271
+ this.useLayoutTextMargins = useLayoutTextMargins;
272
+ }
273
+ selectSlide(handle) {
274
+ this.currentSlideHandle = handle;
275
+ }
276
+ get source() {
277
+ if (!this.currentSource) throw new Error("glimpse authoring is not initialized");
278
+ return this.currentSource;
279
+ }
280
+ get entries() {
281
+ return (this.source.edits ?? []).flatMap((edit) => (edit.kind === "addTextBox" || edit.kind === "addShape") && "xml" in edit ? [{
282
+ kind: "shape",
283
+ xml: edit.xml
284
+ }] : []);
285
+ }
286
+ replaceSource(source) {
287
+ this.currentSource = source;
288
+ }
289
+ get target() {
290
+ if (!this.currentSlideHandle) throw new Error("glimpse slide is not selected");
291
+ return this.currentSlideHandle;
292
+ }
293
+ register(node) {
294
+ const textOptions = createTextOptions(node);
295
+ this.registerTextBox({
296
+ offsetX: asEmu(Math.round(textOptions.x * EMU_PER_IN)),
297
+ offsetY: asEmu(Math.round(textOptions.y * EMU_PER_IN)),
298
+ width: asEmu(Math.round(textOptions.w * EMU_PER_IN)),
299
+ height: asEmu(Math.round(textOptions.h * EMU_PER_IN)),
300
+ rotation: node.rotate === void 0 ? void 0 : asOoxmlAngle(Math.round(node.rotate * 6e4)),
301
+ body: this.useLayoutTextMargins ? void 0 : {
302
+ anchor: "top",
303
+ marginLeft: asEmu(0),
304
+ marginRight: asEmu(0),
305
+ marginTop: asEmu(0),
306
+ marginBottom: asEmu(0)
307
+ },
308
+ paragraphs: buildParagraphs(node)
309
+ });
310
+ }
311
+ registerTextBox(input, options) {
312
+ const name = options?.name ?? `Text ${++this.textCount}`;
313
+ this.currentSource = addTextBox(this.source, this.target, applyHyperlinks({
314
+ ...input,
315
+ name
316
+ }, options?.hyperlinks));
317
+ }
318
+ registerShape(input, options) {
319
+ const name = options?.name ?? `Shape ${++this.shapeCount}`;
320
+ this.currentSource = addShape(this.source, this.target, enrichShapeInput({
321
+ ...input,
322
+ name
323
+ }, options));
324
+ }
325
+ registerPicture(input, options) {
326
+ const name = options?.name ?? `Picture ${++this.pictureCount}`;
327
+ this.currentSource = addPicture(this.source, this.target, {
328
+ ...input,
329
+ name,
330
+ effects: toShadowEffects(options?.shadow)
331
+ });
332
+ }
333
+ registerTable(input, options) {
334
+ const name = options?.name ?? `Table ${++this.tableCount}`;
335
+ this.currentSource = addTable(this.source, this.target, {
336
+ ...input,
337
+ name
338
+ });
339
+ }
340
+ registerChart(input, options) {
341
+ const name = options?.name ?? `Chart ${++this.chartCount}`;
342
+ this.currentSource = addChart(this.source, this.target, {
343
+ ...input,
344
+ name
345
+ });
346
+ }
347
+ setSlideBackgroundGradient(backgroundGradient, opacity) {
348
+ const fill = toGradientFill(backgroundGradient, opacity);
349
+ if (!fill || fill.kind !== "gradient") return false;
350
+ const background = fill.gradientType === "linear" ? {
351
+ kind: "gradient",
352
+ gradientType: "linear",
353
+ stops: fill.stops,
354
+ angle: fill.angle ?? asOoxmlAngle(0)
355
+ } : {
356
+ kind: "gradient",
357
+ gradientType: "radial",
358
+ stops: fill.stops,
359
+ centerX: fill.centerX,
360
+ centerY: fill.centerY
361
+ };
362
+ this.currentSource = setSlideBackground(this.source, this.target, background);
363
+ return true;
364
+ }
365
+ setSlideBackgroundSolid(color) {
366
+ this.currentSource = setSlideBackground(this.source, this.target, {
367
+ kind: "solid",
368
+ color: toColorInput(color)
369
+ });
370
+ }
371
+ setSlideBackgroundImage(bytes) {
372
+ this.currentSource = setSlideBackground(this.source, this.target, {
373
+ kind: "image",
374
+ bytes
375
+ });
376
+ }
377
+ };
378
+ //#endregion
379
+ export { PptxAuthoringRegistry, cleanHex, toColorInput };
380
+
381
+ //# sourceMappingURL=pptxAuthoring.js.map