revert(heal): cut the mask's own fade again, not a step over the whole brush

This reverts 8809eb8. The step cut takes the whole brush out of the frame, so
the fill below has only the rim left to read from.

The colour leak that cut was for no longer needs it: 49c5c9c handed the mask
the whole spot, and heal-colour-pass.mjs measures the repair 1.08 levels off
the ground with the fade cut — the same 1.08 it measures with the step.
This commit is contained in:
2026-10-16 06:13:35 +07:00
parent 1633287a46
commit f670de1377
2 changed files with 4 additions and 51 deletions
-36
View File
@@ -448,40 +448,4 @@ assert.ok(worstBand <= 8, `a painted pixel at x=${bandAt} is ${worstBand} levels
H = keptH;
}
// 10. The brush put ON the blemish, which is what it is for. Every case above
// paints its stroke well inside the brush, so the rim the fill reads is
// ground however the hole was cut — and a fill that takes its colour from
// the brush's OWN pixels is invisible there. Here the whole of what the
// brush covers is the blemish, a disc just smaller than the brush, and the
// repair has to come back the colour of the ground around it. This is the
// shape the cut's softness leaks in: with the cut written as the mask's fade
// — `a = 1 - mask.a` — the outer quarter of the spot stays in the frame at
// partial weight, the blemish's rim is exactly in that band, and it is
// weighed into the blur the fill is made of. The repair then lands in the
// colour of the thing it was repairing, 4 levels off a grey ground on a
// 226,34,40 blemish (measured; the cut variants in heal-colour-pass.mjs).
{
const BLEMISH_R = 0.045 * W; // 7.2px under this 8px brush
const shadeBlemish = (x, y) =>
Math.hypot(x - cx, y - cy) < BLEMISH_R ? [226, 34, 40] : [GREY, GREY, GREY];
const onBlemish = healPass(bytesOf(shadeBlemish), [{ x: cx / W, y: cy / H, r: R }]);
let worstOn = 0;
let onCount = 0;
for (let y = 0; y < H; y++) {
for (let x = 0; x < W; x++) {
if (onBlemish.mask[(y * W + x) * 4 + 3] < 250) continue;
if (Math.hypot(x + 0.5 - cx, y + 0.5 - cy) > 0.5 * R * W * 0.75) continue;
onCount++;
for (let c = 0; c < 3; c++) {
worstOn = Math.max(worstOn, Math.abs(onBlemish.pixels[(y * W + x) * 4 + c] - GREY));
}
}
}
assert.ok(onCount > 20, 'the brush painted too little to judge');
assert.ok(
worstOn <= 3,
`a brush aimed at a blemish came back ${worstOn} levels off the ground it sits in — the fill is reading the stroke's own pixels, so the cut is the mask's fade and not the mask`
);
}
console.log('ok the stroke is one mask, the fill carries the light, and nothing outside it moved');