using System.Buffers.Binary; using System.IO.Compression; using XFESystem.Desktop; using Xunit; namespace XFESystem.Core.Tests; public sealed class CursorRasterTests { private const uint Accent = 0x3B77D9; private sealed class BitmapCanvas(int width, int height, int scale, uint background) : IDesktopCoverageCanvas { public int Width => width; public int Height => height; public int NativeWidth => width * scale; public int NativeHeight => height * scale; public int ScalePercent => scale * 100; public readonly uint[] Pixels = Enumerable.Repeat(background, width * height * scale * scale).ToArray(); public readonly List<(uint Rgb, int X, int Y, int Width, int Height, byte[] Alpha)> Calls = []; public void Fill(uint rgb, int x, int y, int w, int h) { for (int row = Math.Max(0, y * scale); row < Math.Min(NativeHeight, (y + h) * scale); row++) for (int col = Math.Max(0, x * scale); col < Math.Min(NativeWidth, (x + w) * scale); col++) Pixels[row * NativeWidth + col] = rgb; } public void Line(uint rgb, int x1, int y1, int x2, int y2) { } public void Text(string text, uint rgb, int x, int y) { } public void Present() { } public void BlendCoverage(uint rgb, int nativeX, int nativeY, int w, int h, ReadOnlySpan coverage) { Assert.Equal(w * h, coverage.Length); Calls.Add((rgb, nativeX, nativeY, w, h, coverage.ToArray())); for (int row = Math.Max(0, nativeY); row < Math.Min(NativeHeight, nativeY + h); row++) for (int col = Math.Max(0, nativeX); col < Math.Min(NativeWidth, nativeX + w); col++) { byte alpha = coverage[(row - nativeY) * w + col - nativeX]; if (alpha != 0) Pixels[row * NativeWidth + col] = Mix(Pixels[row * NativeWidth + col], rgb, alpha); } } } private static uint Mix(uint background, uint accent, byte alpha) { uint result = 0; for (int shift = 0; shift <= 16; shift += 8) result |= ((((accent >> shift) & 255) * alpha + ((background >> shift) & 255) * (255u - alpha) + 127) / 255) << shift; return result; } [Theory] [InlineData(DesktopPointerShape.Arrow, 1)] [InlineData(DesktopPointerShape.Arrow, 2)] [InlineData(DesktopPointerShape.Text, 1)] [InlineData(DesktopPointerShape.Text, 2)] [InlineData(DesktopPointerShape.Resize, 1)] [InlineData(DesktopPointerShape.Resize, 2)] public void NativeCoverageIsBoundedAndHasThinCorePlusLowAlphaHalo(DesktopPointerShape shape, int scale) { var bitmap = new BitmapCanvas(96, 96, scale, 0x09121B); DesktopPointerRenderer.Draw(bitmap, 40, 40, shape, Accent); Assert.Equal(2, bitmap.Calls.Count); var halo = bitmap.Calls[0]; var core = bitmap.Calls[1]; Assert.All(bitmap.Calls, call => Assert.Equal(Accent, call.Rgb)); Assert.All(halo.Alpha, value => Assert.InRange(value, (byte)0, (byte)38)); Assert.Contains(core.Alpha, value => value is > 0 and < 255); Assert.Contains(core.Alpha, value => value == 255); int coreArea = core.Alpha.Count(value => value >= 128); Assert.True(coreArea < core.Alpha.Length / 8); Assert.True(halo.Alpha.Count(value => value > 0) > coreArea * 4); var bounds = DesktopPointerRenderer.GetBounds(40, 40, shape); Assert.Equal(bounds.X * scale, core.X); Assert.Equal(bounds.Y * scale, core.Y); Assert.Equal(bounds.Width * scale, core.Width); Assert.Equal(bounds.Height * scale, core.Height); for (int row = 0; row < bitmap.NativeHeight; row++) for (int col = 0; col < bitmap.NativeWidth; col++) if (bitmap.Pixels[row * bitmap.NativeWidth + col] != 0x09121B) Assert.True(col >= bounds.X * scale && col < (bounds.X + bounds.Width) * scale && row >= bounds.Y * scale && row < (bounds.Y + bounds.Height) * scale); } [Fact] public void TwoHundredPercentRasterDoesNotReplicateLogicalPixelSquares() { var bitmap = new BitmapCanvas(96, 96, 2, 0x09121B); DesktopPointerRenderer.Draw(bitmap, 40, 40, DesktopPointerShape.Arrow, Accent); var core = bitmap.Calls[1]; int variedBlocks = 0; for (int row = 0; row + 1 < core.Height; row += 2) for (int col = 0; col + 1 < core.Width; col += 2) { byte value = core.Alpha[row * core.Width + col]; if (value != core.Alpha[row * core.Width + col + 1] || value != core.Alpha[(row + 1) * core.Width + col] || value != core.Alpha[(row + 1) * core.Width + col + 1]) variedBlocks++; } Assert.True(variedBlocks > 12); } [Theory] [InlineData(0x09121Bu)] [InlineData(0xF7F8FBu)] public void HaloBlendsRealBackgroundAndCannotIntroduceWhiteFringe(uint background) { var bitmap = new BitmapCanvas(96, 96, 2, background); DesktopPointerRenderer.Draw(bitmap, 40, 40, DesktopPointerShape.Arrow, Accent); var halo = bitmap.Calls[0]; var core = bitmap.Calls[1]; bool checkedHalo = false; for (int index = 0; index < halo.Alpha.Length; index++) { int x = halo.X + index % halo.Width, y = halo.Y + index / halo.Width; uint actual = bitmap.Pixels[y * bitmap.NativeWidth + x]; for (int shift = 0; shift <= 16; shift += 8) Assert.InRange((actual >> shift) & 255, Math.Min((background >> shift) & 255, (Accent >> shift) & 255), Math.Max((background >> shift) & 255, (Accent >> shift) & 255)); if (halo.Alpha[index] is > 0 and < 38 && core.Alpha[index] == 0) { Assert.Equal(Mix(background, Accent, halo.Alpha[index]), actual); Assert.NotEqual(Accent, actual); checkedHalo = true; } } Assert.True(checkedHalo); Assert.Equal(background, bitmap.Pixels[0]); } [Fact] public void SameTranslucentHaloRetainsDifferentDarkAndLightBackgrounds() { var dark = new BitmapCanvas(96, 96, 2, 0x09121B); var light = new BitmapCanvas(96, 96, 2, 0xF7F8FB); DesktopPointerRenderer.Draw(dark, 40, 40, DesktopPointerShape.Text, Accent); DesktopPointerRenderer.Draw(light, 40, 40, DesktopPointerShape.Text, Accent); var halo = dark.Calls[0]; var core = dark.Calls[1]; int sample = Array.FindIndex(halo.Alpha, value => value is > 4 and < 20); Assert.True(sample >= 0); Assert.Equal(0, core.Alpha[sample]); int destination = (halo.Y + sample / halo.Width) * dark.NativeWidth + halo.X + sample % halo.Width; Assert.NotEqual(dark.Pixels[destination], light.Pixels[destination]); } [Fact] public void ArrowIntersectionIsThickerThanItsArmEndpoint() { var bitmap = new BitmapCanvas(96, 96, 2, 0x09121B); DesktopPointerRenderer.Draw(bitmap, 40, 40, DesktopPointerShape.Arrow, Accent); var mask = bitmap.Calls[1]; int Mass(int logicalX) { int sum = 0; for (int row = 76 - mask.Y; row < 84 - mask.Y; row++) for (int col = (40 + logicalX) * 2 - mask.X; col < (41 + logicalX) * 2 - mask.X; col++) sum += mask.Alpha[row * mask.Width + col]; return sum; } Assert.True(Mass(0) > Mass(7) * 2); } [Theory] [InlineData(DesktopPointerShape.Arrow)] [InlineData(DesktopPointerShape.Text)] [InlineData(DesktopPointerShape.Resize)] public void PartiallyOffscreenCursorIsClippedWithoutChangingRemotePixels(DesktopPointerShape shape) { var bitmap = new BitmapCanvas(32, 32, 2, 0x09121B); DesktopPointerRenderer.Draw(bitmap, 0, 0, shape, Accent); Assert.Contains(bitmap.Pixels, value => value != 0x09121B); Assert.Equal(0x09121Bu, bitmap.Pixels[^1]); } private sealed class LegacyCanvas : IDesktopCanvas { public int Width => 96; public int Height => 96; public List Colors { get; } = []; public void Fill(uint rgb, int x, int y, int width, int height) => Colors.Add(rgb); public void Line(uint rgb, int x1, int y1, int x2, int y2) { } public void Text(string text, uint rgb, int x, int y) { } public void Present() { } } [Fact] public void LegacyCanvasDrawsCoreWithoutInventingOpaqueGlowBackground() { var legacy = new LegacyCanvas(); DesktopPointerRenderer.Draw(legacy, 40, 40, DesktopPointerShape.Arrow, Accent); Assert.NotEmpty(legacy.Colors); Assert.All(legacy.Colors, color => Assert.Equal(Accent, color)); } [Fact] public void SettingsKeepsExistingApplicationOrdinalContract() { Assert.Equal(0, (int)DesktopApplication.Files); Assert.Equal(3, (int)DesktopApplication.Terminal); Assert.Equal(4, (int)DesktopApplication.Settings); Assert.Equal(8, (int)DesktopIcon.ApplicationFile); Assert.Equal(9, (int)DesktopIcon.Settings); // A code-native symbol, outside the nine-entry PNG atlas. } private sealed class AllocationProbe(int scalePercent = 200) : IDesktopCoverageCanvas { public int Width => 96; public int Height => 96; public int ScalePercent => scalePercent; public int Calls; public void Fill(uint rgb, int x, int y, int width, int height) { } public void Line(uint rgb, int x1, int y1, int x2, int y2) { } public void Text(string text, uint rgb, int x, int y) { } public void Present() { } public void BlendCoverage(uint rgb, int x, int y, int width, int height, ReadOnlySpan coverage) => Calls++; } [Fact] public void WarmNativeMotionReusesMasksWithoutPerFrameAllocation() { var canvas = new AllocationProbe(); for (int index = 0; index < 100; index++) DesktopPointerRenderer.Draw(canvas, 40, 40, DesktopPointerShape.Arrow, Accent); long before = GC.GetAllocatedBytesForCurrentThread(); for (int index = 0; index < 500; index++) DesktopPointerRenderer.Draw(canvas, 40 + index % 4, 40, DesktopPointerShape.Arrow, Accent); long allocated = GC.GetAllocatedBytesForCurrentThread() - before; Assert.Equal(0, allocated); Assert.Equal(1200, canvas.Calls); } [Fact] public void NewHotFamilyAfterCacheSaturationStillWarmsToZeroAllocation() { // Fill more than the entire 24-family cache using distinct scales. // These entries are unrelated to the new family we subsequently use. for (int scale = 50; scale < 80; scale++) DesktopPointerRenderer.Draw(new AllocationProbe(scale), 40, 40, DesktopPointerShape.Text, Accent); var hot = new AllocationProbe(375); for (int index = 0; index < 100; index++) DesktopPointerRenderer.Draw(hot, 40, 40, DesktopPointerShape.Resize, Accent); long before = GC.GetAllocatedBytesForCurrentThread(); for (int index = 0; index < 500; index++) DesktopPointerRenderer.Draw(hot, 40 + index % 4, 40, DesktopPointerShape.Resize, Accent); long allocated = GC.GetAllocatedBytesForCurrentThread() - before; Assert.Equal(0, allocated); Assert.Equal(1200, hot.Calls); } [Fact] public void ConcurrentFirstUseOfSameMaskFamilyIsSafe() { Parallel.For(0, 48, index => { var canvas = new AllocationProbe(125 + index % 3 * 25); for (int iteration = 0; iteration < 8; iteration++) DesktopPointerRenderer.Draw(canvas, 40, 40, (DesktopPointerShape)(index % 3), Accent); Assert.Equal(16, canvas.Calls); }); } [Fact] public void AnotherThreadsCachePressureDoesNotRebuildTheCurrentUiMask() { var hot = new AllocationProbe(375); for (int index = 0; index < 100; index++) DesktopPointerRenderer.Draw(hot, 40, 40, DesktopPointerShape.Resize, Accent); Exception? failure = null; var pressure = new Thread(() => { try { for (int scale = 50; scale < 90; scale++) DesktopPointerRenderer.Draw(new AllocationProbe(scale), 40, 40, DesktopPointerShape.Text, Accent); } catch (Exception error) { failure = error; } }); pressure.Start(); pressure.Join(); Assert.Null(failure); long before = GC.GetAllocatedBytesForCurrentThread(); for (int index = 0; index < 500; index++) DesktopPointerRenderer.Draw(hot, 40 + index % 4, 40, DesktopPointerShape.Resize, Accent); Assert.Equal(0, GC.GetAllocatedBytesForCurrentThread() - before); Assert.Equal(1200, hot.Calls); } [Fact] public void TransparentOuterGuardKeepsAllRasterCoverageInsideDamageBounds() { foreach (var shape in Enum.GetValues()) { var bitmap = new BitmapCanvas(96, 96, 2, 0x09121B); DesktopPointerRenderer.Draw(bitmap, 40, 40, shape, Accent); foreach (var call in bitmap.Calls) { for (int col = 0; col < call.Width; col++) { Assert.Equal(0, call.Alpha[col]); Assert.Equal(0, call.Alpha[(call.Height - 1) * call.Width + col]); } for (int row = 0; row < call.Height; row++) { Assert.Equal(0, call.Alpha[row * call.Width]); Assert.Equal(0, call.Alpha[row * call.Width + call.Width - 1]); } } } } [Fact] public void OptionalInspectionSheetsUseTheSameNativeCoveragePath() { string? destination = Environment.GetEnvironmentVariable("XFE_CURSOR_PROOF_PATH"); foreach (int scale in new[] { 1, 2 }) { var bitmap = new BitmapCanvas(384, 160, scale, 0x09121B); bitmap.Fill(0xF7F8FB, 0, 80, 384, 80); for (int row = 0; row < 2; row++) for (int shape = 0; shape < 3; shape++) DesktopPointerRenderer.Draw(bitmap, 64 + shape * 128, 40 + row * 80, (DesktopPointerShape)shape, Accent); Assert.Equal(12, bitmap.Calls.Count); if (destination is null) continue; Assert.True(Path.IsPathFullyQualified(destination)); Directory.CreateDirectory(destination); WritePng(Path.Combine(destination, $"Pointer{scale}x.png"), bitmap.NativeWidth, bitmap.NativeHeight, bitmap.Pixels); } } private static void WritePng(string path, int width, int height, uint[] pixels) { using var output = File.Create(path); output.Write(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }); Span header = stackalloc byte[13]; header.Clear(); BinaryPrimitives.WriteUInt32BigEndian(header, (uint)width); BinaryPrimitives.WriteUInt32BigEndian(header[4..], (uint)height); header[8] = 8; header[9] = 2; Chunk(output, "IHDR"u8, header); using var compressed = new MemoryStream(); using (var zlib = new ZLibStream(compressed, CompressionLevel.Fastest, true)) for (int row = 0; row < height; row++) { zlib.WriteByte(0); for (int col = 0; col < width; col++) { uint rgb = pixels[row * width + col]; zlib.WriteByte((byte)(rgb >> 16)); zlib.WriteByte((byte)(rgb >> 8)); zlib.WriteByte((byte)rgb); } } Chunk(output, "IDAT"u8, compressed.ToArray()); Chunk(output, "IEND"u8, []); } private static void Chunk(Stream output, ReadOnlySpan name, ReadOnlySpan data) { Span word = stackalloc byte[4]; BinaryPrimitives.WriteUInt32BigEndian(word, (uint)data.Length); output.Write(word); output.Write(name); output.Write(data); uint crc = uint.MaxValue; foreach (byte value in name) crc = Crc(crc, value); foreach (byte value in data) crc = Crc(crc, value); BinaryPrimitives.WriteUInt32BigEndian(word, ~crc); output.Write(word); } private static uint Crc(uint crc, byte value) { crc ^= value; for (int bit = 0; bit < 8; bit++) crc = (crc >> 1) ^ ((crc & 1) == 0 ? 0 : 0xEDB88320u); return crc; } }