Commit Graph
5 Commits
Author SHA1 Message Date
Nic BoetandClaude Opus 5.5 4daa163e70 fix: clamp pixel zone coordinates to the monitor before rasterising
Zone::Load uses integer (pixel) zone coordinates as they are, while
percentage coordinates are scaled and clamped to the monitor
(e1eb7876c). Zone::Setup then fills the polygon into a monitor-sized
image, and Image::Fill(Polygon) does not check bounds, so a pixel zone
larger than the monitor wrote past the end of that image on every zmc
start. AddressSanitizer: heap-buffer-overflow WRITE in Image::Fill
(zm_image.cpp) from Zone::Setup, Zone::Load, Monitor::connect, for a
zone of 0,0 1279,0 1279,719 0,719 on a 640x360 monitor.

Pixel zones remain where a zone was saved with integer coordinates,
through the API or before the upgrade to percentages, and the monitor
is then made smaller. Negative coordinates wrote before the buffer.

Clamp each vertex to [0, width-1] x [0, height-1] in Zone::Load, as
ParsePercentagePolygon does, and log a warning naming the zone.
Image::Outline already clamps its vertices the same way, so the filled
area and the drawn outline now agree.

fixes #5213

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:20:31 -05:00
Isaac Connor e1eb7876c6 fix: clamp percentage polygon to width-1/height-1
ParsePercentagePolygon clamped to [0, width] / [0, height], so a new
zone created at 100% produced pixel coords equal to the monitor
dimensions. The rasterizer requires hi_x < width and hi_y < height,
so the runtime then logged warnings like
  "polygon hi_x (1920) >= image width (1920), clamping".

Clamp to width-1 / height-1 instead. Updates existing tests that
encoded the previous behavior.
2026-05-13 11:38:42 -04:00
Isaac ConnorandClaude Opus 4.6 7d78b722d0 fix: auto-detect zone coordinate format instead of trusting Units field
The zone loader now ignores the Units DB field and detects the coordinate
format by checking for decimal points: decimal values are percentages,
integer-only values are legacy pixels. This fixes motion detection being
broken when zones had Units=Pixels but percentage coordinates (or vice
versa), which resulted in a ~99x99 pixel zone on a 2560x1440 monitor.

The PHP zone view now always forces Units=Percent when saving, since it
always works in percentage space. convertPixelPointsToPercent() now
returns bool to indicate whether conversion occurred.

Tests added for: truncation bug via atoi, correct percentage-to-pixel
conversion, auto-detect heuristic, and resolution independence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:26:36 -04:00
Isaac ConnorandClaude Opus 4.6 c0016fa00b feat: store zone coordinates as percentages for resolution independence
Convert zone coordinates from absolute pixel values to percentages
(0.00-100.00) so zones automatically adapt when monitor resolution
changes. This eliminates the need to manually reconfigure zones after
resolution adjustments.

Changes:
- Add DB migration (zm_update-1.37.81.sql) to convert existing pixel
  coords to percentages, recalculate area, and update Units default
- Add Zone::ParsePercentagePolygon() in C++ to parse percentage coords
  and convert to pixels at runtime using monitor dimensions
- Backwards compat: C++ Zone::Load() checks Units column and uses old
  pixel parser for legacy 'Pixels' zones
- Update PHP coordsToPoints/mapCoords/getPolyArea for float coords,
  replace scanline area algorithm with shoelace formula
- Update JS zone editor to work in percentage coordinate space with
  SVG viewBox "0 0 100 100" and non-scaling-stroke for consistent
  line thickness
- Position zone SVG overlay inside imageFeed container via JS to align
  with image only (not status bar)
- Support array of zone IDs in Monitor::getStreamHTML zones option
- Update monitor resize handler: percentage coords don't need rescaling,
  only threshold pixel counts are adjusted
- Add 8 Catch2 unit tests for ParsePercentagePolygon

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:19:20 -05:00
Isaac ConnorandClaude Opus 4.6 47edcca6ab fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
When zones have Units='Percent' in the database but their Coords contain
pixel values (>100), ParsePercentagePolygon treats them as percentages,
causing wild scaling (e.g., 639% * 1920 / 100 = 12269) followed by
clamping to monitor bounds, producing degenerate full-frame zones.

Add a pre-check in Zone::Load that scans coordinate values before calling
ParsePercentagePolygon. If any value exceeds 100, log a warning and use
ParsePolygonString (pixel path) instead. Also add unit tests for both
ParsePolygonString and ParsePercentagePolygon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:16:55 -05:00