Skip to content

feat(render): tile real sixel/kitty posters in the grid (image overlay)#95

Merged
detain merged 1 commit into
masterfrom
ai/sixel-tiling-overlay
Jun 27, 2026
Merged

feat(render): tile real sixel/kitty posters in the grid (image overlay)#95
detain merged 1 commit into
masterfrom
ai/sixel-tiling-overlay

Conversation

@detain

@detain detain commented Jun 27, 2026

Copy link
Copy Markdown
Owner

The last mile of tiling sixel posters — wires candy-core's ImageOverlay + sugar-gallery into the app.

What you get

phlix run --mode=sixel (or kitty/iterm2) now shows real image posters tiled in the rails, instead of being downgraded to half-block.

How

Pixel-graphics blobs can't be stitched into the text-cell frame, so they ride the overlay layer:

  • MosaicFactory::forPosterGrid keeps the graphics mosaic and returns an overlay flag (was: downgrade-to-half-block + notice).
  • PosterLoader (overlay mode) registers each rendered blob under a stable per-(url,size) id and resolves with a one-cell-marker block of the requested size instead of the blob; imageLayer() exposes the id → bytes map. This is central — all nine poster screens get tiling with zero changes (they still call withPoster() with the marker block).
  • App::view() returns a View carrying that image layer (a plain string when empty / inline mode), so the runtime resolves markers to screen positions and paints the blobs on top.

The blob never enters the text frame (verified: clean body has no DCS / no markers; two posters paint side-by-side at their grid cells). Idle frames don't re-emit (no flicker); a changed frame repaints images over the cells the diff cleared.

Tests

MosaicFactory overlay flag; PosterLoader overlay (marker block + registered blob + id reuse) + inline-empty-layer. Full suite green (2220); PHPStan L9 clean.

Note

Sixel painting is terminal-specific and can't be verified in CI (no sixel TTY) — needs live confirmation on your sixel terminal via phlix run --mode=sixel.

🤖 Generated with Claude Code

… overlay

`phlix run --mode=sixel` (or kitty/iterm2) now shows REAL image posters tiled in
the rails, instead of being downgraded to half-block. Pixel-graphics blobs can't
be stitched into the text-cell frame, so they ride candy-core's ImageOverlay:

 - MosaicFactory::forPosterGrid keeps the graphics mosaic and returns an
   `overlay` flag (was: downgrade-to-half-block + notice).
 - PosterLoader, in overlay mode, registers each rendered blob under a stable
   per-(url,size) id and resolves with a one-cell-marker BLOCK of the requested
   size instead of the blob. Inline (cell) modes are unchanged. imageLayer()
   exposes the id → bytes map. This is central, so all nine poster screens get
   it with zero changes — they still call withPoster() with the marker block.
 - App::view() returns a View carrying that image layer (a plain string when the
   layer is empty / inline mode), so the runtime resolves the markers to screen
   positions and paints the blobs on top of the text frame.

The blob never enters the text frame (verified: clean body has no DCS, no
markers; two posters paint side-by-side at their grid cells). Cache stays keyed
by protocol so each mode caches separately. Tests: MosaicFactory overlay flag,
PosterLoader overlay (marker block + registered blob + id reuse) + inline empty
layer. Suite green (2220); PHPStan L9 clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@detain detain merged commit 3fcca61 into master Jun 27, 2026
2 checks passed
@detain detain deleted the ai/sixel-tiling-overlay branch June 27, 2026 22:29
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.

1 participant