From 3fcb4edd505d3d7545ebb151b6fb1b5e00b047a7 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Sun, 19 Jul 2026 09:46:55 +0000 Subject: [PATCH 11/71] debug(macos): dump the texture atlas from the probe (rev 5) The renderTile dump shows tiles emitted at correct positions, but some render blank (the leading 'c', 'a') and some glyphs appear as 1-2px slivers with tiny normalized widths (e.g. bmp=2x7 norm width 0.002), suggesting a glyph-slicing / multi-tile-glyph handling problem in the compositor rather than positioning. Dump the atlas (readAtlas) to atlas.ppm plus a non-zero pixel count, to see what was actually uploaded and whether the sampled sub-rects contain glyph pixels. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01AeG2jwYMX5gdvvtUnx3PJa --- src/contour_macos/render_probe.cpp | 31 +++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/contour_macos/render_probe.cpp b/src/contour_macos/render_probe.cpp index a7a1db07..e8ab4cdf 100644 --- a/src/contour_macos/render_probe.cpp +++ b/src/contour_macos/render_probe.cpp @@ -59,7 +59,7 @@ void writePpm(std::string const& path, contour_macos::PixelBuffer const& buf) // produced it. __DATE__/__TIME__ update whenever THIS translation unit is recompiled, so the // printed line is a reliable "is the running binary built from the current source?" signal // without needing a full rebuild. -#define RENDER_PROBE_REVISION 4 +#define RENDER_PROBE_REVISION 5 int main(int argc, char** argv) { @@ -167,6 +167,35 @@ int main(int argc, char** argv) std::fflush(stdout); } + // Diagnostic: dump the texture atlas so we can see what got uploaded and where, and + // whether the normalized sub-rects the tiles sample actually contain glyph pixels. + if (auto shot = target.readAtlas(); shot.has_value()) + { + auto const aw = static_cast(unbox(shot->size.width)); + auto const ah = static_cast(unbox(shot->size.height)); + std::printf("atlas: %ux%u, %zu bytes, format=%d\n", + aw, + ah, + shot->buffer.size(), + static_cast(shot->format)); + // Count non-zero atlas pixels (red channel) to confirm glyphs were uploaded at all. + size_t nonzero = 0; + for (size_t i = 0; i < shot->buffer.size(); i += 4) + if (shot->buffer[i]) + ++nonzero; + std::printf("atlas non-zero (red) pixels: %zu / %u\n", nonzero, aw * ah); + std::ofstream af("atlas.ppm", std::ios::binary); + af << "P6\n" << aw << ' ' << ah << "\n255\n"; + for (size_t i = 0; i + 3 < shot->buffer.size(); i += 4) + { + char const rgb[3] = { static_cast(shot->buffer[i]), + static_cast(shot->buffer[i + 1]), + static_cast(shot->buffer[i + 2]) }; + af.write(rgb, 3); + } + std::fflush(stdout); + } + writePpm(outputPath, target.outputBuffer()); std::printf("render_probe: wrote %s (%ux%u)\n", outputPath.c_str(),