Skip to content

Keep live atlas builder from packing over existing sprites - #72

Merged
treeform merged 1 commit into
treeform:masterfrom
RowDaBoat:fix-atlas-mark-region
Sep 24, 2026
Merged

treeform merged 1 commit into
treeform:masterfrom
RowDaBoat:fix-atlas-mark-region

Conversation

@RowDaBoat

@RowDaBoat RowDaBoat commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #70.

Problem

newAtlasBuilderFromAtlas fills its skyline by calling markRegion for every existing entry, in table order. markRegion used addToSkyline, which replaces the skyline over the rect's columns with y + height. When a shorter entry was marked after a taller one in the same columns, the skyline went down. The next addImage / sk.addAtlasImage then landed on top of an existing sprite, so every quad drawing that sprite showed the new image.

Fix

markRegion now only raises the skyline. Across [x, x + width), each node keeps max(node.y, y + height). Parts of nodes outside the region stay as they are, and neighbors with the same height are merged. So the order entries are marked in no longer matters.

The region is also clamped to [0, atlasSize). markOccupiedEntry pads by the margin, so a sprite on the right edge used to create a skyline node that went past the end of the atlas.

allocate still uses addToSkyline. That's correct there: findSkylinePosition places a new rect at or above every node it covers, so replacing those nodes can't lower the skyline.

Tests

Added to tests/test_atlas_png.nim (already run in CI):

  • Marking a shorter region over a taller one does not lower the skyline. This is the allocator repro from the issue.
  • Overlapping regions of different widths raise only the columns they cover.
  • A live builder made with newAtlasBuilderFromAtlas places a new image without overlapping any existing entry. This is the builder repro from the issue.

Without the fix, the new tests fail with (success: true, x: 0, y: 8, ...). With the fix, all tests pass. The issue's repro now outputs:

(success: true, x: 0, y: 32, width: 8, height: 8)
a:   (x: 1, y: 19, width: 60, height: 10)
b:   (x: 1, y: 31, width: 60, height: 10)
new: (x: 1, y: 43, width: 60, height: 10)

The other unit tests in CI (test_textboxes, test_inputs, test_layout, test_layout_regressions, test_layout_clips, test_cpu_backend) still pass on macOS.

🤖 Generated with Claude Code

markRegion replaced the skyline over the marked columns, so marking a
shorter entry after a taller one lowered it and new images were packed
on top of existing sprites. It now only raises the skyline and clamps
the region to the atlas width.

Fixes treeform#70.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@treeform
treeform merged commit b7f59fb into treeform:master Sep 24, 2026
8 checks passed
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.

Live atlas builder packs new images over existing sprites

2 participants