using XFESystem.Desktop;
using Xunit;
namespace XFESystem.Core.Tests;
public sealed class ChromeRasterTests
{
private sealed class BitmapCanvas(int scale, uint background) : IDesktopCoverageCanvas
{
public int Width => 100;
public int Height => 80;
public int NativeWidth => Width * scale;
public int NativeHeight => Height * scale;
public int ScalePercent => scale * 100;
public uint[] Pixels { get; } = Enumerable.Repeat(background, 100 * 80 * scale * scale).ToArray();
public void Fill(uint rgb, int x, int y, int width, int height)
{
for (int py = Math.Max(0, y * scale); py < Math.Min(NativeHeight, (y + height) * scale); py++)
for (int px = Math.Max(0, x * scale); px < Math.Min(NativeWidth, (x + width) * scale); px++) Pixels[py * NativeWidth + px] = rgb;
}
public void BlendCoverage(uint rgb, int x, int y, int width, int height, ReadOnlySpan<byte> alpha)
{
Assert.Equal(width * height, alpha.Length);
for (int row = 0; row < height; row++)
for (int column = 0; column < width; column++)
{
int px = x + column, py = y + row;
if (px < 0 || py < 0 || px >= NativeWidth || py >= NativeHeight) continue;
int index = py * NativeWidth + px, a = alpha[row * width + column];
uint old = Pixels[index], color = 0;
foreach (int shift in new[] { 0, 8, 16 })
color |= (uint)(((rgb >> shift & 255) * a + (old >> shift & 255) * (255 - a) + 127) / 255) << shift;
Pixels[index] = color;
}
}
public void Line(uint rgb, int x1, int y1, int x2, int y2) => throw new InvalidOperationException("Native coverage must not fall back to aliased lines.");
public void Text(string text, uint rgb, int x, int y) { }
public void Present() { }
}
[Theory]
[InlineData(1)]
[InlineData(2)]
public void RoundedCornersContainIntermediateCoverageAndPreserveOutsidePixels(int scale)
{
const uint background = 0x09121B, foreground = 0xFAFAFE;
var bitmap = new BitmapCanvas(scale, background);
DesktopChromeRenderer.RoundedFill(bitmap, foreground, 10, 12, 60, 42, 12);
Assert.Equal(background, bitmap.Pixels[12 * scale * bitmap.NativeWidth + 10 * scale]);
Assert.Equal(foreground, bitmap.Pixels[30 * scale * bitmap.NativeWidth + 35 * scale]);
Assert.Contains(bitmap.Pixels, pixel => pixel != foreground && pixel != background);
for (int row = 0; row < bitmap.NativeHeight; row++)
for (int col = 0; col < bitmap.NativeWidth; col++)
if (col < 10 * scale || col >= 70 * scale || row < 12 * scale || row >= 54 * scale)
Assert.Equal(background, bitmap.Pixels[row * bitmap.NativeWidth + col]);
}
[Theory]
[InlineData(1)]
[InlineData(2)]
public void DiagonalCaptionStrokesAreAntialiasedAndBlendWithScene(int scale)
{
const uint background = 0xEEEFF8, foreground = 0x343C56;
var bitmap = new BitmapCanvas(scale, background);
DesktopChromeRenderer.Line(bitmap, foreground, 20, 20, 32, 32);
Assert.Contains(bitmap.Pixels, pixel => pixel != foreground && pixel != background);
Assert.Equal(background, bitmap.Pixels[0]);
Assert.Equal(background, bitmap.Pixels[50 * scale * bitmap.NativeWidth + 50 * scale]);
Assert.True(bitmap.Pixels.Count(pixel => pixel != background) < 100 * scale * scale);
}
[Fact]
public void NegativeChromeBoundsClipCleanlyAndTinyRadiiDoNotLoseInterior()
{
var bitmap = new BitmapCanvas(2, 0x102538);
DesktopChromeRenderer.RoundedFill(bitmap, 0x75C9F5, -10, -6, 40, 30, 8);
Assert.Equal(0x75C9F5u, bitmap.Pixels[0]);
DesktopChromeRenderer.RoundedFill(bitmap, 0xFAFAFE, 50, 50, 3, 2, 20);
Assert.Equal(0xFAFAFEu, bitmap.Pixels[101 * bitmap.NativeWidth + 102]);
DesktopChromeRenderer.Line(bitmap, 0x657DE2, -8, -8, 10, 10);
Assert.Contains(bitmap.Pixels, pixel => pixel == 0x102538);
}
}
using XFESystem.Desktop;
using Xunit;
namespace XFESystem.Core.Tests;
public sealed class ChromeRasterTests
{
private sealed class BitmapCanvas(int scale, uint background) : IDesktopCoverageCanvas
{
public int Width => 100;
public int Height => 80;
public int NativeWidth => Width * scale;
public int NativeHeight => Height * scale;
public int ScalePercent => scale * 100;
public uint[] Pixels { get; } = Enumerable.Repeat(background, 100 * 80 * scale * scale).ToArray();
public void Fill(uint rgb, int x, int y, int width, int height)
{
for (int py = Math.Max(0, y * scale); py < Math.Min(NativeHeight, (y + height) * scale); py++)
for (int px = Math.Max(0, x * scale); px < Math.Min(NativeWidth, (x + width) * scale); px++) Pixels[py * NativeWidth + px] = rgb;
}
public void BlendCoverage(uint rgb, int x, int y, int width, int height, ReadOnlySpan<byte> alpha)
{
Assert.Equal(width * height, alpha.Length);
for (int row = 0; row < height; row++)
for (int column = 0; column < width; column++)
{
int px = x + column, py = y + row;
if (px < 0 || py < 0 || px >= NativeWidth || py >= NativeHeight) continue;
int index = py * NativeWidth + px, a = alpha[row * width + column];
uint old = Pixels[index], color = 0;
foreach (int shift in new[] { 0, 8, 16 })
color |= (uint)(((rgb >> shift & 255) * a + (old >> shift & 255) * (255 - a) + 127) / 255) << shift;
Pixels[index] = color;
}
}
public void Line(uint rgb, int x1, int y1, int x2, int y2) => throw new InvalidOperationException("Native coverage must not fall back to aliased lines.");
public void Text(string text, uint rgb, int x, int y) { }
public void Present() { }
}
[Theory]
[InlineData(1)]
[InlineData(2)]
public void RoundedCornersContainIntermediateCoverageAndPreserveOutsidePixels(int scale)
{
const uint background = 0x09121B, foreground = 0xFAFAFE;
var bitmap = new BitmapCanvas(scale, background);
DesktopChromeRenderer.RoundedFill(bitmap, foreground, 10, 12, 60, 42, 12);
Assert.Equal(background, bitmap.Pixels[12 * scale * bitmap.NativeWidth + 10 * scale]);
Assert.Equal(foreground, bitmap.Pixels[30 * scale * bitmap.NativeWidth + 35 * scale]);
Assert.Contains(bitmap.Pixels, pixel => pixel != foreground && pixel != background);
for (int row = 0; row < bitmap.NativeHeight; row++)
for (int col = 0; col < bitmap.NativeWidth; col++)
if (col < 10 * scale || col >= 70 * scale || row < 12 * scale || row >= 54 * scale)
Assert.Equal(background, bitmap.Pixels[row * bitmap.NativeWidth + col]);
}
[Theory]
[InlineData(1)]
[InlineData(2)]
public void DiagonalCaptionStrokesAreAntialiasedAndBlendWithScene(int scale)
{
const uint background = 0xEEEFF8, foreground = 0x343C56;
var bitmap = new BitmapCanvas(scale, background);
DesktopChromeRenderer.Line(bitmap, foreground, 20, 20, 32, 32);
Assert.Contains(bitmap.Pixels, pixel => pixel != foreground && pixel != background);
Assert.Equal(background, bitmap.Pixels[0]);
Assert.Equal(background, bitmap.Pixels[50 * scale * bitmap.NativeWidth + 50 * scale]);
Assert.True(bitmap.Pixels.Count(pixel => pixel != background) < 100 * scale * scale);
}
[Fact]
public void NegativeChromeBoundsClipCleanlyAndTinyRadiiDoNotLoseInterior()
{
var bitmap = new BitmapCanvas(2, 0x102538);
DesktopChromeRenderer.RoundedFill(bitmap, 0x75C9F5, -10, -6, 40, 30, 8);
Assert.Equal(0x75C9F5u, bitmap.Pixels[0]);
DesktopChromeRenderer.RoundedFill(bitmap, 0xFAFAFE, 50, 50, 3, 2, 20);
Assert.Equal(0xFAFAFEu, bitmap.Pixels[101 * bitmap.NativeWidth + 102]);
DesktopChromeRenderer.Line(bitmap, 0x657DE2, -8, -8, 10, 10);
Assert.Contains(bitmap.Pixels, pixel => pixel == 0x102538);
}
}