Browse Source

Fix clip canvas and resize canvas

Equbuxu 3 years ago
parent
commit
c352fd75d9

+ 10 - 3
PixiEditor/Models/DataHolders/Document/Document.Operations.cs

@@ -7,7 +7,6 @@ using SkiaSharp;
 using System;
 using System.Linq;
 using System.Windows;
-using Windows.Graphics;
 
 namespace PixiEditor.Models.DataHolders
 {
@@ -231,9 +230,19 @@ namespace PixiEditor.Models.DataHolders
             for (int i = 0; i < Layers.Count; i++)
             {
                 Layer layer = Layers[i];
+                Layers[i].MaxWidth = newWidth;
+                Layers[i].MaxHeight = newHeight;
+                if (layer.IsReset)
+                    continue;
+
                 Thickness newOffset = offset[i];
                 Int32Rect newRect = new((int)newOffset.Left, (int)newOffset.Top, layer.Width, layer.Height);
                 Int32Rect newLayerRect = newRect.Intersect(newCanvasRect);
+                if (!newLayerRect.HasArea)
+                {
+                    layer.Reset();
+                    continue;
+                }
                 Surface newBitmap = new(newLayerRect.Width, newLayerRect.Height);
                 var oldBitmap = layer.LayerBitmap;
                 using var snapshot = oldBitmap.SkiaSurface.Snapshot();
@@ -243,8 +252,6 @@ namespace PixiEditor.Models.DataHolders
                 oldBitmap.Dispose();
 
                 Layers[i].Offset = new Thickness(newLayerRect.X, newLayerRect.Y, 0, 0);
-                Layers[i].MaxWidth = newWidth;
-                Layers[i].MaxHeight = newHeight;
             }
 
             Width = newWidth;

+ 68 - 20
PixiEditor/Models/DataHolders/Document/Document.cs

@@ -114,16 +114,19 @@ namespace PixiEditor.Models.DataHolders
         /// </summary>
         public void ClipCanvas()
         {
-            DoubleCoords points = GetEdgePoints(Layers);
-            int smallestX = points.Coords1.X;
-            int smallestY = points.Coords1.Y;
-            int biggestX = points.Coords2.X;
-            int biggestY = points.Coords2.Y;
+            DoubleCoords? maybePoints = GetEdgePoints(Layers);
 
-            if (smallestX == 0 && smallestY == 0 && biggestX == 0 && biggestY == 0)
+            if (maybePoints == null)
             {
+                //all layers are empty
                 return;
             }
+            DoubleCoords points = maybePoints.Value;
+
+            int smallestX = points.Coords1.X;
+            int smallestY = points.Coords1.Y;
+            int biggestX = points.Coords2.X;
+            int biggestY = points.Coords2.Y;
 
             int width = biggestX - smallestX;
             int height = biggestY - smallestY;
@@ -133,15 +136,15 @@ namespace PixiEditor.Models.DataHolders
             int oldWidth = Width;
             int oldHeight = Height;
 
-            MoveOffsets(Layers, moveVector);
+            StorageBasedChange change = new StorageBasedChange(this, Layers);
 
-            object[] reverseArguments = { oldOffsets, oldWidth, oldHeight };
-            object[] processArguments = { Layers.Select(x => x.Offset).ToArray(), width, height };
+            object[] reverseArguments = { oldWidth, oldHeight };
+            object[] processArguments = { Layers.Select(x => new Thickness(x.OffsetX - smallestX, x.OffsetY - smallestY, 0, 0)).ToArray(), width, height };
 
             ResizeCanvasProcess(processArguments);
 
-            UndoManager.AddUndoChange(new Change(
-                ResizeCanvasProcess,
+            UndoManager.AddUndoChange(change.ToChange(
+                RestoreDocumentLayersProcess,
                 reverseArguments,
                 ResizeCanvasProcess,
                 processArguments,
@@ -155,22 +158,18 @@ namespace PixiEditor.Models.DataHolders
         {
             var layersToCenter = Layers.Where(x => x.IsActive && LayerStructureUtils.GetFinalLayerIsVisible(x, LayerStructure));
             if (!layersToCenter.Any())
-            {
                 return;
-            }
 
-            DoubleCoords points = GetEdgePoints(layersToCenter);
+            DoubleCoords? maybePoints = ClipLayersAndGetEdgePoints(layersToCenter);
+            if (maybePoints == null)
+                return;
+            DoubleCoords points = maybePoints.Value;
 
             int smallestX = points.Coords1.X;
             int smallestY = points.Coords1.Y;
             int biggestX = points.Coords2.X;
             int biggestY = points.Coords2.Y;
 
-            if (smallestX == 0 && smallestY == 0 && biggestX == 0 && biggestY == 0)
-            {
-                return;
-            }
-
             Coordinates contentCenter = CoordinatesCalculator.GetCenterPoint(points.Coords1, points.Coords2);
             Coordinates documentCenter = CoordinatesCalculator.GetCenterPoint(
                 new Coordinates(0, 0),
@@ -241,7 +240,47 @@ namespace PixiEditor.Models.DataHolders
             return 0;
         }
 
-        private DoubleCoords GetEdgePoints(IEnumerable<Layer> layers)
+        private DoubleCoords? GetEdgePoints(IEnumerable<Layer> layers)
+        {
+            if (Layers.Count == 0)
+                throw new ArgumentException("Not enough layers");
+
+            int smallestX = int.MaxValue;
+            int smallestY = int.MaxValue;
+            int biggestX = int.MinValue;
+            int biggestY = int.MinValue;
+
+            bool allLayersSkipped = true;
+
+            foreach (Layer layer in layers)
+            {
+                Int32Rect bounds = layer.TightBounds;
+                if (layer.IsReset || !bounds.HasArea)
+                    continue;
+                allLayersSkipped = false;
+
+                if (bounds.X < smallestX)
+                    smallestX = bounds.X;
+
+                if (bounds.X + bounds.Width > biggestX)
+                    biggestX = bounds.X + bounds.Width;
+
+                if (bounds.Y < smallestY)
+                    smallestY = bounds.Y;
+
+                if (bounds.Y + bounds.Height > biggestY)
+                    biggestY = bounds.Y + bounds.Height;
+            }
+
+            if (allLayersSkipped)
+                return null;
+
+            return new DoubleCoords(
+                new Coordinates(smallestX, smallestY),
+                new Coordinates(biggestX, biggestY));
+        }
+
+        private DoubleCoords? ClipLayersAndGetEdgePoints(IEnumerable<Layer> layers)
         {
             if (Layers.Count == 0)
             {
@@ -253,9 +292,15 @@ namespace PixiEditor.Models.DataHolders
             int biggestX = int.MinValue;
             int biggestY = int.MinValue;
 
+            bool allLayersSkipped = true;
+
             foreach (Layer layer in layers)
             {
                 layer.ClipCanvas();
+                if (layer.IsReset)
+                    continue;
+                allLayersSkipped = false;
+
                 if (layer.OffsetX < smallestX)
                 {
                     smallestX = layer.OffsetX;
@@ -277,6 +322,9 @@ namespace PixiEditor.Models.DataHolders
                 }
             }
 
+            if (allLayersSkipped)
+                return null;
+
             return new DoubleCoords(
                 new Coordinates(smallestX, smallestY),
                 new Coordinates(biggestX, biggestY));

+ 5 - 2
PixiEditor/Models/Layers/Layer.cs

@@ -9,7 +9,6 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System.Windows;
-using Windows.Graphics;
 
 namespace PixiEditor.Models.Layers
 {
@@ -491,7 +490,11 @@ namespace PixiEditor.Models.Layers
         public void ClipCanvas()
         {
             var dimensions = GetContentDimensions();
-            if (dimensions == Int32Rect.Empty) return;
+            if (dimensions == Int32Rect.Empty)
+            {
+                Reset();
+                return;
+            }
 
             ResizeCanvas(0, 0, dimensions.X, dimensions.Y, dimensions.Width, dimensions.Height);
             Offset = new Thickness(OffsetX + dimensions.X, OffsetY + dimensions.Y, 0, 0);