// Package diffs compares two renderings of the same screen.
//
// The comparison is deliberately coarse. squint renders both sides in one
// run on one machine, so there is no font-hinting or architecture noise to
// tolerate -- but a language model is the fine judge downstream, so this
// only has to answer "did anything move", generously, and mark where.
// Being generous here is what keeps a reviewer's attention on the three
// screens that changed instead of the forty that did not.
package diffs
import (
"fmt"
"image"
"image/color"
"image/draw"
)
// Tolerance is how far one colour channel may move before a pixel counts.
// Both sides come from the same browser in the same run, so this is not
// for anti-aliasing; it is so a single rounding step in a gradient does
// not start a conversation.
const Tolerance = 16
// Threshold is the fraction of pixels that must differ before a shot is
// worth a look. Generous on purpose: the model downstream decides whether
// a real change matters, and a tight number here would hand it noise.
const Threshold = 0.001
// Result is what comparing two renderings found.
//
// Measuring happens in image pixels, because that is what an image has.
// Everything a reader is shown is quoted in CSS pixels -- the same units as
// the viewport in the config and the size beside the name in the report.
// Two different numbers for the same page is how a report starts lying.
type Result struct {
// Total and Changed count CSS pixels; Fraction is Changed over Total
// and is the same either way.
Total int `json:"total_pixels"`
Changed int `json:"changed_pixels"`
Fraction float64 `json:"fraction"`