Просмотр исходного кода

Fixed missing pixels when undoing

flabbet 8 месяцев назад
Родитель
Сommit
7d36121f95

+ 5 - 4
src/ChunkyImageLib/Operations/BresenhamLineHelper.cs

@@ -2,19 +2,20 @@
 using Drawie.Numerics;
 
 namespace ChunkyImageLib.Operations;
+
 public static class BresenhamLineHelper
 {
-    public static VecF[] GetBresenhamLine(VecI start, VecI end)
+    public static VecI[] GetBresenhamLine(VecI start, VecI end)
     {
         int count = Math.Abs((start - end).LongestAxis) + 1;
         if (count > 100000)
-            return Array.Empty<VecF>();
-        VecF[] output = new VecF[count];
+            return [];
+        VecI[] output = new VecI[count];
         CalculateBresenhamLine(start, end, output);
         return output;
     }
 
-    private static void CalculateBresenhamLine(VecI start, VecI end, VecF[] output)
+    private static void CalculateBresenhamLine(VecI start, VecI end, VecI[] output)
     {
         int index = 0;
 

+ 1 - 1
src/ChunkyImageLib/Operations/BresenhamLineOperation.cs

@@ -23,7 +23,7 @@ internal class BresenhamLineOperation : IMirroredDrawOperation
         this.color = color;
         this.blendMode = blendMode;
         paint = new Paint() { BlendMode = blendMode };
-        points = BresenhamLineHelper.GetBresenhamLine(from, to);
+        points = BresenhamLineHelper.GetBresenhamLine(from, to).Select(v => new VecF(v)).ToArray();
     }
 
     public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)

+ 13 - 8
src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs

@@ -24,6 +24,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
     private readonly List<VecI> points = new();
     private int frame;
     private VecF lastPos;
+    private int lastAppliedPointIndex = -1;
 
     [GenerateUpdateableChangeActions]
     public LineBasedPen_UpdateableChange(Guid memberGuid, Color color, VecI pos, float strokeWidth, bool erasing,
@@ -59,7 +60,12 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
     [UpdateChangeMethod]
     public void Update(VecI pos, float strokeWidth)
     {
-        points.Add(pos);
+        if (points.Count > 0)
+        {
+            var bresenham = BresenhamLineHelper.GetBresenhamLine(points[^1], pos);
+            points.AddRange(bresenham);
+        }
+        
         this.strokeWidth = strokeWidth;
     }
 
@@ -81,16 +87,13 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
     {
         var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask, frame);
 
-        var (from, to) = points.Count > 1 ? (points[^2], points[^1]) : (points[0], points[0]);
-
         int opCount = image.QueueLength;
 
-        var bresenham = BresenhamLineHelper.GetBresenhamLine(from, to);
-
         float spacingPixels = strokeWidth * spacing;
-
-        foreach (var point in bresenham)
+        
+        for(int i = Math.Max(lastAppliedPointIndex, 0); i < points.Count; i++)
         {
+            var point = points[i];
             if (points.Count > 1 && VecF.Distance(lastPos, point) < spacingPixels)
                 continue;
 
@@ -103,6 +106,8 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
 
             image.EnqueueDrawEllipse((RectD)rect, color, color, 0, 0, antiAliasing, srcPaint);
         }
+        
+        lastAppliedPointIndex = points.Count - 1;
 
         var affChunks = image.FindAffectedArea(opCount);
 
@@ -126,7 +131,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
         VecF lastPos = points[0];
 
         float spacingInPixels = strokeWidth * this.spacing;
-
+        
         for (int i = 0; i < points.Count; i++)
         {
             if (i > 0 && VecF.Distance(lastPos, points[i]) < spacingInPixels)

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changes/Drawing/PixelPerfectPen_UpdateableChange.cs

@@ -73,8 +73,8 @@ internal class PixelPerfectPen_UpdateableChange : UpdateableChange
         (pixelsToConfirm2, pixelsToConfirm) = (pixelsToConfirm, pixelsToConfirm2);
         pixelsToConfirm.Clear();
 
-        VecF[] line = BresenhamLineHelper.GetBresenhamLine(incomingPoints[pointsCount - 2], incomingPoints[pointsCount - 1]);
-        foreach (VecF pixel in line)
+        VecI[] line = BresenhamLineHelper.GetBresenhamLine(incomingPoints[pointsCount - 2], incomingPoints[pointsCount - 1]);
+        foreach (VecI pixel in line)
         {
             pixelsToConfirm.Add(pixel);
         }