Browse Source

Added outline node and disabled previews

Krzysztof Krysiński 5 months ago
parent
commit
b2cb47ac6b

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 306b9f1b786af58a147166436eb521979f71f18a
+Subproject commit 82cec52a169a9a712bab5fb00f9c210afa6b2fc6

+ 114 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Effects/OutlineNode.cs

@@ -0,0 +1,114 @@
+using Drawie.Backend.Core;
+using Drawie.Backend.Core.ColorsImpl;
+using Drawie.Backend.Core.Shaders;
+using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Rendering;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Effects;
+
+[NodeInfo("Outline")]
+public class OutlineNode : RenderNode, IRenderInput, ICustomShaderNode
+{
+    public RenderInputProperty Background { get; }
+    public InputProperty<OutlineType> Type { get; }
+    public InputProperty<double> Thickness { get; }
+    public InputProperty<Color> Color { get; }
+
+    private Kernel simpleKernel = new Kernel(3, 3, [1, 1, 1, 1, 1, 1, 1, 1, 1]);
+    private Kernel pixelPerfectKernel = new Kernel(3, 3, [0, 1, 0, 1, -4, 1, 0, 1, 0]);
+    private Kernel gaussianKernel = new Kernel(5, 5, [
+        1, 4, 6, 4, 1,
+        4, 16, 24, 16, 4,
+        6, 24, 36, 24, 6,
+        4, 16, 24, 16, 4,
+        1, 4, 6, 4, 1
+    ]);
+
+    private Paint paint;
+    private ImageFilter filter;
+
+    private OutlineType lastType;
+
+    public OutlineNode()
+    {
+        Background = CreateRenderInput("Background", "BACKGROUND");
+        Type = CreateInput("Type", "TYPE", OutlineType.Simple);
+        Thickness = CreateInput("Thickness", "THICKNESS", 1.0);
+        Color = CreateInput("Color", "COLOR", Colors.Black);
+
+        paint = new Paint();
+
+        Output.FirstInChain = null;
+    }
+
+    protected override void OnExecute(RenderContext context)
+    {
+        base.OnExecute(context);
+        Kernel finalKernel = Type.Value switch
+        {
+            OutlineType.Simple => simpleKernel,
+            OutlineType.Gaussian => gaussianKernel,
+            OutlineType.PixelPerfect => pixelPerfectKernel,
+            _ => simpleKernel
+        };
+
+        VecI offset = new VecI(finalKernel.RadiusX, finalKernel.RadiusY);
+        double gain = 1.0 / finalKernel.Sum;
+
+        filter?.Dispose();
+        filter = ImageFilter.CreateMatrixConvolution(finalKernel, (float)gain, 0, offset, TileMode.Clamp, true);
+    }
+
+    protected override void OnPaint(RenderContext context, DrawingSurface surface)
+    {
+        if (Background.Value == null)
+        {
+            return;
+        }
+
+        paint.ImageFilter = filter;
+        paint.ColorFilter = ColorFilter.CreateBlendMode(Color.Value, BlendMode.SrcIn);
+
+        int saved = surface.Canvas.SaveLayer(paint);
+
+        Background.Value.Paint(context, surface);
+
+        surface.Canvas.RestoreToCount(saved);
+
+        for (int i = 1; i < (int)Thickness.Value; i++)
+        {
+            saved = surface.Canvas.SaveLayer(paint);
+
+            surface.Canvas.DrawSurface(surface, 0, 0);
+
+            surface.Canvas.RestoreToCount(saved);
+        }
+
+        Background.Value.Paint(context, surface);
+    }
+
+    public override RectD? GetPreviewBounds(int frame, string elementToRenderName = "")
+    {
+        return null;
+    }
+
+    public override bool RenderPreview(DrawingSurface renderOn, RenderContext context, string elementToRenderName)
+    {
+        return false;
+    }
+
+    public override Node CreateCopy()
+    {
+        return new OutlineNode();
+    }
+}
+
+public enum OutlineType
+{
+    Simple,
+    Gaussian,
+    PixelPerfect,
+}

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

@@ -25,7 +25,7 @@ public class ApplyFilterNode : RenderNode, IRenderInput
 
     protected override void OnPaint(RenderContext context, DrawingSurface surface)
     {
-        if (Background.Value == null)
+        if (Background.Value == null || Filter.Value == null || _paint == null)
             return;
 
         _paint.SetFilters(Filter.Value);

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

@@ -24,6 +24,7 @@ public class KernelFilterNode : FilterNode
     private TileMode lastTile;
     private double lastGain;
     private double lastBias;
+    private bool lastOnAlpha;
 
     private float[] lastKernelValues = new float[9];
 
@@ -40,13 +41,14 @@ public class KernelFilterNode : FilterNode
     {
         var kernel = Kernel.Value;
         
-        if (kernel.AsSpan().SequenceEqual(lastKernelValues) && Tile.Value == lastTile && Gain.Value == lastGain && Bias.Value == lastBias)
+        if (kernel.AsSpan().SequenceEqual(lastKernelValues) && Tile.Value == lastTile && Gain.Value == lastGain && Bias.Value == lastBias && OnAlpha.Value == lastOnAlpha)
             return filter;
         
         lastKernel = kernel;
         lastTile = Tile.Value;
         lastGain = Gain.Value;
         lastBias = Bias.Value;
+        lastOnAlpha = OnAlpha.Value;
         
         filter?.Dispose();
         

+ 3 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -855,5 +855,7 @@
   "TEXT_NODE": "Text",
   "TEXT_LABEL": "Text",
   "TEXT_ON_PATH_NODE": "Text on Path",
-  "HIGH_DPI_RENDERING": "High DPI Rendering"
+  "HIGH_DPI_RENDERING": "High DPI Rendering",
+  "THICKNESS": "Thickness",
+  "TYPE": "Type"
 }

+ 2 - 2
src/PixiEditor/Styles/Templates/NodeView.axaml

@@ -53,7 +53,7 @@
                                 </ItemsControl>
                             </StackPanel>
                         </Border>
-                        <Border IsVisible="{Binding !!ResultPreview, RelativeSource={RelativeSource TemplatedParent}}"
+                        <!--<Border IsVisible="{Binding !!ResultPreview, RelativeSource={RelativeSource TemplatedParent}}"
                                 CornerRadius="0, 0, 4.5, 4.5" Grid.Row="2" ClipToBounds="True">
                             <Panel RenderOptions.BitmapInterpolationMode="None" Width="200" Height="200">
                                 <Panel.Background>
@@ -66,7 +66,7 @@
                                                            RenderOptions.BitmapInterpolationMode="None">
                             </visuals:PreviewPainterControl>
                             </Panel>
-                        </Border>
+                        </Border>-->
                     </Grid>
                 </Border>
             </ControlTemplate>

+ 7 - 0
src/PixiEditor/ViewModels/Document/Nodes/Effects/OutlineNodeViewModel.cs

@@ -0,0 +1,7 @@
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Effects;
+using PixiEditor.ViewModels.Nodes;
+
+namespace PixiEditor.ViewModels.Document.Nodes.Effects;
+
+[NodeViewModel("OUTLINE_NODE", "EFFECTS", "\uE80B")]
+internal class OutlineNodeViewModel : NodeViewModel<OutlineNode>;