feat(shapes): Shape Effects, 3-D, Arrowheads & Connectors — issue #18 epic#58
Merged
Merged
Conversation
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 (fullMSO_LINE_END_TYPEenum +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_SoftEdgesEffectmirroring the provena:outerShdwpattern; wired intoCT_EffectListin ECMA-376 schema order.softEdge/@radisRequiredAttributeper schema; glow always emits its mandatoryEG_ColorChoicechild.Shape.scene_3d / Shape.shape_3d—CT_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 uniquecNvPrid 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 beforegrpSpPr. 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 enclosingp:grpSpaffine outward (one recursion handles arbitrary nesting); identity fallback on degenerate chExt; existingleft/topsemantics unchanged. Group rotation/flip intentionally not folded (matches COMShape.Left).Issue-named aliases over shipped API (additive, no signature change)
LineFormat.head_end / .tail_end(.type/.width/.length)Connector.start_connection / .end_connectionTests
38 new unit tests in
tests/test_issue18_shape_effects.py+ 10 behave scenarios infeatures/iss-18-shape-effects.feature. Per-class save→reopen round-trip coverage included.Trinity (verbatim)
UAT
uat/uat_issue18_shape_effects.pyruns 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