Przeglądaj źródła

Something something fixes

flabbet 11 miesięcy temu
rodzic
commit
1bcc639cbe

+ 4 - 4
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ModifyImageLeftNode.cs

@@ -14,7 +14,7 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 [PairNode(typeof(ModifyImageRightNode), "ModifyImageZone", true)]
 public class ModifyImageLeftNode : Node
 {
-    public InputProperty<Surface?> Image { get; }
+    public InputProperty<Texture?> Image { get; }
     
     public FuncOutputProperty<VecD> Coordinate { get; }
     
@@ -26,7 +26,7 @@ public class ModifyImageLeftNode : Node
 
     public ModifyImageLeftNode()
     {
-        Image = CreateInput<Surface>(nameof(Surface), "IMAGE", null);
+        Image = CreateInput<Texture>(nameof(Surface), "IMAGE", null);
         Coordinate = CreateFuncOutput(nameof(Coordinate), "UV", ctx => ctx.Position);
         Color = CreateFuncOutput(nameof(Color), "COLOR", GetColor);
     }
@@ -48,7 +48,7 @@ public class ModifyImageLeftNode : Node
 
     internal void PreparePixmap(RenderingContext forContext)
     {
-        pixmapCache[forContext] = Image.Value?.DrawingSurface.Snapshot().PeekPixels();
+        pixmapCache[forContext] = Image.Value?.Surface.Snapshot().PeekPixels();
     }
     
     internal void DisposePixmap(RenderingContext forContext)
@@ -59,7 +59,7 @@ public class ModifyImageLeftNode : Node
         }
     }
 
-    protected override Surface? OnExecute(RenderingContext context)
+    protected override Texture? OnExecute(RenderingContext context)
     {
         return Image.Value;
     }

+ 6 - 6
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ModifyImageRightNode.cs

@@ -22,20 +22,20 @@ public class ModifyImageRightNode : Node, IPairNodeEnd
     public FuncInputProperty<VecD> Coordinate { get; }
     public FuncInputProperty<Color> Color { get; }
 
-    public OutputProperty<Surface> Output { get; }
+    public OutputProperty<Texture> Output { get; }
 
     public override string DisplayName { get; set; } = "MODIFY_IMAGE_RIGHT_NODE";
 
-    private Surface surface;
+    private Texture surface;
 
     public ModifyImageRightNode()
     {
         Coordinate = CreateFuncInput(nameof(Coordinate), "UV", new VecD());
         Color = CreateFuncInput(nameof(Color), "COLOR", new Color());
-        Output = CreateOutput<Surface>(nameof(Output), "OUTPUT", null);
+        Output = CreateOutput<Texture>(nameof(Output), "OUTPUT", null);
     }
 
-    protected override Surface? OnExecute(RenderingContext renderingContext)
+    protected override Texture? OnExecute(RenderingContext renderingContext)
     {
         if (StartNode == null)
         {
@@ -55,11 +55,11 @@ public class ModifyImageRightNode : Node, IPairNodeEnd
         var width = size.X;
         var height = size.Y;
         
-        surface = new Surface(size);
+        surface = new Texture(size);
 
         startNode.PreparePixmap(renderingContext);
         
-        using Pixmap targetPixmap = surface.PeekPixels();
+        using Pixmap targetPixmap = surface.Surface.PeekPixels();
 
         ModifyImageInParallel(renderingContext, targetPixmap, width, height);
         

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

@@ -42,7 +42,7 @@ public class SampleImageNode : Node
 
     internal void PreparePixmap()
     {
-        pixmap = Image.Value?.PeekReadOnlyPixels();
+        pixmap = Image.Value?.Surface.PeekPixels();
     }
 
     protected override Texture? OnExecute(RenderingContext context)

+ 22 - 16
src/PixiEditor.ChangeableDocument/Rendering/DocumentRenderer.cs

@@ -17,6 +17,12 @@ public class DocumentRenderer
 
     private IReadOnlyDocument Document { get; }
 
+    public Texture RenderFull(KeyFrameTime frameTime, ChunkResolution resolution)
+    {
+        RenderingContext context = new(frameTime, VecI.Zero, resolution, Document.Size);
+        return Document.NodeGraph.Execute(context);
+    }
+
     public OneOf<Chunk, EmptyChunk> RenderChunk(VecI chunkPos, ChunkResolution resolution, KeyFrameTime frameTime,
         RectI? globalClippingRect = null)
     {
@@ -25,7 +31,7 @@ public class DocumentRenderer
         {
             RectI? transformedClippingRect = TransformClipRect(globalClippingRect, resolution, chunkPos);
 
-            Surface? evaluated = Document.NodeGraph.Execute(context);
+            Texture? evaluated = Document.NodeGraph.Execute(context);
             if (evaluated is null)
             {
                 return new EmptyChunk();
@@ -33,12 +39,12 @@ public class DocumentRenderer
 
             Chunk chunk = Chunk.Create(resolution);
 
-            chunk.Surface.DrawingSurface.Canvas.Save();
-            chunk.Surface.DrawingSurface.Canvas.Clear();
+            chunk.Surface.Surface.Canvas.Save();
+            chunk.Surface.Surface.Canvas.Clear();
 
             if (transformedClippingRect is not null)
             {
-                chunk.Surface.DrawingSurface.Canvas.ClipRect((RectD)transformedClippingRect);
+                chunk.Surface.Surface.Canvas.ClipRect((RectD)transformedClippingRect);
             }
 
             VecD pos = chunkPos;
@@ -59,13 +65,13 @@ public class DocumentRenderer
                 return new EmptyChunk();
             }
 
-            using var chunkSnapshot = evaluated.DrawingSurface.Snapshot((RectI)sourceRect);
+            using var chunkSnapshot = evaluated.Surface.Snapshot((RectI)sourceRect);
             
             if(context.IsDisposed) return new EmptyChunk();
 
-            chunk.Surface.DrawingSurface.Canvas.DrawImage(chunkSnapshot, 0, 0, context.ReplacingPaintWithOpacity);
+            chunk.Surface.Surface.Canvas.DrawImage(chunkSnapshot, 0, 0, context.ReplacingPaintWithOpacity);
 
-            chunk.Surface.DrawingSurface.Canvas.Restore();
+            chunk.Surface.Surface.Canvas.Restore();
 
             return chunk;
         }
@@ -87,7 +93,7 @@ public class DocumentRenderer
         {
             RectI? transformedClippingRect = TransformClipRect(globalClippingRect, resolution, chunkPos);
 
-            Surface? evaluated = node.Execute(context);
+            Texture? evaluated = node.Execute(context);
             if (evaluated is null)
             {
                 return new EmptyChunk();
@@ -118,7 +124,7 @@ public class DocumentRenderer
         NodeGraph membersOnlyGraph = ConstructMembersOnlyGraph(layersToCombine, Document.NodeGraph);
         try
         {
-            Surface? evaluated = membersOnlyGraph.Execute(context);
+            Texture? evaluated = membersOnlyGraph.Execute(context);
             if (evaluated is null)
             {
                 return new EmptyChunk();
@@ -153,7 +159,7 @@ public class DocumentRenderer
             }
         });
 
-        IInputProperty<Surface> lastInput = outputNode.Input;
+        IInputProperty<Texture> lastInput = outputNode.Input;
 
         foreach (var layer in layersInOrder)
         {
@@ -168,28 +174,28 @@ public class DocumentRenderer
     }
 
     private static OneOf<Chunk, EmptyChunk> ChunkFromResult(ChunkResolution resolution,
-        RectI? transformedClippingRect, Surface evaluated,
+        RectI? transformedClippingRect, Texture evaluated,
         RenderingContext context)
     {
         Chunk chunk = Chunk.Create(resolution);
 
-        chunk.Surface.DrawingSurface.Canvas.Save();
-        chunk.Surface.DrawingSurface.Canvas.Clear();
+        chunk.Surface.Surface.Canvas.Save();
+        chunk.Surface.Surface.Canvas.Clear();
 
         int x = 0;
         int y = 0;
 
         if (transformedClippingRect is not null)
         {
-            chunk.Surface.DrawingSurface.Canvas.ClipRect((RectD)transformedClippingRect);
+            chunk.Surface.Surface.Canvas.ClipRect((RectD)transformedClippingRect);
             x = transformedClippingRect.Value.X;
             y = transformedClippingRect.Value.Y;
         }
 
-        chunk.Surface.DrawingSurface.Canvas.DrawSurface(evaluated.DrawingSurface, x, y,
+        chunk.Surface.Surface.Canvas.DrawSurface(evaluated.Surface, x, y,
             context.ReplacingPaintWithOpacity);
 
-        chunk.Surface.DrawingSurface.Canvas.Restore();
+        chunk.Surface.Surface.Canvas.Restore();
 
         return chunk;
     }

+ 63 - 4
src/PixiEditor.DrawingApi.Core/Texture.cs

@@ -20,6 +20,9 @@ public class Texture : IDisposable
     private bool pixmapUpToDate;
     private Pixmap pixmap;
 
+    private Paint nearestNeighborReplacingPaint =
+        new() { BlendMode = BlendMode.Src, FilterQuality = FilterQuality.None };
+
     public Texture(VecI size)
     {
         Size = size;
@@ -33,15 +36,20 @@ public class Texture : IDisposable
         Surface.Changed += SurfaceOnChanged;
     }
 
+    public Texture(Texture other) : this(other.Size)
+    {
+        Surface.Canvas.DrawSurface(other.Surface, 0, 0);
+    }
+
     internal Texture(DrawingSurface surface)
     {
         Surface = surface;
         Surface.Changed += SurfaceOnChanged;
     }
-    
+
     ~Texture()
     {
-       Surface.Changed -= SurfaceOnChanged;
+        Surface.Changed -= SurfaceOnChanged;
     }
 
     private void SurfaceOnChanged(RectD? changedRect)
@@ -106,10 +114,61 @@ public class Texture : IDisposable
         return newTexture;
     }
 
-    public Color? GetSRGBPixel(VecI vecI)
+    public Pixmap? PeekReadOnlyPixels()
+    {
+        if (pixmapUpToDate)
+        {
+            return pixmap;
+        }
+
+        pixmap = Surface.PeekPixels();
+        pixmapUpToDate = true;
+
+        return pixmap;
+    }
+
+    public void CopyTo(Texture destination)
+    {
+        destination.Surface.Canvas.DrawSurface(Surface, 0, 0);
+    }
+
+    public unsafe bool IsFullyTransparent()
+    {
+        ulong* ptr = (ulong*)PeekReadOnlyPixels().GetPixels();
+        for (int i = 0; i < Size.X * Size.Y; i++)
+        {
+            // ptr[i] actually contains 4 16-bit floats. We only care about the first one which is alpha.
+            // An empty pixel can have alpha of 0 or -0 (not sure if -0 actually ever comes up). 0 in hex is 0x0, -0 in hex is 0x8000
+            if ((ptr[i] & 0x1111_0000_0000_0000) != 0 && (ptr[i] & 0x1111_0000_0000_0000) != 0x8000_0000_0000_0000)
+                return false;
+        }
+
+        return true;
+    }
+
+    public void DrawBytes(VecI surfaceSize, byte[] pixels, ColorType color, AlphaType alphaType)
+    {
+        if (surfaceSize != Size)
+            throw new ArgumentException("Surface size must match the size of the byte array");
+
+        using Image image = Image.FromPixels(new ImageInfo(Size.X, Size.Y, color, alphaType, ColorSpace.CreateSrgb()),
+            pixels);
+        Surface.Canvas.DrawImage(image, 0, 0);
+    }
+
+    public Texture ResizeNearestNeighbor(VecI newSize)
+    {
+        using Image image = Surface.Snapshot();
+        Texture newSurface = new(newSize);
+        newSurface.Surface.Canvas.DrawImage(image, new RectD(0, 0, newSize.X, newSize.Y),
+            nearestNeighborReplacingPaint);
+        return newSurface;
+    }
+
+    public Color GetSRGBPixel(VecI vecI)
     {
         if (vecI.X < 0 || vecI.X >= Size.X || vecI.Y < 0 || vecI.Y >= Size.Y)
-            return null;
+            return Color.Empty;
 
         if (!pixmapUpToDate)
         {

+ 2 - 2
src/PixiEditor/Models/DocumentModels/ActionAccumulator.cs

@@ -41,7 +41,7 @@ internal class ActionAccumulator
 
     private void SceneOnPaint(Texture obj)
     {
-        canvasUpdater.Render(obj, ChunkResolution.Full); 
+        canvasUpdater.RenderFull(obj, ChunkResolution.Full); 
     }
 
     public void AddFinishedActions(params IAction[] actions)
@@ -101,7 +101,7 @@ internal class ActionAccumulator
             var affectedAreas = new AffectedAreasGatherer(document.AnimationHandler.ActiveFrameTime, internals.Tracker, optimizedChanges);
             List<IRenderInfo> renderResult = new();
             //await canvasUpdater.UpdateGatheredChunks(affectedAreas, undoBoundaryPassed || viewportRefreshRequest);
-            renderResult.AddRange(await previewUpdater.UpdateGatheredChunks(affectedAreas, undoBoundaryPassed));
+            //renderResult.AddRange(await previewUpdater.UpdateGatheredChunks(affectedAreas, undoBoundaryPassed));
 
             if (undoBoundaryPassed)
             {

+ 12 - 2
src/PixiEditor/Models/Rendering/CanvasUpdater.cs

@@ -249,6 +249,16 @@ internal class CanvasUpdater
         }
     }
 
+    public void RenderFull(Texture screenSurface, ChunkResolution resolution)
+    {
+        var texture = doc.Renderer.RenderFull(doc.AnimationHandler.ActiveFrameTime, resolution);
+        
+        if (texture is null)
+            return;
+        
+        screenSurface.Surface.Canvas.DrawSurface(texture.Surface, 0, 0);
+    }
+
     private void RenderChunk(VecI chunkPos, Texture screenSurface, ChunkResolution resolution,
         RectI? globalClippingRectangle, RectI? globalScaledClippingRectangle)
     {
@@ -266,9 +276,9 @@ internal class CanvasUpdater
                         screenSurface.Surface.Canvas.Save();
                         screenSurface.Surface.Canvas.ClipRect((RectD)globalScaledClippingRectangle);
                     }
-
+                    
                     screenSurface.Surface.Canvas.DrawSurface(
-                        chunk.Surface.DrawingSurface,
+                        chunk.Surface.Surface,
                         chunkPos.Multiply(chunk.PixelSize), ReplacingPaint);
                     chunk.Dispose();