فهرست منبع

Fixed flood fill on empty chunks

flabbet 8 ماه پیش
والد
کامیت
9bc777e7d8
1فایلهای تغییر یافته به همراه31 افزوده شده و 2 حذف شده
  1. 31 2
      src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFillHelper.cs

+ 31 - 2
src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFillHelper.cs

@@ -110,7 +110,24 @@ public static class FloodFillHelper
             {
                 if (colorToReplace.A == 0 && !processedEmptyChunks.Contains(chunkPos))
                 {
-                    drawingChunk.Surface.DrawingSurface.Canvas.Clear(drawingColor);
+                    int saved = drawingChunk.Surface.DrawingSurface.Canvas.Save();
+                    if (selection is not null && !selection.IsEmpty)
+                    {
+                        using VectorPath localSelection = new VectorPath(selection);
+                        localSelection.Transform(Matrix3X3.CreateTranslation(-chunkPos.X * chunkSize, -chunkPos.Y * chunkSize));
+                        
+                        drawingChunk.Surface.DrawingSurface.Canvas.ClipPath(localSelection);
+                        if (SelectionIntersectsChunk(selection, chunkPos, chunkSize))
+                        {
+                            drawingChunk.Surface.DrawingSurface.Canvas.Clear(drawingColor);
+                        }
+                    }
+                    else
+                    {
+                        drawingChunk.Surface.DrawingSurface.Canvas.Clear(drawingColor);
+                    }
+
+                    drawingChunk.Surface.DrawingSurface.Canvas.RestoreToCount(saved);
                     for (int i = 0; i < chunkSize; i++)
                     {
                         if (chunkPos.Y > 0)
@@ -180,6 +197,9 @@ public static class FloodFillHelper
             return null;
         if (checkFirstPixel && !bounds.IsWithinBounds(referenceChunk.Surface.GetRawPixel(pos)))
             return null;
+        
+        if(!SelectionIntersectsChunk(selection, chunkPos, chunkSize))
+            return null;
 
         byte[] pixelStates = new byte[chunkSize * chunkSize];
         DrawSelection(pixelStates, selection, globalSelectionBounds, chunkPos, chunkSize);
@@ -249,7 +269,7 @@ public static class FloodFillHelper
         RectI localBounds = globalBounds.Offset(-chunkPos * chunkSize).Intersect(new(0, 0, chunkSize, chunkSize));
         if (localBounds.IsZeroOrNegativeArea)
             return;
-        VectorPath shiftedSelection = new VectorPath(selection);
+        using VectorPath shiftedSelection = new VectorPath(selection);
         shiftedSelection.Transform(Matrix3X3.CreateTranslation(-chunkPos.X * chunkSize, -chunkPos.Y * chunkSize));
 
         fixed (byte* arr = array)
@@ -262,4 +282,13 @@ public static class FloodFillHelper
             drawingSurface.Canvas.Flush();
         }
     }
+    
+    private static bool SelectionIntersectsChunk(VectorPath selection, VecI chunkPos, int chunkSize)
+    {
+        if (selection is null || selection.IsEmpty)
+            return true;
+        
+        RectD chunkBounds = new(chunkPos * chunkSize, new VecI(chunkSize));
+        return selection.Bounds.IntersectsWithInclusive(chunkBounds);
+    }
 }