From 08290ece169c781388c154baa223eb750390e839 Mon Sep 17 00:00:00 2001 From: gramps Date: Mon, 5 Oct 2026 16:13:39 -0700 Subject: [PATCH] Compositor: prefill only uncovered rows when backdrop not fully covered (Unit 4) --- Services/Compositor/SceneCompositor.cs | 49 ++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/Services/Compositor/SceneCompositor.cs b/Services/Compositor/SceneCompositor.cs index 5261f6b..33a9e51 100644 --- a/Services/Compositor/SceneCompositor.cs +++ b/Services/Compositor/SceneCompositor.cs @@ -92,8 +92,53 @@ public sealed class SceneCompositor var covered = liveCaptureFrame != null && liveCaptureFrame.Width == cropW && liveCaptureFrame.Height == cropH; if (!covered) - for (var i = 3; i < buffer.Length; i += 4) - buffer[i] = 255; // opaque black base + { + if (liveCaptureFrame != null) + { + var (uScale, uOx, uOy) = StretchMath.UniformToFill(cropW, cropH, liveCaptureFrame.Width, liveCaptureFrame.Height); + var drawnW = liveCaptureFrame.Width * uScale; + var drawnH = liveCaptureFrame.Height * uScale; + var ox = (int)Math.Floor(uOx); + var oy = (int)Math.Floor(uOy); + var oh = (int)Math.Ceiling(oy + drawnH); + var ow = cropW; + if (oy > 0) + { + var topCount = oy * ow; + for (var i = 3; i < topCount * 4; i += 4) + buffer[i] = 255; + } + if (oh < cropH) + { + var start = oh * ow; + var bottomCount = (cropH - oh) * ow; + for (var i = start * 4 + 3; i < (start + bottomCount) * 4; i += 4) + buffer[i] = 255; + } + if (ox > 0 || (int)Math.Ceiling(uOx + drawnW) < cropW) + { + var x0s = (int)Math.Floor(uOx); + var x1s = (int)Math.Ceiling(uOx + drawnW); + for (var y = oy; y < oh && y < cropH; y++) + { + var di = (y * ow + 0) * 4; + for (var x = 0; x < x0s && x < ow; x++) + { + buffer[di + x * 4 + 3] = 255; + } + for (var x = x1s; x < ow; x++) + { + buffer[di + x * 4 + 3] = 255; + } + } + } + } + else + { + for (var i = 3; i < buffer.Length; i += 4) + buffer[i] = 255; // opaque black base + } + } if (liveCaptureFrame != null) BlitContent(buffer, cropW, cropH, 0, 0, cropW, cropH, liveCaptureFrame, 1f, false, false);