Merge main into stable#3765
Conversation
… shape-clipped image rendering (SD-2999 and SD-3033) ## Summary Major improvements to vector shape rendering fidelity, covering outer shadow effects, shape-group transform composition, pictures clipped to preset shape geometry, and the anchoring/layout corrections needed to position this artwork where Word puts it. ### Outer shadow effects on vector shapes - New `ShapeEffects` / `ShapeOuterShadowEffect` contract types, with shared paint-extent math in `contracts/src/shape-effects.ts` (`resolveOuterShadowOffset`, `getOuterShadowStdDeviation`, `getOuterShadowPaintExtent`) so the painter and measurer agree on how much room a shadow needs. - DomPainter renders shadows with SVG filters (`feDropShadow` for filled shapes; a blur/offset/flood/composite chain that clones the path for no-fill outline-only shadows). - Effect extents grow to fit the shadow paint area, and the resolved-layout version signature now includes the vector effect extent so shadow changes invalidate correctly. ### Shape-group transforms - `ShapeGroupTransform` gains `rotation` / `flipH` / `flipV`; group transforms are applied as container transforms so nested groups compose correctly (child-local orientation, nested affine orientation, rotation around the visible group box). - The DOM measurer measures transformed group bounds, preserves effect extents, and avoids double-applying measured rotation. - Grouped picture children get correct clipping and edge-stroke paint room. ### Pictures clipped to preset shape geometry - Images masked by a preset shape (`prstGeom` on `pic:spPr`) now carry a `shapeClipPath` plus an `objectFit` through the converter → layout adapter → painter pipeline, for inline, anchored, and grouped images alike. - Stretched fills are mapped to the right fit: `cover` for shape-masked stretches, `fill` for srcRect-clipped stretches, with negative `srcRect` values (which Word treats as canvas growth, not crop) handled explicitly. - Layout-bridge now dirties inline image masks and rendered drawing changes so mask edits repaint. ### Anchoring and layout corrections - Paragraphs holding page-relative anchors (explicit or fallback) now participate in wrap; pre-registered anchors resolve against the active section, and stale pre-registered wraps are dropped. - Anchored objects on section-marker paragraphs (`sectPr`-only empty paragraphs) are preserved: the marker paragraph is visually suppressed while its anchors register at the marker origin, with Word-compatible offsets for marker image groups. - Header/footer: anchored `wrapNone` media render as page-level absolute overlays, non-page-relative overlays position from the container origin, ordinary `wrapNone` media are measured, and anchored media are excluded from decoration normalization. - Page-background (behind-doc) decorations stack by authored OOXML z-index instead of document order. ### Text in shapes - Textbox paragraph spacing (`before`/`after`) is carried per logical paragraph in `ShapeTextContent.paragraphs` and rendered in vector shape text, with a new `isParagraphBoundary` flag distinguishing paragraph breaks from intra-paragraph `<w:br>`. ### Preset geometry - Arrow shapes regenerated with Word-compatible geometry; `roundRect` paths generated in target coordinate space. - Stroke width preserved on large-coordinate-scale shapes via `vector-effect: non-scaling-stroke`. ## Testing - New regression suite `painters/dom/src/renderer-shape-regressions.test.ts` (~1,000 lines) plus expanded unit coverage across contracts, layout-engine, layout-bridge, layout-resolved, measuring, layout-adapter, converter helpers, and header/footer session management. Co-authored-by: Luccas Correa <luccas@harbourshare.com> Co-authored-by: Gabriel Chittolina <163901514+chittolinag@users.noreply.github.com> Co-authored-by: Caio Pizzol <97641911+caio-pizzol@users.noreply.github.com> Co-authored-by: Caio Pizzol <caio@harbourshare.com> Co-authored-by: Nick Bernal <117235294+harbournick@users.noreply.github.com> Co-authored-by: Nick Bernal <nick@superdoc.dev> Source-PR: #3713 Closes #3713 Note: this ports only the public subtree changes from a mixed source commit (49 public paths, 1 non-public path ignored). Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 28ce25fc52a5d4989391b4b7d6506c222239fe6b Ported-Public-Prefix: superdoc/public
test: coverage for built-in find Note: this ports only the public subtree changes from a mixed source commit (2 public paths, 5 non-public paths ignored). Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 23014752ee7a47401af1e0516086ef7aa24da91b Ported-Public-Prefix: superdoc/public
|
The ecma-spec MCP tools are installed but every call is being denied by the permission layer, so I couldn't run live schema lookups. I reviewed the changed handlers against ECMA-376 from knowledge instead — flagging that caveat up front. Here's what I checked across the actual changed files ( Status: PASS Every OOXML element and attribute these handlers read is real and used correctly.
No non-existent attributes, no missing-required-attribute writes (these are read paths with sensible fallbacks), and no incorrect defaults. Clean from a spec standpoint. One non-blocking note: if you want me to re-run this against the live ECMA-376 schema graph for a definitive check, you'll need to approve the |
|
🎉 This PR is included in superdoc-cli v0.20.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-sdk v1.19.0 |
|
🎉 This PR is included in @superdoc-dev/mcp v0.15.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.43.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.14.0 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.15.0 |
Summary
merge/main-into-stable-2026-06-23stableAuto-created by promote-stable workflow.