Skip to content

feat(shapes): Shape Effects, 3-D, Arrowheads & Connectors — issue #18 epic#58

Merged
MHoroszowski merged 1 commit into
masterfrom
feature/issue18-shape-effects
May 18, 2026
Merged

feat(shapes): Shape Effects, 3-D, Arrowheads & Connectors — issue #18 epic#58
MHoroszowski merged 1 commit into
masterfrom
feature/issue18-shape-effects

Conversation

@MHoroszowski
Copy link
Copy Markdown
Owner

Resolves the genuinely-missing surface of the issue #18 epic and adds issue-named convenience API over the sub-features this fork already shipped. One branch; nine sub-features. Maintainer UAT signed off.

Investigation finding

Issue #18 is written against upstream scanny/python-pptx, which is behind this fork. Arrowhead ends (full MSO_LINE_END_TYPE enum + LineFormat.begin/end_arrowhead_* + oxml + 42 tests) and the experimental connector connect API were already shipped here — for those, scope was verify-no-regression plus thin issue-named aliases, not a rebuild.

New (genuinely missing)

  • ShadowFormat.glow_effect / .reflection_effect / .soft_edge_effectCT_GlowEffect / CT_ReflectionEffect / CT_SoftEdgesEffect mirroring the proven a:outerShdw pattern; wired into CT_EffectList in ECMA-376 schema order. softEdge/@rad is RequiredAttribute per schema; glow always emits its mandatory EG_ColorChoice child.
  • Shape.scene_3d / Shape.shape_3dCT_Scene3D/Camera/LightRig/Shape3D. scene3d default emits both the schema-required camera and lightRig (camera-only → PowerPoint repair). Wired into spPr after effectLst, before extLst.
  • Shape.flip_horizontal / Shape.flip_vertical — delegate to the existing oxml flipH/flipV.
  • Shape.duplicate(insert_at_z=None) — deep-copy with sequential unique cNvPr id reassignment (max_shape_id+1+i, so a duplicated group's children don't collide → no repair) and unique name; z-clamped so the clone never lands before grpSpPr. Pure-XML copy; relationship-backed shapes share the part (documented limitation).
  • Shape.slide_left/_top/_width/_height — additive, read-only world-space coordinates composing every enclosing p:grpSp affine outward (one recursion handles arbitrary nesting); identity fallback on degenerate chExt; existing left/top semantics unchanged. Group rotation/flip intentionally not folded (matches COM Shape.Left).

Issue-named aliases over shipped API (additive, no signature change)

  • LineFormat.head_end / .tail_end (.type/.width/.length)
  • Connector.start_connection / .end_connection

Tests

38 new unit tests in tests/test_issue18_shape_effects.py + 10 behave scenarios in features/iss-18-shape-effects.feature. Per-class save→reopen round-trip coverage included.

Trinity (verbatim)

python3 -m pytest tests/ -q            -> 3925 passed (3887 + 38), 0 failed
ruff check src tests                   -> All checks passed!
python3 -m behave features/ --no-color -> 1119 scenarios, 0 failed (1109 + 10)

UAT

uat/uat_issue18_shape_effects.py runs clean, 16/16 round-trip checks, exit 0. Interceptor screenshots of slides 1/2/4 in real PowerPoint show glow/reflection/soft-edge, a 3-D extruded box, and a flipped+duplicated arrow rendering with no repair dialog. Maintainer visual sign-off received.

Closes #18

…epic

Resolves the genuinely-missing surface of the issue #18 epic and adds
issue-named convenience API over the sub-features this fork already
shipped. One branch; nine sub-features.

Investigation finding (recorded so the delta is auditable): issue #18 is
written against upstream scanny/python-pptx, which is behind this fork.
Arrowhead ends (full MSO_LINE_END_TYPE enum + LineFormat.begin/end_
arrowhead_* + oxml + 42 tests) and the experimental connector connect
API were ALREADY shipped here; for those, scope was verify-no-regression
plus thin issue-named aliases, not a rebuild.

New (genuinely missing):
- ShadowFormat.glow_effect / .reflection_effect / .soft_edge_effect —
  CT_GlowEffect / CT_ReflectionEffect / CT_SoftEdgesEffect mirroring the
  proven a:outerShdw pattern; wired into CT_EffectList in ECMA-376
  schema order (blur,fillOverlay,glow,innerShdw,outerShdw,prstShdw,
  reflection,softEdge). softEdge/@RaD is RequiredAttribute per schema;
  glow always emits its mandatory EG_ColorChoice child.
- Shape.scene_3d / Shape.shape_3d — CT_Scene3D / CT_Camera / CT_LightRig
  / CT_Shape3D. scene3d default emits BOTH the schema-required camera
  AND lightRig (camera-only → PowerPoint repair). Wired into spPr after
  effectLst, before extLst.
- Shape.flip_horizontal / Shape.flip_vertical — delegate to the existing
  oxml flipH/flipV (creates a:xfrm in schema-safe order).
- Shape.duplicate(insert_at_z=None) — deep-copy with sequential unique
  cNvPr id reassignment (max_shape_id+1+i, so a duplicated *group*'s
  children don't collide → no repair) and unique name; z-clamped so the
  clone never lands before grpSpPr. Pure-XML copy; relationship-backed
  shapes share the part (documented limitation).
- Shape.slide_left/_top/_width/_height — additive, read-only world-space
  coordinates composing every enclosing p:grpSp affine outward (one
  recursion handles arbitrary nesting); identity fallback on degenerate
  chExt; never mutates stored xfrm; existing left/top semantics
  unchanged. Group rotation/flip intentionally not folded (matches COM
  Shape.Left).

Issue-named aliases over shipped API (additive, no signature change):
- LineFormat.head_end / .tail_end (.type/.width/.length)
- Connector.start_connection / .end_connection

Tests: 38 new unit tests in tests/test_issue18_shape_effects.py
(glow 4, reflection 4, soft-edge 4, 3-D 4, head/tail 3, start/end 2,
group-coords 5, flip 4, duplicate 8) + 10 behave scenarios in
features/iss-18-shape-effects.feature. Per-class save→reopen round-trip
coverage included.

Trinity (verbatim):
  python3 -m pytest tests/ -q            -> 3925 passed (3887 + 38)
  ruff check src tests                   -> All checks passed!
  python3 -m behave features/ --no-color -> 1119 scenarios, 0 failed
                                            (1109 + 10)

UAT: uat/uat_issue18_shape_effects.py runs clean, 16/16 round-trip
checks, exit 0. Interceptor screenshots of slides 1/2/4 in real
PowerPoint show glow/reflection/soft-edge, a 3-D extruded box, and a
flipped+duplicated arrow rendering with NO repair dialog
(sheets_on_w1=0). Visual sign-off is the maintainer's call per §6a —
not claimed here.

Closes #18
@MHoroszowski MHoroszowski merged commit 72830b1 into master May 18, 2026
16 checks passed
@MHoroszowski MHoroszowski deleted the feature/issue18-shape-effects branch May 18, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Epic] Shape Effects, Arrowheads & Connectors — glow, reflection, soft-edge, 3D

1 participant