53 lines
3.6 KiB
Markdown
53 lines
3.6 KiB
Markdown
# 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.
|