48 lines
1.3 KiB
C#
48 lines
1.3 KiB
C#
using Minint.Core.Models;
|
|
|
|
namespace Minint.Core.Services.Impl;
|
|
|
|
public sealed class FloodFillService : IFloodFillService
|
|
{
|
|
public void Fill(MinintLayer layer, int x, int y, int newColorIndex, int width, int height)
|
|
{
|
|
if (x < 0 || x >= width || y < 0 || y >= height)
|
|
return;
|
|
|
|
var pixels = layer.Pixels;
|
|
int targetIndex = pixels[y * width + x];
|
|
|
|
if (targetIndex == newColorIndex)
|
|
return;
|
|
|
|
var queue = new Queue<(int X, int Y)>();
|
|
var visited = new bool[width * height];
|
|
|
|
queue.Enqueue((x, y));
|
|
visited[y * width + x] = true;
|
|
|
|
while (queue.Count > 0)
|
|
{
|
|
var (cx, cy) = queue.Dequeue();
|
|
pixels[cy * width + cx] = newColorIndex;
|
|
|
|
Span<(int, int)> neighbors =
|
|
[
|
|
(cx - 1, cy), (cx + 1, cy),
|
|
(cx, cy - 1), (cx, cy + 1)
|
|
];
|
|
|
|
foreach (var (nx, ny) in neighbors)
|
|
{
|
|
if (nx < 0 || nx >= width || ny < 0 || ny >= height)
|
|
continue;
|
|
int ni = ny * width + nx;
|
|
if (visited[ni] || pixels[ni] != targetIndex)
|
|
continue;
|
|
visited[ni] = true;
|
|
queue.Enqueue((nx, ny));
|
|
}
|
|
}
|
|
}
|
|
}
|