Selaa lähdekoodia

Aliased pen works

flabbet 10 kuukautta sitten
vanhempi
commit
bc395fb519

+ 35 - 1
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -25,6 +25,7 @@ internal class EllipseOperation : IMirroredDrawOperation
     private VecF[]? ellipse;
     private VecF[]? ellipseFill;
     private RectI? ellipseFillRect;
+    private bool antialiased;
 
     public EllipseOperation(RectI location, Color strokeColor, Color fillColor, int strokeWidth, double rotationRad, Paint? paint = null)
     {
@@ -34,6 +35,7 @@ internal class EllipseOperation : IMirroredDrawOperation
         this.strokeWidth = strokeWidth;
         this.rotation = rotationRad;
         this.paint = paint?.Clone() ?? new Paint();
+        antialiased = paint?.IsAntiAliased ?? false;
     }
 
     private void Init()
@@ -76,8 +78,22 @@ internal class EllipseOperation : IMirroredDrawOperation
         surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
 
-        paint.IsAntiAliased = targetChunk.Resolution != ChunkResolution.Full;
+        paint.IsAntiAliased = antialiased || targetChunk.Resolution != ChunkResolution.Full;
 
+        if (antialiased)
+        {
+            DrawAntiAliased(surf);   
+        }
+        else
+        {
+            DrawAliased(surf);
+        }
+
+        surf.Canvas.Restore();
+    }
+
+    private void DrawAliased(DrawingSurface surf)
+    {
         if (strokeWidth == 1)
         {
             if (Math.Abs(rotation) < 0.001)
@@ -131,6 +147,24 @@ internal class EllipseOperation : IMirroredDrawOperation
             surf.Canvas.DrawColor(strokeColor, paint.BlendMode);
             surf.Canvas.Restore();
         }
+    }
+
+    private void DrawAntiAliased(DrawingSurface surf)
+    {
+        surf.Canvas.Save();
+        surf.Canvas.RotateRadians((float)rotation, (float)location.Center.X, (float)location.Center.Y);
+        
+        paint.Color = fillColor;
+        paint.Style = PaintStyle.Fill;
+        
+        surf.Canvas.DrawOval(location.Center, location.Size / 2f, paint);
+        
+        paint.Color = strokeColor;
+        paint.Style = PaintStyle.Stroke;
+        paint.StrokeWidth = strokeWidth;
+        
+        surf.Canvas.DrawOval(location.Center, location.Size / 2f, paint);
+        
         surf.Canvas.Restore();
     }
 

+ 25 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs

@@ -1,6 +1,7 @@
 using ChunkyImageLib.Operations;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
+using Drawie.Backend.Core.Shaders;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Numerics;
@@ -34,6 +35,10 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
         this.drawOnMask = drawOnMask;
         points.Add(pos);
         this.frame = frame;
+        if (this.antiAliasing)
+        {
+            srcPaint.BlendMode = BlendMode.SrcOver;
+        }
     }
 
     [UpdateChangeMethod]
@@ -69,6 +74,11 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
         foreach (var point in bresenham)
         {
             var rect = new RectI(point - new VecI(strokeWidth / 2), new VecI(strokeWidth));
+            if (antiAliasing)
+            {
+                ApplySoftnessGradient((VecD)point);
+            }
+
             image.EnqueueDrawEllipse(rect, color, color, 1, 0, srcPaint);
         }
 
@@ -89,10 +99,25 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
         for (int i = 0; i < points.Count; i++)
         {
             var rect = new RectI(points[i] - new VecI(strokeWidth / 2), new VecI(strokeWidth));
+            if (antiAliasing)
+            {
+                ApplySoftnessGradient(points[i]);
+            }
+
             targetImage.EnqueueDrawEllipse(rect, color, color, 1, 0, srcPaint);
         }
     }
 
+    private void ApplySoftnessGradient(VecD pos)
+    {
+        srcPaint.Shader?.Dispose();
+        float radius = strokeWidth / 2f;
+        radius = MathF.Max(1, radius);
+        srcPaint.Shader = Shader.CreateRadialGradient(
+            pos, radius, new Color[] { color, color.WithAlpha(0) },
+            new float[] { 0.5f, 1 }, ShaderTileMode.Clamp);
+    }
+
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
         out bool ignoreInUndo)
     {

+ 2 - 1
src/PixiEditor/Data/Configs/ToolSetsConfig.json

@@ -33,7 +33,8 @@
       {
         "ToolName": "Pen",
         "Settings": {
-          "AntiAliasing": true
+          "AntiAliasing": true,
+          "ExposeHardness": true
         }
       },
       "Select",