Skip to content

Merge main into stable#3764

Closed
superdoc-bot[bot] wants to merge 3 commits into
stablefrom
merge/main-into-stable-2026-06-23
Closed

Merge main into stable#3764
superdoc-bot[bot] wants to merge 3 commits into
stablefrom
merge/main-into-stable-2026-06-23

Conversation

@superdoc-bot

@superdoc-bot superdoc-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • creates merge/main-into-stable-2026-06-23 from stable
  • merges main into the candidate branch
  • opens the promotion PR to stable

Auto-created by promote-stable workflow.

luccas-harbour and others added 3 commits June 20, 2026 13:54
… 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
@github-actions

Copy link
Copy Markdown
Contributor

I wasn't able to run the live ecma-spec lookups β€” every call to the MCP tools came back blocked on permissions (and the question prompt was dismissed), so I verified the element/attribute names and unit conventions against ECMA-376 from knowledge rather than the schema graph. Flagging that up front in case you want to re-run with the tools enabled.

Here's the review of the OOXML handler changes (encode-image-node-helpers.js, textbox-content-helpers.js, vector-shape-helpers.js):

Status: PASS

Everything the handlers read maps to real ECMA-376 constructs, and the conversions are right:

  • extractOuterShadowEffect (vector-shape-helpers.js:348) reads a:effectLst β†’ a:outerShdw with blurRad, dist, dir, and a child color. All valid on CT_OuterShadowEffect. Units are handled correctly: blurRad/dist are EMU β†’ emuToPixels, and dir is a positive-fixed-angle in 60000ths of a degree β†’ rotToDegrees. Color/alpha β†’ color/opacity is fine. See https://ooxml.dev/spec?q=outerShdw

  • Shape group transform (encode-image-node-helpers.js) reads wpg:wgp/wpg:grpSpPr/wpg:grpSp and a:xfrm with rot/flipH/flipV plus off/ext/chOff/chExt β€” all legitimate on CT_GroupTransform2D, and rot correctly goes through rotToDegrees. Children via wps:wsp, pic:pic, a:prstGeom@prst, a:blip@r:embed are all valid. See https://ooxml.dev/spec?q=xfrm

  • Picture presentation reads a:stretch/a:fillRect/a:srcRect (l/t/r/b) and explicitly handles negative srcRect values β€” srcRect is ST_Percentage, which can legitimately be negative, so this is spec-aware rather than a violation. The prst="ellipse" β†’ mask is a rendering choice, not a spec claim. See https://ooxml.dev/spec?q=srcRect

  • extractTextBoxParagraphSpacing (textbox-content-helpers.js) reads spcFirstLastPara off wps:bodyPr (CT_TextBodyProperties) and treats an omitted attribute as false, suppressing first/last edge spacing unless explicitly enabled. That default matches the spec, and the w:spacing w:before/w:after twips β†’ px conversion is correct. See https://ooxml.dev/spec?q=bodyPr

  • w:br is treated as an intra-paragraph line break and distinguished from the paragraph boundary (isParagraphBoundary only on the synthetic break between logical paragraphs) β€” correct WML semantics.

No non-existent attributes, no missing required attributes, no wrong defaults, no spec violations in the parsing paths. If you want, re-enable the ecma-spec tool permissions and I'll re-confirm spcFirstLastPara's default and CT_OuterShadowEffect's attribute list against the actual schema.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

βœ… All modified and coverable lines are covered by tests.

πŸ“’ Thoughts on this report? Let us know!

@caio-pizzol caio-pizzol deleted the merge/main-into-stable-2026-06-23 branch June 23, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants