返回 ppt-master
native-shape-authoring.md
根目录 / skills / ppt-master / references / native-shape-authoring.md
1 > See [`shared-standards-core.md`](./shared-standards-core.md) §§1.4–1.5 for the native-shape metadata and validation contracts.
2
3 # Native Shape Authoring Reference
4
5 Use this reference during Executor SVG construction or project-owned canonical
6 template maintenance when basic primitives, one standard PowerPoint shape, or
7 supported shape/text operands can express the intended object. Prefer, in order:
8 editable basic primitives, one exact Office preset, then a PowerPoint-style
9 Boolean result from closed shapes and/or resolvable text. Hand-authored freeform
10 geometry is allowed only when those
11 constructions cannot faithfully express the object. Neither helper writes a
12 page. The preset helper does not create the shape's own `p:txBody`; keep visible
13 text outside the atomic fragment.
14
15 ## 1. Selection Gate
16
17 Apply this decision order before drawing any new geometric contour.
18
19 > This gate is for picking the **highest-level faithful native construction**.
20 > Do not hand-author a freeform merely because an SVG path is convenient.
21
22 | Condition | Action |
23 |---|---|
24 | Plain rectangle, symmetric rounded rectangle, circle, or ellipse | Write the ordinary SVG primitive; the exporter already emits an editable native shape. |
25 | Straight relationship, divider, or leader | Write `<line>`; use a registered marker only when direction is meaningful. |
26 | One DrawingML preset exactly expresses the intended object | Run `preset_shape_svg.py render`, then insert its complete stdout fragment into the hand-authored page or canonical template. |
27 | A stock `bentConnector*` / `curvedConnector*` contour exactly expresses a bent or curved relationship and endpoint attachment is not required | Run `preset_shape_svg.py render --object-kind connector`; the result is an unconnected native Connector shape. |
28 | Two or more supported closed-shape / resolvable-text operands require Union, Combine, Fragment, Intersect, or Subtract | Run `shape_boolean_svg.py render`, then replace the operands with every stdout path; the result remains ordinary editable custom geometry. |
29 | Basic primitives, one preset, and Boolean materialization cannot faithfully express the visual meaning or contour | Write ordinary `<path>` / `<polygon>` geometry; export keeps it as editable custom geometry. |
30 | The shape only resembles a preset | Never infer a preset; continue to the Boolean gate, then use freeform only if no faithful construction exists. |
31 | Mirror/preserve input already owns native-shape metadata | Keep the existing object and metadata; never reselect its preset. |
32
33 **Hard rule**: `preset_shape_svg.py` is the only authoring entry for
34 `data-pptx-authoring="preset"`. Never add `data-pptx-prst`, frame, adjustment,
35 or registry path data by hand. Insert the helper's complete compact `<g>` and
36 rerun the helper whenever its geometry or paint changes.
37
38 ---
39
40 ## 2. Semantic Preset Candidate Guide
41
42 Use the table below as the **go-to menu**: match the page's visual intent to a
43 candidate preset *before* defaulting to a plain rect or path. Reaching here
44 first is exactly how presets get used instead of forgotten.
45
46 "Automatic" means the Executor independently applies this semantic decision
47 gate before drawing a new object. It does not scan existing SVG, classify
48 paths or contours, or upgrade ordinary SVG during export.
49
50 | Visual intent | Candidate presets | Boundary |
51 |---|---|---|
52 | Literal geometric body | `triangle`, `diamond`, `pentagon`, `hexagon`, `octagon`, `star5` | Use only when the named geometry itself is the intent. |
53 | Solid block direction | `rightArrow`, `leftArrow`, `upArrow`, `downArrow`, `leftRightArrow`, `upDownArrow`, `chevron` | Use `<line>` for a thin straight relationship; do not fake a solid directional object with a stroked path. |
54 | Standard flowchart node | `flowChartProcess`, `flowChartDecision`, `flowChartInputOutput`, `flowChartTerminator`, `flowChartDocument` | Use only for an actual flowchart; ordinary content cards remain cards. |
55 | Stock bent / curved relationship contour | `bentConnector*`, `curvedConnector*` | Prefer when the contour fits and endpoint attachment is not required. The authored object is an unconnected native Connector, so moving nodes does not reroute it. |
56 | Stock callout | `wedgeRectCallout`, `wedgeRoundRectCallout`, `wedgeEllipseCallout`, `cloudCallout` | For a brand-specific or custom tail, continue through the Boolean gate; use freeform only if the result still cannot be expressed faithfully. |
57 | Stock ribbon or scroll | `ribbon*`, `ellipseRibbon*`, `verticalScroll`, `horizontalScroll` | Select only when the stock contour is visually acceptable. |
58 | Standalone math symbol | `mathPlus`, `mathMinus`, `mathMultiply`, `mathDivide`, `mathEqual`, `mathNotEqual` | Inline formulas and prose symbols remain text/formula assets. |
59 | Literal Office symbol | `heart`, `sun`, `moon`, `lightningBolt`, `gear6`, `gear9` | Never replace an icon required by `spec_lock.icons`. |
60
61 Use registry search for a less common literal shape:
62
63 ```bash
64 python3 ${SKILL_DIR}/scripts/preset_shape_svg.py list --search arrow
65 python3 ${SKILL_DIR}/scripts/preset_shape_svg.py describe rightArrow
66 ```
67
68 **Shape-first diagram rule**: use `<line>` for straight thin relationships;
69 use an exact connector-family preset for a stock bent or curved contour; use a
70 block-arrow / chevron preset for a solid direction. Resort to an open freeform
71 path only when those native constructions cannot faithfully express the
72 relationship, data geometry, or locked hand-drawn / organic style. Newly
73 authored connector-family presets remain unconnected and do not gain attachment
74 semantics. Existing Connector topology imported from a source PPTX remains
75 owned by the preserve/mirror round-trip contract.
76
77 **Forbidden — false native semantics**:
78
79 - `actionButton*` when navigation or trigger behavior is expected; the helper
80 maps its visual preset geometry only and never creates an action or hyperlink;
81 - `chartX`, `chartStar`, or `chartPlus` as a substitute for native charts;
82 - logo, icon glyph, illustration, brand contour, or data-chart marks.
83
84 ---
85
86 ## 3. Fragment Generation
87
88 Run one command for one selected object. Generated project pages choose the
89 object's solid paint from the current page context, using `spec_lock.md` roles as
90 reusable anchors rather than an exhaustive palette; `create-template` takes colors
91 from the confirmed brief and template `design_spec.md`. Mirror/preserve input
92 keeps the source object's paint instead of regenerating this authored form.
93
94 ```bash
95 python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \
96 --id p03-growth-arrow \
97 --frame 160 210 320 112 \
98 --fill "#2563EB" \
99 --stroke none \
100 --adjust "adj1=val 50000"
101 ```
102
103 For a stock bent / curved contour that does not require endpoint attachment:
104
105 ```bash
106 python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render bentConnector3 \
107 --id p03-flow-connector \
108 --object-kind connector \
109 --frame 420 180 220 140 \
110 --fill none \
111 --stroke "#475569" \
112 --stroke-width 2
113 ```
114
115 Every connector-family preset requires `--object-kind connector`, `--fill none`,
116 and a visible stroke. It exports as an unconnected `p:cxnSp`; a connector
117 preset can never be authored as an ordinary `shape`.
118
119 **Hard rule — stdout-only exception**: the helper prints one deterministic
120 `<g>` fragment. Read that output and insert it with the normal page/template
121 `apply_patch` edit. Do not redirect it into `svg_output/`, loop over pages or
122 templates, batch shapes, or let it choose layout. The main Agent still authors
123 every complete SVG page sequentially and maintains each reusable template
124 explicitly.
125
126 ---
127
128 ## 4. Atomic Fragment Contract
129
130 The helper emits one compact logical group. Metadata and base paint are written
131 once on the group; its direct children are the visible paths regenerated from
132 the locked preset registry.
133
134 | Component | Ownership |
135 |---|---|
136 | Logical `<g data-pptx-authoring="preset">` | Stable id, object kind, preset, frame, adjustments, and explicit local base paint. |
137 | Direct `<path>` children | Ordered browser-visible registry layers. A child writes only a path-specific fill/stroke override when the preset requires one. |
138 | Deliberately absent transport fields | No hidden carrier, preview wrapper, `data-pptx-part`, or stored fingerprint belongs in project-authored SVG. Those fields remain part of expanded PPTX import/round-trip transport. |
139
140 **Hard rule**: treat the returned group as atomic. Keep it as the content group
141 when it stands alone. When it needs labels, icons, or other decorations, put
142 the preset and those siblings in a separate parent content group; never put
143 them inside the preset group itself. Do not edit the direct paths; they are
144 validation evidence generated from the registry, not a freehand contour
145 surface.
146
147 Canonical page/template authoring also keeps paint and opacity off ancestor
148 groups that contain the preset. Compatible ancestor paint still exports under
149 the general SVG composition rules, but the checker warns because the atom is no
150 longer paint-self-contained; rerun the helper with channel alpha instead.
151
152 On a structured template, a validated authored-preset group is one semantic
153 atom. It may be Slide-local, the single carrier of an `object` slot, or a direct
154 Master/Layout fixed atom. This narrow exception does not permit ordinary nested
155 `<g>` structures in Master/Layout layers or placeholder carriers. The template
156 workflow may add the registered structural ownership attributes to the complete
157 helper group; it still must not alter preset metadata, paint, or direct paths.
158
159 **Frame coordinate space**: `--frame x y w h` is expressed in the coordinate
160 space where you insert the fragment. At the page root that is page coordinates;
161 inside a `<g transform="translate(…)">` use **group-local** coordinates — the
162 ancestor transform stacks on top, so page-absolute values would double-offset
163 the shape off-canvas. Keep the helper's exact space-separated ordinary-decimal
164 `data-pptx-frame` spelling; compact authoring does not accept alternate numeric
165 spellings.
166
167 **Regeneration rule**: rerun the helper when preset, frame, adjustment, fill,
168 stroke, or stroke width changes. Moving, scaling, rotating, or flipping the
169 complete logical group is allowed; zero-scale transforms and shear/skew are
170 forbidden, and the transformed frame must remain inside DrawingML's coordinate
171 range. Stroke width must remain inside DrawingML's line-width range. To freely
172 edit the contour, replace the whole fragment with ordinary SVG rather than
173 modifying a generated direct path.
174
175 For a canonical reusable template, the complete helper fragment may remain as
176 an executable exemplar. A final-page adaptation may copy it unchanged only
177 when all registry metadata, frame, adjustments, and paint remain unchanged;
178 otherwise regenerate the complete compact group.
179
180 ---
181
182 ## 5. Boundaries
183
184 | Concern | Behavior |
185 |---|---|
186 | Shape text | Keep visible SVG `<text>` outside the atomic fragment. It remains editable but may export as a grouped text box rather than the preset's own `p:txBody`. |
187 | Connector attachment | Authoring helper v1 creates an unconnected `p:cxnSp` and does not accept endpoint/site metadata. Do not hand-add it. The imported-shape contract may preserve an attachment that already exists in a source PPTX; creating a new attached connector is currently unsupported. |
188 | Action button behavior | `actionButton*` presets map visual geometry only. No action, navigation target, or hyperlink is created automatically. |
189 | Gradient/pattern paint | Authoring helper v1 accepts solid HEX paint only. Use ordinary SVG when a complex paint treatment is essential. |
190 | Multi-path darken/lighten | Direct visible layers use the shared normalized paint behavior from the PPTX importer. Their registry-derived HEX values are authorized derivatives of the selected base color and need no separate lock row. |
191 | Expanded compatibility | Existing helper-authored carrier/preview fragments remain readable as ordinary Slide-local input and receive a non-blocking migration warning; they do not become structured fixed atoms or object-slot carriers. Imported expanded fragments remain the lossless mirror/preserve form. |
192 | External edits | Any registry-path, style, or semantic mismatch fails quality check and export; regenerate the fragment. |
193
194 **Validation**: `svg_quality_checker.py` independently rerenders every compact
195 authored preset from registry metadata and compares its direct visible paths
196 and paint. The exporter performs the same validation, then expands the compact
197 group only in memory to reuse the lossless native-shape conversion path.
198 Compatible expanded authored input remains under its separate carrier/preview
199 freshness contract.
200
201 ---
202
203 ## 6. Shape Boolean Materialization
204
205 **Trigger**: Current page construction has two or more supported shape/text operands
206 whose faithful result calls for PowerPoint-style Union, Combine, Fragment,
207 Intersect, or Subtract. A §IX `Native shape suggestion` is a semantic candidate,
208 not a prerequisite or tool command; Executor may adopt, adapt, or decline it
209 from the actual content and explicit user/template constraints.
210
211 ```bash
212 python3 ${SKILL_DIR}/scripts/shape_boolean_svg.py render <svg-file> \
213 --operation subtract \
214 --source body \
215 --source cutout \
216 --id result
217 ```
218
219 | Concern | Contract |
220 |---|---|
221 | Sources | Closed `path`, `polygon`, `rect`, `circle`, `ellipse`, one validated compact authored shape preset, or supported horizontal implicit-LTR direct `<text>` with a resolvable exact OpenType weight/style (`--font-dir` adds search roots). Text becomes glyph geometry and is no longer editable text. Open geometry, groups, nested text, images, definitions, and nested SVG viewports fail closed. |
222 | Primary shape | The first `--source` supplies result paint. For `subtract`, all later operands are removed from that primary geometry. Explicit paint flags override only their named channels. |
223 | Coordinates | Ancestor and local transforms are baked into SVG-root coordinate space. Place stdout in the primary operand's z-order with no additional transform; never reinsert it under an original transformed ancestor. Root-coordinate space does not require each result path to be a direct `<svg>` child. |
224 | Placement | Ordinary Slide-local results belong in the applicable untransformed direct-root semantic `<g>` with its normal `id` / `data-pptx-bounds`. Master/Layout results remain direct-root path atoms and redeclare `data-pptx-layer`. One non-fragment result may be the direct `data-pptx-carrier="true"` child of an `object` slot. |
225 | Fragment roles | Fragment paths may share one ordinary Slide-local semantic group, but remain separate shapes and cannot collectively claim one carrier or one Master/Layout atom. Helper output inherits no structural role metadata from its operands; redeclare only the final layer/carrier/role contract. |
226 | Result | `union`, `combine`, `intersect`, and `subtract` emit one ordinary `<path>`. `fragment` emits stable sibling paths named `<id>-1`, `<id>-2`, ... in top/left/bottom/right/area order. |
227 | Winding | Results use explicit nonzero contour direction and never emit `fill-rule`, `clip-rule`, `clip-path`, `mask`, or Merge Shapes metadata. Operands that depend on even-odd fill, clipping, or masking fail closed. |
228 | Preservation | This helper authors new geometry only. Never use it to merge or split mirror/preserve source structure. |
229
230 Operation semantics match PowerPoint's visible Merge Shapes result: `union`
231 keeps every covered region, `combine` keeps the symmetric difference,
232 `intersect` keeps only common coverage, `subtract` removes every later source
233 from the primary, and `fragment` returns each atomic filled region. The PPTX
234 stores the materialized freeform geometry, not replayable operation history.
235
236 **Hard rule — stdout-only replacement**: The helper never writes the source
237 page. In one normal `apply_patch` edit, remove every selected operand and insert
238 every returned path in root coordinate space at the primary operand's z-order,
239 using the placement contract above. Fragment paths remain separate shapes; an
240 ordinary semantic group does not turn them into one structural atom.
241
242 ---
243
244 ## 7. Shape-Only Modelling Techniques
245
246 Applies to any page built from shapes, **with or without images** — a text-only,
247 data-only, or icon-only deck reaches these the same way. Each technique below is
248 plain geometry plus gradient paint, so all of it survives native export.
249
250 ### 7.1 Alternating light/dark gradient = dimensional form
251
252 The single highest-yield shape technique. A cylinder, metallic band, dimensional
253 numeral, or curved panel is produced by one gradient whose stops **alternate
254 light and dark** across the shape — light · dark · light for a three-stop ramp,
255 or light · dark · light · dark · light for a five-stop one. The alternation
256 imitates a curved surface catching light twice; a plain two-stop ramp always
257 reads flat no matter how strong the contrast.
258
259 Keep every stop on one hue and vary only lightness, hold one light direction for
260 the whole page, and remove strokes so adjacent facets meet cleanly. For a
261 cylinder, apply the alternating ramp across the body and cap it with an ellipse
262 carrying its own shallower ramp. The same light logic applies across separate
263 facets of any folded form.
264
265 ### 7.2 Reflection without a reflection effect
266
267 Native reflection is `Bake-required` ([`svg-effects.md`](./svg-effects.md) §6.12),
268 so build it from geometry instead:
269
270 1. Duplicate the object and flip it with `transform="translate(0, 2·y_bottom) scale(1, -1)"`.
271 2. Keep only the top **10–25 %** of the flipped copy — that is all a reflection
272 ever shows.
273 3. Lay a rectangle over it filled with a gradient running from fully transparent
274 at the object's base to the page background color at the cut line, so the
275 copy dissolves into the page.
276 4. Drop the whole reflection to roughly **60–70 %** opacity.
277
278 Seat rows of certificates, product shots, logo tiles, and cylinders this way. Do
279 not add a blur — it will not survive export, and a short gradient fade already
280 reads correctly at slide scale.
281
282 ### 7.3 Fragment as a modelling tool, not just a boolean
283
284 `fragment` (§6) is the fastest way to build layered diagrams from one silhouette:
285 lay evenly distributed bars across a triangle and fragment it into pyramid tiers;
286 cross a circle with two bars for a quadrant wheel; slice an annulus radially for
287 ring segments. Every piece inherits the parent contour, so the assembly stays
288 perfectly registered — impossible to achieve by drawing the tiers separately.
289
290 Distribute the cutting bars with a constant step before fragmenting; uneven tiers
291 read as a mistake rather than a hierarchy. Paint the resulting pieces with one
292 gradient family per §7.1 so the stack reads as a single solid.
293
294 ### 7.4 Soft edges without the soft-edge effect
295
296 Feathered edges are `Bake-required` ([`svg-effects.md`](./svg-effects.md) §6.12),
297 but the four jobs they normally do are all reachable with gradients:
298
299 | Intent | Build instead |
300 |---|---|
301 | Contact shadow under an object | Ellipse filled with a `radialGradient` from dark-transparent at the centre to fully transparent at the rim |
302 | Spotlight / stage pool | Cone or ellipse filled with a gradient fading to transparent at its far end, at low opacity over the scene |
303 | Object dissolving into the page | Overlay a rectangle whose gradient runs from transparent to the exact page background hex |
304 | Hiding an object while keeping it live | Full transparency, or a background-registered fill ([`image-layout-patterns.md`](./image-layout-patterns.md) `#M1-08`) |
305
306 A radial or linear alpha ramp reads the same as a feathered edge at slide scale
307 and, unlike a filter, exports intact. Never approximate a soft edge with a stack
308 of stroked outlines — the banding is visible on projection.
309
310 ### 7.5 Ground plane and staging
311
312 An object floating in empty canvas looks pasted on. Give it a surface: a wide
313 shallow ellipse or trapezoid beneath it, filled with a gradient that fades to the
314 background at its edges, optionally with a soft dark ellipse directly under the
315 object as contact shadow. A trapezoid narrowing away from the viewer reads as a
316 receding floor; a cylinder or slab reads as a pedestal.
317
318 Keep the plane low-contrast — it is staging, not content. This is what makes
319 certificate rows, product hero shots, and trophy/award pages look composed
320 rather than floating, and it costs two shapes.
321
321 lines MARKDOWN