Browse Source

Added fill

flabbet 11 months ago
parent
commit
a599c03596

+ 18 - 0
src/ChunkyImageLib/Operations/EllipseHelper.cs

@@ -1,5 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 
 namespace ChunkyImageLib.Operations;
@@ -103,6 +104,9 @@ public class EllipseHelper
             return new();
         float radiusX = (rect.Width - 1) / 2.0f;
         float radiusY = (rect.Height - 1) / 2.0f;
+        if (rotationRad == 0)
+            return GenerateMidpointEllipse(radiusX, radiusY, rect.Center.X, rect.Center.Y);
+        
         return GenerateMidpointEllipse(radiusX, radiusY, rect.Center.X, rect.Center.Y, rotationRad);
     }
 
@@ -181,6 +185,10 @@ public class EllipseHelper
         return listToFill;
     }
 
+    // This function works, but honestly Skia produces better results, and it doesn't require so much
+    // computation on the CPU. I'm leaving this, because once I (or someone else) figure out how to
+    // make it better, and it will be useful.
+    // Desmos with all the math https://www.desmos.com/calculator/m9lgg7s9zu
     private static HashSet<VecI> GenerateMidpointEllipse(double halfWidth, double halfHeight, double centerX,
         double centerY, double rotationRad)
     {
@@ -336,4 +344,14 @@ public class EllipseHelper
             coordinates.Add(new VecI(xFloor, yFloorInv));
         }
     }
+
+    public static VectorPath GenerateEllipseVectorFromRect(RectI location)
+    {
+        VectorPath path = new();
+        path.AddOval(location);
+       
+        path.Close();
+        
+        return path;
+    }
 }

+ 46 - 11
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -20,6 +20,8 @@ internal class EllipseOperation : IMirroredDrawOperation
     private bool init = false;
     private VectorPath? outerPath;
     private VectorPath? innerPath;
+    
+    private VectorPath ellipseOutline;
     private Point[]? ellipse;
     private Point[]? ellipseFill;
     private RectI? ellipseFillRect;
@@ -39,13 +41,21 @@ internal class EllipseOperation : IMirroredDrawOperation
         init = true;
         if (strokeWidth == 1)
         {
-            var ellipseList = EllipseHelper.GenerateEllipseFromRect(location, rotation);
+            if (Math.Abs(rotation) < 0.001)
+            {
+                var ellipseList = EllipseHelper.GenerateEllipseFromRect(location);
 
-            ellipse = ellipseList.Select(a => new Point(a)).ToArray();
-            if (fillColor.A > 0 || paint.BlendMode != BlendMode.SrcOver)
+                ellipse = ellipseList.Select(a => new Point(a)).ToArray();
+
+                if (fillColor.A > 0 || paint.BlendMode != BlendMode.SrcOver)
+                {
+                    (var fill, ellipseFillRect) = EllipseHelper.SplitEllipseFillIntoRegions(ellipseList.ToList(), location);
+                    ellipseFill = fill.Select(a => new Point(a)).ToArray();
+                }
+            }
+            else
             {
-                /*(var fill, ellipseFillRect) = EllipseHelper.SplitEllipseFillIntoRegions(ellipseList, location);
-                ellipseFill = fill.Select(a => new Point(a)).ToArray();*/
+                ellipseOutline = EllipseHelper.GenerateEllipseVectorFromRect(location);
             }
         }
         else
@@ -70,14 +80,39 @@ internal class EllipseOperation : IMirroredDrawOperation
 
         if (strokeWidth == 1)
         {
-            if (fillColor.A > 0 || paint.BlendMode != BlendMode.SrcOver)
+            if (Math.Abs(rotation) < 0.001)
             {
-                /*paint.Color = fillColor;
-                surf.Canvas.DrawPoints(PointMode.Lines, ellipseFill!, paint);
-                surf.Canvas.DrawRect(ellipseFillRect!.Value, paint);*/
+                if (fillColor.A > 0 || paint.BlendMode != BlendMode.SrcOver)
+                {
+                    paint.Color = fillColor;
+                    surf.Canvas.DrawPoints(PointMode.Lines, ellipseFill!, paint);
+                    surf.Canvas.DrawRect(ellipseFillRect!.Value, paint);
+                }
+                
+                paint.Color = strokeColor;
+                paint.StrokeWidth = 1f;
+                surf.Canvas.DrawPoints(PointMode.Points, ellipse!, paint);
+            }
+            else
+            {
+                surf.Canvas.Save();
+                surf.Canvas.RotateRadians((float)rotation, (float)location.Center.X, (float)location.Center.Y);
+                
+                if (fillColor.A > 0 || paint.BlendMode != BlendMode.SrcOver)
+                {
+                    paint.Color = fillColor;
+                    paint.Style = PaintStyle.Fill;
+                    surf.Canvas.DrawPath(ellipseOutline, paint);
+                }
+                
+                paint.Color = strokeColor;
+                paint.Style = PaintStyle.Stroke;
+                paint.StrokeWidth = 1f;
+                
+                surf.Canvas.DrawPath(ellipseOutline, paint);
+
+                surf.Canvas.Restore();
             }
-            paint.Color = strokeColor;
-            surf.Canvas.DrawPoints(PointMode.Points, ellipse!, paint);
         }
         else
         {