# TrapMap Managed PNG Export Design ## Goal Replace `System.Drawing.Common` in TrapMap image export so Clumsy can save the full grid PNG without depending on platform-specific drawing assemblies. ## Chosen approach Use a small internal RGBA rasterizer for grid primitives and `StbImageWriteSharp` 1.16.7 for PNG encoding. Keep the public request/result API and the existing TrapMap call site unchanged. Alternatives rejected: - Copying `System.Drawing.Common.dll` beside the build output is unreliable because Clumsy performs its own dependency attachment and can load the incompatible `netstandard2.0` facade first. - `SkiaSharp` adds native Windows assets and more deployment points. - `ImageSharp` has a larger dependency/licensing surface and its current release does not target this project's `netstandard2.0` runtime. `StbImageWriteSharp` is selected because its package contains one managed `netstandard2.0` implementation and declares no dependencies. It has no native assets or alternate platform facades for Clumsy to select incorrectly. ## Rasterization - Allocate an in-memory 32-bit RGBA pixel buffer after the existing 4000-pixel edge validation. - Preserve the current canvas dimensions, 4 pixels per cell, colors, Y inversion, vehicle/workstation geometry, header height, and 50 MiB final-file limit. - Draw filled rectangles, 1/2-pixel lines, circles, crosses, and vehicle polygons with deterministic integer raster operations. - Render header and workstation text with a small embedded ASCII bitmap font. Non-ASCII metadata is sanitized to a printable fallback for the PNG header only; original messages remain unchanged in DLog/Console. - Keep header lines non-overlapping and include bounds, resolution, rows/columns, occupied count/rate, obstacle count, tire status/message, and input source. ## PNG encoding - Pass the RGBA pixel buffer to `StbImageWriteSharp.ImageWriter.WritePng`. - Insert a standard `pHYs` chunk immediately after `IHDR`, with X/Y both 11,811 pixels per metre and unit `1` (300 DPI). - Calculate the inserted chunk's CRC-32 and write its integers in big-endian order. - Validate the completed PNG before publication; encoding or metadata failures remain contained export failures. - Preserve the current collision-safe temporary-file reservation, actual encoded-size check, atomic move, and best-effort cleanup behavior. ## Project and deployment changes - Remove the `System.Drawing.Common` package reference and `DeployFrameworkDrawingRuntime` target from `ClumsyPilot.csproj`. - Add `StbImageWriteSharp` version 1.16.7. No other new package is allowed. - The final build output must not require or deploy `System.Drawing.Common.dll` for TrapMap; it may deploy the single managed `StbImageWriteSharp.dll`. - Existing Clumsy references are not modified. ## Verification - TDD first proves the current exporter/package still depends on `System.Drawing.Common`. - Reflection/source contracts assert the old package, build target, `using System.Drawing`, and drawing types are absent, and the exact Stb package is present. - Decode the generated PNG in the test with a test-only decoder or framework reader and verify dimensions, 300 DPI metadata, representative colors, Y inversion, header separation, unique concurrent filenames, and no temporary files. - Run source, build, grid, lifecycle, and image tests; require zero build errors and no new warnings. ## Non-goals - No changes to grid construction, obstacle/tire inputs, vehicle motion, Painter visualization, export switches, output directory, or file-size/pixel limits. - No screenshot capture and no new general-purpose graphics framework.