CPKreuz пре 8 месеци
родитељ
комит
1e91c79cfd

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit f1b0d435bb5a916def8a7eed99fd71bf2749cc30
+Subproject commit 091a73eb0c67eadf3d5376f410e933466a4a4502

+ 29 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/DrawieColorFilter.cs

@@ -0,0 +1,29 @@
+using Drawie.Backend.Core.ColorsImpl;
+using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Numerics;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph;
+
+public sealed class DrawieColorFilter(Filter previous, ColorFilter filter) : Filter(previous), IDisposable
+{
+    private bool willDipose;
+    private Paint _paint = new() { ColorFilter = filter, BlendMode = BlendMode.Src };
+
+    protected override void DoApply(DrawingSurface surface)
+    {
+        using var snapshot = surface.Snapshot();
+        surface.Canvas.DrawImage(snapshot, 0, 0, _paint);
+
+        if (willDipose)
+        {
+            _paint.Dispose();
+            filter.Dispose();
+        }
+    }
+
+    public void Dispose()
+    {
+        willDipose = true;
+    }
+}

+ 28 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/DrawieImageFilter.cs

@@ -0,0 +1,28 @@
+using Drawie.Backend.Core.ColorsImpl;
+using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Numerics;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph;
+
+public sealed class DrawieImageFilter(Filter previous, ImageFilter filter) : Filter(previous)
+{
+    private Paint _paint = new() { ImageFilter = filter, BlendMode = BlendMode.Src };
+
+    protected override void DoApply(DrawingSurface surface)
+    {
+        using var snapshot = surface.Snapshot();
+        surface.Canvas.DrawImage(snapshot, 0, 0, _paint);
+    }
+
+    public void SetImageFilter(ImageFilter imageFilter)
+    {
+        
+    }
+
+    public void Dispose()
+    {
+        _paint.Dispose();
+        filter.Dispose();
+    }
+}

+ 8 - 37
src/PixiEditor.ChangeableDocument/Changeables/Graph/Filter.cs

@@ -1,48 +1,19 @@
 using System.Diagnostics.Contracts;
 using System.Diagnostics.Contracts;
+using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph;
 
 
-public sealed class Filter : IDisposable
+public abstract class Filter(Filter? previous)
 {
 {
-    public Filter(ColorFilter? colorFilter, ImageFilter? imageFilter)
-    {
-        ColorFilter = colorFilter;
-        ImageFilter = imageFilter;
-    }
-    
-    public ColorFilter? ColorFilter { get; }
-    
-    public ImageFilter? ImageFilter { get; }
+    public Filter? Previous { get; } = previous;
 
 
-    [Pure]
-    public Filter Add(ColorFilter? colorFilter, ImageFilter? imageFilter)
+    public void Apply(DrawingSurface surface)
     {
     {
-        ColorFilter? color = ColorFilter;
+        Previous?.Apply(surface);
         
         
-        if (colorFilter != null)
-        {
-            color = ColorFilter == null ? colorFilter : ColorFilter.CreateCompose(colorFilter, ColorFilter);
-        }
-
-        ImageFilter? image = ImageFilter;
-        if (imageFilter == null)
-        {
-            image = ImageFilter == null ? imageFilter : ImageFilter.CreateCompose(imageFilter, ImageFilter);
-        }
-
-        return new Filter(color, image);
-    }
-
-    [Pure]
-    public Filter Add(ColorFilter? colorFilter) => Add(colorFilter, null);
-
-    [Pure]
-    public Filter Add(ImageFilter? imageFilter) => Add(null, imageFilter);
-
-    public void Dispose()
-    {
-        ColorFilter?.Dispose();
-        ImageFilter?.Dispose();
+        DoApply(surface);
     }
     }
+    
+    protected abstract void DoApply(DrawingSurface surface);
 }
 }

+ 4 - 9
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/ApplyFilterNode.cs

@@ -11,7 +11,6 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.FilterNodes;
 [NodeInfo("ApplyFilter")]
 [NodeInfo("ApplyFilter")]
 public class ApplyFilterNode : RenderNode, IRenderInput
 public class ApplyFilterNode : RenderNode, IRenderInput
 {
 {
-    private Paint _paint = new();
     public InputProperty<Filter?> Filter { get; }
     public InputProperty<Filter?> Filter { get; }
 
 
     public RenderInputProperty Background { get; }
     public RenderInputProperty Background { get; }
@@ -25,15 +24,11 @@ public class ApplyFilterNode : RenderNode, IRenderInput
 
 
     protected override void OnPaint(RenderContext context, DrawingSurface surface)
     protected override void OnPaint(RenderContext context, DrawingSurface surface)
     {
     {
-        if (Background.Value == null || Filter.Value == null)
+        if (Background.Value == null)
             return;
             return;
-        
-        _paint.SetFilters(Filter.Value);
-        var layer = surface.Canvas.SaveLayer(_paint);
-        
+
         Background.Value.Paint(context, surface);
         Background.Value.Paint(context, surface);
-        
-        surface.Canvas.RestoreToCount(layer);
+        Filter.Value?.Apply(surface);
     }
     }
 
 
     public override RectD? GetPreviewBounds(int frame, string elementToRenderName = "")
     public override RectD? GetPreviewBounds(int frame, string elementToRenderName = "")
@@ -49,7 +44,7 @@ public class ApplyFilterNode : RenderNode, IRenderInput
 
 
         RenderContext context = new(renderOn, frame, ChunkResolution.Full, VecI.One);
         RenderContext context = new(renderOn, frame, ChunkResolution.Full, VecI.One);
         
         
-        int layer = renderOn.Canvas.SaveLayer(_paint);
+        int layer = renderOn.Canvas.SaveLayer();
         Background.Value.Paint(context, renderOn);
         Background.Value.Paint(context, renderOn);
         renderOn.Canvas.RestoreToCount(layer);
         renderOn.Canvas.RestoreToCount(layer);
 
 

+ 4 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/ColorMatrixFilterNode.cs

@@ -8,7 +8,7 @@ public class ColorMatrixFilterNode : FilterNode
 {
 {
     public InputProperty<ColorMatrix> Matrix { get; }
     public InputProperty<ColorMatrix> Matrix { get; }
 
 
-    private ColorFilter filter;
+    private DrawieColorFilter? filter;
     private ColorMatrix lastMatrix;
     private ColorMatrix lastMatrix;
     
     
     public ColorMatrixFilterNode()
     public ColorMatrixFilterNode()
@@ -16,7 +16,8 @@ public class ColorMatrixFilterNode : FilterNode
         Matrix = CreateInput(nameof(Matrix), "MATRIX", ColorMatrix.Identity);
         Matrix = CreateInput(nameof(Matrix), "MATRIX", ColorMatrix.Identity);
     }
     }
 
 
-    protected override ColorFilter? GetColorFilter()
+
+    protected override Filter? GetFilter(Filter? parent)
     {
     {
         if (Matrix.Value.Equals(lastMatrix))
         if (Matrix.Value.Equals(lastMatrix))
         {
         {
@@ -26,7 +27,7 @@ public class ColorMatrixFilterNode : FilterNode
         lastMatrix = Matrix.Value;
         lastMatrix = Matrix.Value;
         filter?.Dispose();
         filter?.Dispose();
         
         
-        filter = ColorFilter.CreateColorMatrix(Matrix.Value);
+        filter = new DrawieColorFilter(parent, ColorFilter.CreateColorMatrix(Matrix.Value));
         return filter;
         return filter;
     }
     }
 
 

+ 2 - 15
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/FilterNode.cs

@@ -18,21 +18,8 @@ public abstract class FilterNode : Node
     
     
     protected override void OnExecute(RenderContext context)
     protected override void OnExecute(RenderContext context)
     {
     {
-        var colorFilter = GetColorFilter();
-        var imageFilter = GetImageFilter();
-
-        if (colorFilter == null && imageFilter == null)
-        {
-            Output.Value = Input.Value;
-            return;
-        }
-
-        var filter = Input.Value;
-
-        Output.Value = filter == null ? new Filter(colorFilter, imageFilter) : filter.Add(colorFilter, imageFilter);
+        Output.Value = GetFilter(Input.Value) ?? Input.Value;
     }
     }
 
 
-    protected virtual ColorFilter? GetColorFilter() => null;
-    
-    protected virtual ImageFilter? GetImageFilter() => null;
+    protected abstract Filter? GetFilter(Filter? parent);
 }
 }

+ 12 - 5
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/GrayscaleNode.cs

@@ -23,7 +23,7 @@ public class GrayscaleNode : FilterNode
     private bool lastNormalize;
     private bool lastNormalize;
     private Vec3D lastCustomWeight;
     private Vec3D lastCustomWeight;
     
     
-    private ColorFilter? filter;
+    private DrawieColorFilter? filter;
     
     
     public GrayscaleNode()
     public GrayscaleNode()
     {
     {
@@ -34,7 +34,7 @@ public class GrayscaleNode : FilterNode
         CustomWeight = CreateInput("CustomWeight", "WEIGHT_FACTOR", new Vec3D(1, 1, 1));
         CustomWeight = CreateInput("CustomWeight", "WEIGHT_FACTOR", new Vec3D(1, 1, 1));
     }
     }
 
 
-    protected override ColorFilter GetColorFilter()
+    protected override Filter? GetFilter(Filter? parent)
     {
     {
         if (Mode.Value == lastMode 
         if (Mode.Value == lastMode 
             && Factor.Value == lastFactor 
             && Factor.Value == lastFactor 
@@ -43,15 +43,20 @@ public class GrayscaleNode : FilterNode
         {
         {
             return filter;
             return filter;
         }
         }
+
+        if (Factor.Value == 0)
+        {
+            return null;
+        }
         
         
         lastMode = Mode.Value;
         lastMode = Mode.Value;
         lastFactor = Factor.Value;
         lastFactor = Factor.Value;
         lastNormalize = Normalize.Value;
         lastNormalize = Normalize.Value;
         lastCustomWeight = CustomWeight.Value;
         lastCustomWeight = CustomWeight.Value;
-        
+
         filter?.Dispose();
         filter?.Dispose();
-        
-        filter = ColorFilter.CreateColorMatrix(Mode.Value switch
+
+        var colorFilter = ColorFilter.CreateColorMatrix(Mode.Value switch
         {
         {
             GrayscaleMode.Weighted => UseFactor(WeightedMatrix),
             GrayscaleMode.Weighted => UseFactor(WeightedMatrix),
             GrayscaleMode.Average => UseFactor(AverageMatrix),
             GrayscaleMode.Average => UseFactor(AverageMatrix),
@@ -59,6 +64,8 @@ public class GrayscaleNode : FilterNode
                                               ColorMatrix.UseAlpha)
                                               ColorMatrix.UseAlpha)
         });
         });
         
         
+        filter = new DrawieColorFilter(parent, colorFilter);
+        
         return filter;
         return filter;
     }
     }
 
 

+ 5 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/KernelFilterNode.cs

@@ -19,7 +19,7 @@ public class KernelFilterNode : FilterNode
 
 
     public InputProperty<bool> OnAlpha { get; }
     public InputProperty<bool> OnAlpha { get; }
 
 
-    private ImageFilter filter;
+    private DrawieImageFilter? filter;
     private Kernel lastKernel;
     private Kernel lastKernel;
     private TileMode lastTile;
     private TileMode lastTile;
     private double lastGain;
     private double lastGain;
@@ -34,7 +34,7 @@ public class KernelFilterNode : FilterNode
         OnAlpha = CreateInput(nameof(OnAlpha), "ON_ALPHA", false);
         OnAlpha = CreateInput(nameof(OnAlpha), "ON_ALPHA", false);
     }
     }
 
 
-    protected override ImageFilter? GetImageFilter()
+    protected override Filter? GetFilter(Filter? parent)
     {
     {
         var kernel = Kernel.Value;
         var kernel = Kernel.Value;
         
         
@@ -50,7 +50,9 @@ public class KernelFilterNode : FilterNode
         
         
         var kernelOffset = new VecI(kernel.RadiusX, kernel.RadiusY);
         var kernelOffset = new VecI(kernel.RadiusX, kernel.RadiusY);
         
         
-        filter = ImageFilter.CreateMatrixConvolution(kernel, (float)Gain.Value, (float)Bias.Value, kernelOffset, Tile.Value, OnAlpha.Value);
+        var drawieFilter = ImageFilter.CreateMatrixConvolution(kernel, (float)Gain.Value, (float)Bias.Value, kernelOffset, Tile.Value, OnAlpha.Value);
+        filter = new DrawieImageFilter(parent, drawieFilter);
+        
         return filter;
         return filter;
     }
     }
 
 

+ 7 - 18
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FolderNode.cs

@@ -48,12 +48,6 @@ public class FolderNode : StructureNode, IReadOnlyFolderNode, IClipSource, IPrev
             using Paint paint = new();
             using Paint paint = new();
             paint.Color = Colors.White.WithAlpha((byte)Math.Round(Opacity.Value * 255f));
             paint.Color = Colors.White.WithAlpha((byte)Math.Round(Opacity.Value * 255f));
 
 
-            if (sceneContext.TargetPropertyOutput == Output)
-            {
-                paint.ColorFilter = Filters.Value?.ColorFilter;
-                paint.ImageFilter = Filters.Value?.ImageFilter;
-            }
-
             int saved = sceneContext.RenderSurface.Canvas.SaveLayer(paint);
             int saved = sceneContext.RenderSurface.Canvas.SaveLayer(paint);
             Content.Value?.Paint(sceneContext, sceneContext.RenderSurface);
             Content.Value?.Paint(sceneContext, sceneContext.RenderSurface);
 
 
@@ -102,25 +96,20 @@ public class FolderNode : StructureNode, IReadOnlyFolderNode, IClipSource, IPrev
             ApplyRasterClip(outputWorkingSurface.DrawingSurface, tempSurface.DrawingSurface);
             ApplyRasterClip(outputWorkingSurface.DrawingSurface, tempSurface.DrawingSurface);
         }
         }
 
 
-        AdjustPaint(useFilters);
+        AdjustPaint();
+        
+        if (useFilters)
+        {
+            Filters.Value.Apply(outputWorkingSurface.DrawingSurface);
+        }
 
 
         blendPaint.BlendMode = RenderContext.GetDrawingBlendMode(BlendMode.Value);
         blendPaint.BlendMode = RenderContext.GetDrawingBlendMode(BlendMode.Value);
         sceneContext.RenderSurface.Canvas.DrawSurface(outputWorkingSurface.DrawingSurface, 0, 0, blendPaint);
         sceneContext.RenderSurface.Canvas.DrawSurface(outputWorkingSurface.DrawingSurface, 0, 0, blendPaint);
     }
     }
 
 
-    private void AdjustPaint(bool useFilters)
+    private void AdjustPaint()
     {
     {
         blendPaint.Color = Colors.White.WithAlpha((byte)Math.Round(Opacity.Value * 255f));
         blendPaint.Color = Colors.White.WithAlpha((byte)Math.Round(Opacity.Value * 255f));
-        if (useFilters)
-        {
-            blendPaint.ColorFilter = Filters.Value?.ColorFilter;
-            blendPaint.ImageFilter = Filters.Value?.ImageFilter;
-        }
-        else
-        {
-            blendPaint.ColorFilter = null;
-            blendPaint.ImageFilter = null;
-        }
     }
     }
 
 
     public override RectD? GetTightBounds(KeyFrameTime frameTime)
     public override RectD? GetTightBounds(KeyFrameTime frameTime)

+ 1 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/LayerNode.cs

@@ -107,12 +107,11 @@ public abstract class LayerNode : StructureNode, IReadOnlyLayerNode, IClipSource
 
 
         if (useFilters && Filters.Value != null)
         if (useFilters && Filters.Value != null)
         {
         {
-            blendPaint.SetFilters(Filters.Value);
+            Filters.Value.Apply(workingSurface);
             DrawWithFilters(ctx, workingSurface, blendPaint);
             DrawWithFilters(ctx, workingSurface, blendPaint);
         }
         }
         else
         else
         {
         {
-            blendPaint.SetFilters(null);
             DrawWithoutFilters(ctx, workingSurface, blendPaint);
             DrawWithoutFilters(ctx, workingSurface, blendPaint);
         }
         }
     }
     }

+ 0 - 13
src/PixiEditor.ChangeableDocument/Helpers/PaintHelper.cs

@@ -1,13 +0,0 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph;
-using Drawie.Backend.Core.Surfaces.PaintImpl;
-
-namespace PixiEditor.ChangeableDocument.Helpers;
-
-internal static class PaintHelper
-{
-    public static void SetFilters(this Paint paint, Filter? filter)
-    {
-        paint.ColorFilter = filter?.ColorFilter;
-        paint.ImageFilter = filter?.ImageFilter;
-    }
-}

+ 2 - 1
src/PixiEditor.ChangeableDocument/Rendering/RenderContext.cs

@@ -1,6 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Animations;
 using PixiEditor.ChangeableDocument.Changeables.Animations;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Numerics;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
 using DrawingApiBlendMode = Drawie.Backend.Core.Surfaces.BlendMode;
 using DrawingApiBlendMode = Drawie.Backend.Core.Surfaces.BlendMode;
 
 
@@ -16,7 +17,7 @@ public class RenderContext
     
     
     public DrawingSurface RenderSurface { get; set; }
     public DrawingSurface RenderSurface { get; set; }
     public bool FullRerender { get; set; } = false;
     public bool FullRerender { get; set; } = false;
-
+    public Filter? Filter { get; set; }
 
 
     public RenderContext(DrawingSurface renderSurface, KeyFrameTime frameTime, ChunkResolution chunkResolution,
     public RenderContext(DrawingSurface renderSurface, KeyFrameTime frameTime, ChunkResolution chunkResolution,
         VecI docSize, double opacity = 1) 
         VecI docSize, double opacity = 1) 

+ 5 - 1
src/PixiEditor/ViewModels/Nodes/NodePropertyViewModel.cs

@@ -36,8 +36,12 @@ internal abstract class NodePropertyViewModel : ViewModelBase, INodePropertyHand
         get => _value;
         get => _value;
         set
         set
         {
         {
+            var oldValue = _value;
             ViewModelMain.Current.NodeGraphManager.UpdatePropertyValue((node, PropertyName, value));
             ViewModelMain.Current.NodeGraphManager.UpdatePropertyValue((node, PropertyName, value));
-            //ValueChanged?.Invoke(this, new NodePropertyValueChangedArgs(oldValue, value));
+            if(SetProperty(ref _value, value))
+            {
+                ValueChanged?.Invoke(this, new NodePropertyValueChangedArgs(oldValue, value));
+            }
         }
         }
     }
     }