Browse Source

Fix the preview layer

Equbuxu 3 years ago
parent
commit
c1d445b9d5

+ 9 - 8
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -159,7 +159,7 @@ namespace PixiEditor.Models.Controllers
 
 
         public void SetActiveTool(Tool tool)
         public void SetActiveTool(Tool tool)
         {
         {
-            ActiveDocument?.PreviewLayer?.Clear();
+            ActiveDocument?.PreviewLayer?.Reset();
             SelectedTool?.Toolbar.SaveToolbarSettings();
             SelectedTool?.Toolbar.SaveToolbarSettings();
             SelectedTool = tool;
             SelectedTool = tool;
             SelectedTool.Toolbar.LoadSharedSettings();
             SelectedTool.Toolbar.LoadSharedSettings();
@@ -213,7 +213,7 @@ namespace PixiEditor.Models.Controllers
             SelectedTool.OnRecordingLeftMouseDown(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
             SelectedTool.OnRecordingLeftMouseDown(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
             if (ActiveDocument != null)
             if (ActiveDocument != null)
             {
             {
-                ActiveDocument.PreviewLayer.Clear();
+                ActiveDocument.PreviewLayer.Reset();
             }
             }
         }
         }
 
 
@@ -235,18 +235,19 @@ namespace PixiEditor.Models.Controllers
                 return;
                 return;
             }
             }
 
 
-            if (ToolSize != previewLayerSize || ActiveDocument.PreviewLayer.IsCleared)
+            if (ToolSize != previewLayerSize || ActiveDocument.PreviewLayer.IsReset)
             {
             {
-                cachedHighlight = CoordinatesCalculator.RectangleToCoordinates(
-                    CoordinatesCalculator.CalculateThicknessCenter(newPosition, ToolSize));
+
+                cachedHighlight = CoordinatesCalculator.RectangleToCoordinates(0, 0, ToolSize - 1, ToolSize - 1);
+                var center = CoordinatesCalculator.CalculateThicknessCenter(newPosition, ToolSize);
 
 
                 previewLayerSize = ToolSize;
                 previewLayerSize = ToolSize;
                 halfSize = (int)Math.Floor(ToolSize / 2f);
                 halfSize = (int)Math.Floor(ToolSize / 2f);
 
 
                 cachedPixels = BitmapPixelChanges.FromSingleColoredArray(cachedHighlight, new SKColor(0, 0, 0, 77));
                 cachedPixels = BitmapPixelChanges.FromSingleColoredArray(cachedHighlight, new SKColor(0, 0, 0, 77));
 
 
-                if (!ActiveDocument.PreviewLayer.IsCleared)
-                    ActiveDocument.PreviewLayer.Clear();
+                if (!ActiveDocument.PreviewLayer.IsReset)
+                    ActiveDocument.PreviewLayer.Reset();
                 ActiveDocument.PreviewLayer.SetPixels(cachedPixels);
                 ActiveDocument.PreviewLayer.SetPixels(cachedPixels);
             }
             }
 
 
@@ -255,7 +256,7 @@ namespace PixiEditor.Models.Controllers
 
 
             if (!IsInsideBounds(cachedHighlight))
             if (!IsInsideBounds(cachedHighlight))
             {
             {
-                ActiveDocument.PreviewLayer.Clear();
+                ActiveDocument.PreviewLayer.Reset();
                 previewLayerSize = -1;
                 previewLayerSize = -1;
             }
             }
         }
         }

+ 18 - 4
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -6,12 +6,15 @@ using PixiEditor.Models.Tools.ToolSettings.Settings;
 using SkiaSharp;
 using SkiaSharp;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
 
 
 namespace PixiEditor.Models.Controllers
 namespace PixiEditor.Models.Controllers
 {
 {
     public class BitmapOperationsUtility
     public class BitmapOperationsUtility
     {
     {
+        private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
+
         private Coordinates lastMousePos;
         private Coordinates lastMousePos;
 
 
         private SizeSetting sizeSetting;
         private SizeSetting sizeSetting;
@@ -74,8 +77,20 @@ namespace PixiEditor.Models.Controllers
         /// </summary>
         /// </summary>
         public void ApplyPreviewLayer()
         public void ApplyPreviewLayer()
         {
         {
+            var previewLayer = Manager.ActiveDocument.PreviewLayer;
+            var activeLayer = Manager.ActiveLayer;
+
+            activeLayer.DynamicResizeAbsolute(previewLayer.OffsetX + previewLayer.Width, previewLayer.OffsetY + previewLayer.Height, previewLayer.OffsetX, previewLayer.OffsetY);
+            previewLayer.LayerBitmap.SkiaSurface.Draw(
+                    activeLayer.LayerBitmap.SkiaSurface.Canvas,
+                    previewLayer.OffsetX,
+                    previewLayer.OffsetY,
+                    BlendingPaint
+                );
+            Manager.ActiveLayer.InvokeLayerBitmapChange(new Int32Rect(previewLayer.OffsetX, previewLayer.OffsetY, previewLayer.Width, previewLayer.Height));
             // Don't forget about firing BitmapChanged
             // Don't forget about firing BitmapChanged
-            Manager.ActiveDocument.GeneratePreviewLayer();
+            BitmapChanged?.Invoke(this, null);
+            Manager.ActiveDocument.PreviewLayer.Reset();
         }
         }
 
 
         private void UseTool(List<Coordinates> mouseMoveCords, BitmapOperationTool tool, SKColor color)
         private void UseTool(List<Coordinates> mouseMoveCords, BitmapOperationTool tool, SKColor color)
@@ -183,12 +198,11 @@ namespace PixiEditor.Models.Controllers
             {
             {
                 if (clearPreviewLayer)
                 if (clearPreviewLayer)
                 {
                 {
-                    Manager.ActiveDocument.PreviewLayer.Clear();
+                    Manager.ActiveDocument.PreviewLayer.ClearCanvas();
                 }
                 }
 
 
-                // TODO: Use on preview layer
                 ((BitmapOperationTool)Manager.SelectedTool).Use(
                 ((BitmapOperationTool)Manager.SelectedTool).Use(
-                    Manager.ActiveDocument.ActiveLayer,
+                    Manager.ActiveDocument.PreviewLayer,
                     mouseMove,
                     mouseMove,
                     Manager.PrimaryColor);
                     Manager.PrimaryColor);
             }
             }

+ 0 - 2
PixiEditor/Models/Controllers/LayerStackRenderer.cs

@@ -93,8 +93,6 @@ namespace PixiEditor.Models.Controllers
 
 
         private void Update(Int32Rect dirtyRectangle)
         private void Update(Int32Rect dirtyRectangle)
         {
         {
-            //finalSurface.SkiaSurface.Canvas.Clear();
-
             dirtyRectangle = dirtyRectangle.Intersect(new Int32Rect(0, 0, finalBitmap.PixelWidth, finalBitmap.PixelHeight));
             dirtyRectangle = dirtyRectangle.Intersect(new Int32Rect(0, 0, finalBitmap.PixelWidth, finalBitmap.PixelHeight));
             finalSurface.SkiaSurface.Canvas.DrawRect(
             finalSurface.SkiaSurface.Canvas.DrawRect(
                 new SKRect(
                 new SKRect(

+ 30 - 7
PixiEditor/Models/Controllers/SingleLayerRenderer.cs

@@ -12,6 +12,7 @@ namespace PixiEditor.Models.Controllers
     public class SingleLayerRenderer : INotifyPropertyChanged, IDisposable
     public class SingleLayerRenderer : INotifyPropertyChanged, IDisposable
     {
     {
         private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
         private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
+        private SKPaint ClearPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.Src, Color = SKColors.Transparent };
         private Layer layer;
         private Layer layer;
 
 
         private SKSurface backingSurface;
         private SKSurface backingSurface;
@@ -53,18 +54,40 @@ namespace PixiEditor.Models.Controllers
 
 
         private void Update(Int32Rect dirtyRectangle)
         private void Update(Int32Rect dirtyRectangle)
         {
         {
-            backingSurface.Canvas.Clear();
+            dirtyRectangle = dirtyRectangle.Intersect(new Int32Rect(0, 0, finalBitmap.PixelWidth, finalBitmap.PixelHeight));
+            if (!dirtyRectangle.HasArea)
+                return;
+            backingSurface.Canvas.DrawRect(
+                new SKRect(
+                    dirtyRectangle.X, dirtyRectangle.Y,
+                    dirtyRectangle.X + dirtyRectangle.Width,
+                    dirtyRectangle.Y + dirtyRectangle.Height
+                    ),
+                ClearPaint
+                );
             finalBitmap.Lock();
             finalBitmap.Lock();
             if (layer.IsVisible)
             if (layer.IsVisible)
             {
             {
                 BlendingPaint.Color = new SKColor(255, 255, 255, (byte)(layer.Opacity * 255));
                 BlendingPaint.Color = new SKColor(255, 255, 255, (byte)(layer.Opacity * 255));
-                layer.LayerBitmap.SkiaSurface.Draw(
-                    backingSurface.Canvas,
-                    layer.OffsetX,
-                    layer.OffsetY,
-                    BlendingPaint);
+                var layerDirty = dirtyRectangle.Intersect(new Int32Rect(layer.OffsetX, layer.OffsetY, layer.Width, layer.Height));
+                using (var snapshot = layer.LayerBitmap.SkiaSurface.Snapshot())
+                {
+                    backingSurface.Canvas.DrawImage(
+                        snapshot,
+                        new SKRect(
+                            layerDirty.X - layer.OffsetX,
+                            layerDirty.Y - layer.OffsetY,
+                            layerDirty.X - layer.OffsetX + layerDirty.Width,
+                            layerDirty.Y - layer.OffsetY + layerDirty.Height),
+                        new SKRect(
+                            layerDirty.X,
+                            layerDirty.Y,
+                            layerDirty.X + layerDirty.Width,
+                            layerDirty.Y + layerDirty.Height
+                        ),
+                        BlendingPaint);
+                }
             }
             }
-            dirtyRectangle = dirtyRectangle.Intersect(new Int32Rect(0, 0, finalBitmap.PixelWidth, finalBitmap.PixelHeight));
 
 
             finalBitmap.AddDirtyRect(dirtyRectangle);
             finalBitmap.AddDirtyRect(dirtyRectangle);
             finalBitmap.Unlock();
             finalBitmap.Unlock();

+ 2 - 2
PixiEditor/Models/DataHolders/Selection.cs

@@ -42,7 +42,7 @@ namespace PixiEditor.Models.DataHolders
             {
             {
                 case SelectionType.New:
                 case SelectionType.New:
                     SelectedPoints = new ObservableCollection<Coordinates>(selection);
                     SelectedPoints = new ObservableCollection<Coordinates>(selection);
-                    SelectionLayer.Clear();
+                    SelectionLayer.Reset();
                     break;
                     break;
                 case SelectionType.Add:
                 case SelectionType.Add:
                     SelectedPoints = new ObservableCollection<Coordinates>(SelectedPoints.Concat(selection).Distinct());
                     SelectedPoints = new ObservableCollection<Coordinates>(SelectedPoints.Concat(selection).Distinct());
@@ -58,7 +58,7 @@ namespace PixiEditor.Models.DataHolders
 
 
         public void Clear()
         public void Clear()
         {
         {
-            SelectionLayer.Clear();
+            SelectionLayer.Reset();
             SelectedPoints.Clear();
             SelectedPoints.Clear();
         }
         }
     }
     }

+ 26 - 16
PixiEditor/Models/Layers/Layer.cs

@@ -1,4 +1,5 @@
-using PixiEditor.Models.DataHolders;
+using PixiEditor.Helpers.Extensions;
+using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Undo;
 using PixiEditor.Models.Undo;
 using PixiEditor.ViewModels;
 using PixiEditor.ViewModels;
@@ -36,7 +37,7 @@ namespace PixiEditor.Models.Layers
         {
         {
             Name = name;
             Name = name;
             LayerBitmap = new Surface(1, 1);
             LayerBitmap = new Surface(1, 1);
-            IsCleared = true;
+            IsReset = true;
             Width = 1;
             Width = 1;
             Height = 1;
             Height = 1;
             LayerGuid = Guid.NewGuid();
             LayerGuid = Guid.NewGuid();
@@ -46,7 +47,7 @@ namespace PixiEditor.Models.Layers
         {
         {
             Name = name;
             Name = name;
             LayerBitmap = new Surface(width, height);
             LayerBitmap = new Surface(width, height);
-            IsCleared = true;
+            IsReset = true;
             Width = width;
             Width = width;
             Height = height;
             Height = height;
             LayerGuid = Guid.NewGuid();
             LayerGuid = Guid.NewGuid();
@@ -143,9 +144,13 @@ namespace PixiEditor.Models.Layers
             get => layerBitmap;
             get => layerBitmap;
             private set
             private set
             {
             {
+                Int32Rect prevRect = new Int32Rect(OffsetX, OffsetY, Width, Height);
                 layerBitmap = value;
                 layerBitmap = value;
+                Width = layerBitmap.Width;
+                Height = layerBitmap.Height;
+                Int32Rect curRect = new Int32Rect(OffsetX, OffsetY, Width, Height);
                 RaisePropertyChanged(nameof(LayerBitmap));
                 RaisePropertyChanged(nameof(LayerBitmap));
-                InvokeLayerBitmapChange();
+                InvokeLayerBitmapChange(prevRect.Expand(curRect));
             }
             }
         }
         }
 
 
@@ -191,9 +196,11 @@ namespace PixiEditor.Models.Layers
             get => offset;
             get => offset;
             set
             set
             {
             {
+                Int32Rect prevRect = new Int32Rect(OffsetX, OffsetY, Width, Height);
                 offset = value;
                 offset = value;
-                RaisePropertyChanged("Offset");
-                InvokeLayerBitmapChange();
+                Int32Rect curRect = new Int32Rect(OffsetX, OffsetY, Width, Height);
+                RaisePropertyChanged(nameof(Offset));
+                InvokeLayerBitmapChange(prevRect.Expand(curRect));
             }
             }
         }
         }
 
 
@@ -201,19 +208,19 @@ namespace PixiEditor.Models.Layers
 
 
         public int MaxHeight { get; set; } = int.MaxValue;
         public int MaxHeight { get; set; } = int.MaxValue;
 
 
-        public bool IsCleared { get; private set; }
+        public bool IsReset { get; private set; }
 
 
         public event EventHandler<Int32Rect> LayerBitmapChanged;
         public event EventHandler<Int32Rect> LayerBitmapChanged;
 
 
         public void InvokeLayerBitmapChange()
         public void InvokeLayerBitmapChange()
         {
         {
-            IsCleared = false;
+            IsReset = false;
             LayerBitmapChanged?.Invoke(this, new Int32Rect(OffsetX, OffsetY, Width, Height));
             LayerBitmapChanged?.Invoke(this, new Int32Rect(OffsetX, OffsetY, Width, Height));
         }
         }
 
 
         public void InvokeLayerBitmapChange(Int32Rect dirtyArea)
         public void InvokeLayerBitmapChange(Int32Rect dirtyArea)
         {
         {
-            IsCleared = false;
+            IsReset = false;
             LayerBitmapChanged?.Invoke(this, dirtyArea);
             LayerBitmapChanged?.Invoke(this, dirtyArea);
         }
         }
 
 
@@ -432,7 +439,7 @@ namespace PixiEditor.Models.Layers
             if (newMaxX >= MaxWidth) newMaxX = MaxWidth - 1;
             if (newMaxX >= MaxWidth) newMaxX = MaxWidth - 1;
             if (newMaxY >= MaxHeight) newMaxY = MaxHeight - 1;
             if (newMaxY >= MaxHeight) newMaxY = MaxHeight - 1;
 
 
-            if (IsCleared)
+            if (IsReset)
             {
             {
                 Offset = new Thickness(newMinX, newMinY, 0, 0);
                 Offset = new Thickness(newMinX, newMinY, 0, 0);
             }
             }
@@ -482,12 +489,9 @@ namespace PixiEditor.Models.Layers
             Offset = new Thickness(OffsetX + smallestX, OffsetY + smallestY, 0, 0);
             Offset = new Thickness(OffsetX + smallestX, OffsetY + smallestY, 0, 0);
         }
         }
 
 
-        /// <summary>
-        ///     Clears bitmap.
-        /// </summary>
-        public void Clear()
+        public void Reset()
         {
         {
-            if (IsCleared)
+            if (IsReset)
                 return;
                 return;
             var dirtyRect = new Int32Rect(OffsetX, OffsetY, Width, Height);
             var dirtyRect = new Int32Rect(OffsetX, OffsetY, Width, Height);
             LayerBitmap?.Dispose();
             LayerBitmap?.Dispose();
@@ -495,10 +499,16 @@ namespace PixiEditor.Models.Layers
             Width = 1;
             Width = 1;
             Height = 1;
             Height = 1;
             Offset = new Thickness(0, 0, 0, 0);
             Offset = new Thickness(0, 0, 0, 0);
-            IsCleared = true;
+            IsReset = true;
             LayerBitmapChanged?.Invoke(this, dirtyRect);
             LayerBitmapChanged?.Invoke(this, dirtyRect);
         }
         }
 
 
+        public void ClearCanvas()
+        {
+            LayerBitmap.SkiaSurface.Canvas.Clear();
+            InvokeLayerBitmapChange();
+        }
+
         /// <summary>
         /// <summary>
         ///     Converts layer WriteableBitmap to byte array.
         ///     Converts layer WriteableBitmap to byte array.
         /// </summary>
         /// </summary>

+ 1 - 1
PixiEditor/ViewModels/ViewModelMain.cs

@@ -238,7 +238,7 @@ namespace PixiEditor.ViewModels
         {
         {
             foreach (var document in BitmapManager.Documents)
             foreach (var document in BitmapManager.Documents)
             {
             {
-                document.PreviewLayer.Clear();
+                document.PreviewLayer.Reset();
             }
             }
         }
         }