瀏覽代碼

Added anti aliased ellipse tool

flabbet 10 月之前
父節點
當前提交
4a1ffc7d29

+ 2 - 2
src/ChunkyImageLib/ChunkyImage.cs

@@ -591,13 +591,13 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable, ICache
 
     /// <exception cref="ObjectDisposedException">This image is disposed</exception>
     public void EnqueueDrawEllipse(RectI location, Color strokeColor, Color fillColor, int strokeWidth,
-        double rotationRad = 0,
+        double rotationRad = 0, bool antiAliased = false,
         Paint? paint = null)
     {
         lock (lockObject)
         {
             ThrowIfDisposed();
-            EllipseOperation operation = new(location, strokeColor, fillColor, strokeWidth, rotationRad, paint);
+            EllipseOperation operation = new(location, strokeColor, fillColor, strokeWidth, rotationRad, antiAliased, paint);
             EnqueueOperation(operation);
         }
     }

+ 13 - 5
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -27,7 +27,8 @@ internal class EllipseOperation : IMirroredDrawOperation
     private RectI? ellipseFillRect;
     private bool antialiased;
 
-    public EllipseOperation(RectI location, Color strokeColor, Color fillColor, int strokeWidth, double rotationRad, Paint? paint = null)
+    public EllipseOperation(RectI location, Color strokeColor, Color fillColor, int strokeWidth, double rotationRad,
+        bool antiAliased, Paint? paint = null)
     {
         this.location = location;
         this.strokeColor = strokeColor;
@@ -35,7 +36,7 @@ internal class EllipseOperation : IMirroredDrawOperation
         this.strokeWidth = strokeWidth;
         this.rotation = rotationRad;
         this.paint = paint?.Clone() ?? new Paint();
-        antialiased = paint?.IsAntiAliased ?? false;
+        antialiased = antiAliased;
     }
 
     private void Init()
@@ -94,6 +95,7 @@ internal class EllipseOperation : IMirroredDrawOperation
 
     private void DrawAliased(DrawingSurface surf)
     {
+        paint.IsAntiAliased = false;
         if (strokeWidth == 1)
         {
             if (Math.Abs(rotation) < 0.001)
@@ -154,16 +156,22 @@ internal class EllipseOperation : IMirroredDrawOperation
         surf.Canvas.Save();
         surf.Canvas.RotateRadians((float)rotation, (float)location.Center.X, (float)location.Center.Y);
         
+        paint.IsAntiAliased = false;
         paint.Color = fillColor;
         paint.Style = PaintStyle.Fill;
         
-        surf.Canvas.DrawOval(location.Center, location.Size / 2f, paint);
+        RectD fillRect = ((RectD)location).Inflate(-strokeWidth / 2f);
         
+        surf.Canvas.DrawOval(fillRect.Center, fillRect.Size / 2f, paint);
+        
+        paint.IsAntiAliased = true;
         paint.Color = strokeColor;
         paint.Style = PaintStyle.Stroke;
         paint.StrokeWidth = strokeWidth;
         
-        surf.Canvas.DrawOval(location.Center, location.Size / 2f, paint);
+        RectD strokeRect = ((RectD)location).Inflate((-strokeWidth / 2f));
+        
+        surf.Canvas.DrawOval(strokeRect.Center, strokeRect.Size / 2f, paint);
         
         surf.Canvas.Restore();
     }
@@ -191,7 +199,7 @@ internal class EllipseOperation : IMirroredDrawOperation
             newLocation = (RectI)newLocation.ReflectX((double)verAxisX).Round();
         if (horAxisY is not null)
             newLocation = (RectI)newLocation.ReflectY((double)horAxisY).Round();
-        return new EllipseOperation(newLocation, strokeColor, fillColor, strokeWidth, rotation, paint);
+        return new EllipseOperation(newLocation, strokeColor, fillColor, strokeWidth, rotation, antialiased, paint);
     }
 
     public void Dispose()

+ 4 - 3
src/ChunkyImageLib/Operations/RectangleOperation.cs

@@ -41,7 +41,7 @@ internal class RectangleOperation : IMirroredDrawOperation
 
         if (Data.AntiAliasing)
         {
-            DrawAntiAliased(surf, rect, innerRect);
+            DrawAntiAliased(surf, rect);
         }
         else
         {
@@ -69,7 +69,7 @@ internal class RectangleOperation : IMirroredDrawOperation
         surf.Canvas.DrawColor(Data.StrokeColor, Data.BlendMode);
     }
 
-    private void DrawAntiAliased(DrawingSurface surf, RectD rect, RectD innerRect)
+    private void DrawAntiAliased(DrawingSurface surf, RectD rect)
     {
         // draw fill
         if (Data.FillColor.A > 0)
@@ -89,7 +89,8 @@ internal class RectangleOperation : IMirroredDrawOperation
         paint.StrokeWidth = (float)Data.StrokeWidth;
         paint.Color = Data.StrokeColor;
         paint.Style = PaintStyle.Stroke;
-        surf.Canvas.DrawRect((float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height, paint);
+        RectD innerRect = rect.Inflate(-Data.StrokeWidth / 2f);
+        surf.Canvas.DrawRect((float)innerRect.Left, (float)innerRect.Top, (float)innerRect.Width, (float)innerRect.Height, paint);
     }
 
     public AffectedArea FindAffectedArea(VecI imageSize)

+ 4 - 2
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawRasterEllipse_UpdateableChange.cs

@@ -13,11 +13,12 @@ internal class DrawRasterEllipse_UpdateableChange : UpdateableChange
     private int strokeWidth;
     private readonly bool drawOnMask;
     private int frame;
+    private bool antialiased;
 
     private CommittedChunkStorage? storedChunks;
 
     [GenerateUpdateableChangeActions]
-    public DrawRasterEllipse_UpdateableChange(Guid memberGuid, RectI location, double rotationRad, Color strokeColor, Color fillColor, int strokeWidth, bool drawOnMask, int frame)
+    public DrawRasterEllipse_UpdateableChange(Guid memberGuid, RectI location, double rotationRad, Color strokeColor, Color fillColor, int strokeWidth, bool antialiased, bool drawOnMask, int frame)
     {
         this.memberGuid = memberGuid;
         this.location = location;
@@ -27,6 +28,7 @@ internal class DrawRasterEllipse_UpdateableChange : UpdateableChange
         this.strokeWidth = strokeWidth;
         this.drawOnMask = drawOnMask;
         this.frame = frame;
+        this.antialiased = antialiased;
     }
 
     [UpdateChangeMethod]
@@ -53,7 +55,7 @@ internal class DrawRasterEllipse_UpdateableChange : UpdateableChange
         if (!location.IsZeroOrNegativeArea)
         {
             DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
-            targetImage.EnqueueDrawEllipse(location, strokeColor, fillColor, strokeWidth, rotation);
+            targetImage.EnqueueDrawEllipse(location, strokeColor, fillColor, strokeWidth, rotation, antialiased);
         }
 
         var affectedArea = targetImage.FindAffectedArea();

+ 3 - 3
src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs

@@ -97,7 +97,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
                 ApplySoftnessGradient((VecD)point);
             }
 
-            image.EnqueueDrawEllipse(rect, color, color, 1, 0, srcPaint);
+            image.EnqueueDrawEllipse(rect, color, color, 1, 0, antiAliasing, srcPaint);
         }
 
         var affChunks = image.FindAffectedArea(opCount);
@@ -110,7 +110,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
         if (points.Count == 1)
         {
             var rect = new RectI(points[0] - new VecI(strokeWidth / 2), new VecI(strokeWidth));
-            targetImage.EnqueueDrawEllipse(rect, color, color, 1, 0, srcPaint);
+            targetImage.EnqueueDrawEllipse(rect, color, color, 1, 0, antiAliasing, srcPaint);
             return;
         }
 
@@ -130,7 +130,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
                 ApplySoftnessGradient(points[i]);
             }
 
-            targetImage.EnqueueDrawEllipse(rect, color, color, 1, 0, srcPaint);
+            targetImage.EnqueueDrawEllipse(rect, color, color, 1, 0, antiAliasing, srcPaint);
         }
     }
 

+ 3 - 3
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/RasterEllipseToolExecutor.cs

@@ -25,7 +25,7 @@ internal class RasterEllipseToolExecutor : ComplexShapeToolExecutor<IRasterEllip
         lastRect = rect;
         lastRadians = rotationRad;
 
-        internals!.ActionAccumulator.AddActions(new DrawRasterEllipse_Action(memberId, rect, rotationRad, StrokeColor, FillColor, StrokeWidth, drawOnMask, document!.AnimationHandler.ActiveFrameBindable));
+        internals!.ActionAccumulator.AddActions(new DrawRasterEllipse_Action(memberId, rect, rotationRad, StrokeColor, FillColor, StrokeWidth, toolbar.AntiAliasing, drawOnMask, document!.AnimationHandler.ActiveFrameBindable));
     }
 
     public override ExecutorType Type => ExecutorType.ToolLinked;
@@ -33,7 +33,7 @@ internal class RasterEllipseToolExecutor : ComplexShapeToolExecutor<IRasterEllip
     protected override void DrawShape(VecI currentPos, double rotationRad, bool firstDraw) => DrawEllipseOrCircle(currentPos, rotationRad, firstDraw);
     protected override IAction SettingsChangedAction()
     {
-        return new DrawRasterEllipse_Action(memberId, lastRect, lastRadians, StrokeColor, FillColor, StrokeWidth, drawOnMask, document!.AnimationHandler.ActiveFrameBindable);
+        return new DrawRasterEllipse_Action(memberId, lastRect, lastRadians, StrokeColor, FillColor, StrokeWidth, toolbar.AntiAliasing, drawOnMask, document!.AnimationHandler.ActiveFrameBindable);
     }
 
     protected override IAction TransformMovedAction(ShapeData data, ShapeCorners corners)
@@ -45,7 +45,7 @@ internal class RasterEllipseToolExecutor : ComplexShapeToolExecutor<IRasterEllip
         lastRadians = radians;
         
         return new DrawRasterEllipse_Action(memberId, lastRect, lastRadians, StrokeColor,
-            FillColor, StrokeWidth, drawOnMask, document!.AnimationHandler.ActiveFrameBindable);
+            FillColor, StrokeWidth, toolbar.AntiAliasing, drawOnMask, document!.AnimationHandler.ActiveFrameBindable);
     }
 
     protected override IAction EndDrawAction() => new EndDrawRasterEllipse_Action();