Skip to content

Implement leaf-box title centering and fix canvas margin issues#15

Merged
Malcolmnixon merged 3 commits into
mainfrom
feature/leaf-title-centering-and-canvas-margin
Jul 10, 2026
Merged

Implement leaf-box title centering and fix canvas margin issues#15
Malcolmnixon merged 3 commits into
mainfrom
feature/leaf-title-centering-and-canvas-margin

Conversation

@Malcolmnixon

Copy link
Copy Markdown
Member

This pull request addresses inconsistencies in box title positioning between renderers by centralizing the title placement logic into a single shared method. It introduces the BoxMetrics.TitleCursorTop helper and updates both the SVG and Skia renderers to use it, ensuring that leaf boxes have their titles vertically centered, while non-leaf boxes keep their titles top-pinned. The changes also clarify the roadmap for future unification of text rendering and fix a bug where box edges could sit flush against the viewport boundary due to incorrect axis handling. Several test cases are updated to reflect the new, consistent behavior.

Renderer and Layout Consistency Improvements:

  • Added BoxMetrics.TitleCursorTop, a shared method to compute the Y coordinate for a box's title block, ensuring both Skia and SVG renderers use the same logic for title placement. Leaf boxes now have centered titles, unless they have side ports, while containers keep the header top-pinned.
  • Updated SkiaRasterRenderer.RenderBoxTitle and SvgRenderer.RenderBoxTitle to use BoxMetrics.TitleCursorTop, eliminating previously duplicated and diverging code. [1] [2]

Bug Fixes:

  • Fixed a bug in MergeRegionDecomposer.LevelFootprint where box edges could sit flush against the rendered viewport boundary by using RealWidth/RealHeight instead of possibly axis-swapped Width/Height.

Testing and Documentation:

  • Updated tests in SkiaPortAndContentInsetTests and SvgRendererTests to account for the new title placement logic, ensuring that titles are centered for leaf boxes and correctly offset for folder tabs. [1] [2]
  • Expanded the ROADMAP.md with a section describing the plan to unify all text rendering onto a single LayoutLabel/LayoutText primitive, and documented the resolved leaf-box title centering and canvas margin issues.

Malcolm Nixon and others added 3 commits July 9, 2026 17:32
…ering items

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- BoxMetrics.TitleCursorTop: shared formula used by SvgRenderer and
  SkiaRasterRenderer. Leaf boxes (no children, no compartments) now
  center their title block vertically instead of pinning it to the
  top. Centering is skipped when the box has a left/right-side port
  (ContentInsetLeft/Right > 0), since such a port's inward-rendered
  label runs through the box's mid-height band and would otherwise
  collide with a centered title (e.g. ports-showcase-horizontal's
  Hub box).
- MergeRegionDecomposer.LevelFootprint: fixed a canvas-margin bug
  where the hierarchical/merge-region path's cross-axis extent read
  the axis-swapped Width/Height (swapped for Down/Up flow by
  AxisTransform.NormalizeInputAxes) instead of the never-swapped
  RealWidth/RealHeight, undercounting the far-edge padding so boxes
  could render flush against the canvas boundary.
- Updated SvgRendererTests and SkiaPortAndContentInsetTests for the
  new centering behavior.
- Regenerated gallery SVG/PNG assets.
- Updated ROADMAP.md: marked the leaf-title-centering and
  canvas-margin items resolved.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 10, 2026 01:38
@Malcolmnixon
Malcolmnixon merged commit 2e0fa1a into main Jul 10, 2026
6 checks passed
@Malcolmnixon
Malcolmnixon deleted the feature/leaf-title-centering-and-canvas-margin branch July 10, 2026 01:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves cross-renderer consistency by centralizing box-title vertical placement logic in a shared metrics helper and applies a related layout-footprint fix to prevent content from rendering flush against viewport boundaries (notably for Down/Up directions).

Changes:

  • Added BoxMetrics.TitleCursorTop(LayoutBox, Theme) to unify title-block Y placement (leaf boxes centered; containers top-pinned; side-port cases skip centering).
  • Updated both SvgRenderer and SkiaRasterRenderer to use the shared title-cursor helper instead of renderer-specific logic.
  • Fixed MergeRegionDecomposer.LevelFootprint cross-axis sizing for Down/Up flows by using RealWidth/RealHeight, and updated tests + gallery SVGs to reflect the new positioning.

Reviewed changes

Copilot reviewed 7 out of 37 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/DemaConsulting.Rendering.Svg.Tests/SvgRendererTests.cs Updates folder-tab/title placement assertion to match the new shared title-cursor logic.
test/DemaConsulting.Rendering.Skia.Tests/SkiaPortAndContentInsetTests.cs Adjusts a PNG renderer test to keep title top-pinned (non-leaf) so the horizontal-centering invariant remains isolated.
src/DemaConsulting.Rendering.Svg/SvgRenderer.cs Switches title placement to BoxMetrics.TitleCursorTop for consistent SVG title Y positioning.
src/DemaConsulting.Rendering.Skia/SkiaRasterRenderer.cs Switches title placement to BoxMetrics.TitleCursorTop for consistent Skia title Y positioning.
src/DemaConsulting.Rendering.Layout/Engine/Layered/MergeRegionDecomposer.cs Fixes Down/Up footprint computation by using RealWidth/RealHeight on axis-swapped nodes.
src/DemaConsulting.Rendering.Abstractions/BoxMetrics.cs Introduces shared TitleCursorTop helper implementing the unified title placement rules.
ROADMAP.md Documents the text-rendering unification direction and marks the title-centering and canvas-margin issues as resolved.
docs/gallery/shape-gallery.svg Updates expected rendered output for title placement changes.
docs/gallery/ports-showcase-vertical.svg Updates expected rendered output for title placement changes.
docs/gallery/ports-showcase-horizontal.svg Updates expected rendered output for title placement changes.
docs/gallery/parallel-edges-preserved.svg Updates expected rendered output for title placement changes.
docs/gallery/parallel-edges-preserved-vertical.svg Updates expected rendered output for title placement changes.
docs/gallery/parallel-edges-merged.svg Updates expected rendered output for title placement changes.
docs/gallery/orthogonal-obstacle.svg Updates expected rendered output for title placement changes.
docs/gallery/mixed-direction-nested.svg Updates expected rendered output for title placement changes.
docs/gallery/layered-pipeline.svg Updates expected rendered output for title placement changes.
docs/gallery/hierarchical-nested.svg Updates expected rendered output for title placement changes.
docs/gallery/folder-top-face-anchor.svg Updates expected rendered output for title placement changes.
docs/gallery/direction-right.svg Updates expected rendered output for title placement changes.
docs/gallery/direction-down.svg Updates expected rendered output for title placement changes.
docs/gallery/containment-packed.svg Updates expected rendered output for title placement changes.
docs/gallery/boundary-ports-showcase-vertical.svg Updates expected output (including viewBox width) to reflect the corrected footprint/margins.
docs/gallery/boundary-ports-showcase-horizontal.svg Updates expected rendered output for title placement changes.
docs/gallery/boundary-ports-showcase-deep-chain.svg Updates expected rendered output for title placement changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +61 to +66
/// <summary>
/// Computes the Y coordinate at which a box's title block (keyword line, if any, then the bold
/// name line) should begin, i.e. the position immediately before the leading
/// <see cref="Theme.LabelPadding"/> gap that precedes the first line. Both renderers must call
/// this so title placement never silently diverges between them.
/// </summary>
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.

2 participants