Browse Source

Extremely Improved dynamic layers performance

flabbet 5 years ago
parent
commit
45ee0f5d4e

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

@@ -83,12 +83,10 @@ namespace PixiEditor.Models.Controllers
                 for (int i = 0; i < modifiedLayers.Length; i++)
                 {
                     var layer = Manager.ActiveDocument.Layers[modifiedLayers[i].LayerIndex];
-                    layer.DynamicResize(modifiedLayers[i].PixelChanges);
                     oldPixelsValues[i] = new LayerChange(
                         GetOldPixelsValues(modifiedLayers[i].PixelChanges.ChangedPixels.Keys.ToArray()),
                         modifiedLayers[i].LayerIndex);
-                    
-                        layer.ApplyPixels(modifiedLayers[i].PixelChanges);
+                    layer.ApplyPixels(modifiedLayers[i].PixelChanges);
                     BitmapChanged?.Invoke(this, new BitmapChangedEventArgs(modifiedLayers[i].PixelChanges,
                         oldPixelsValues[i].PixelChanges, modifiedLayers[i].LayerIndex));
                 }
@@ -124,9 +122,9 @@ namespace PixiEditor.Models.Controllers
             Dictionary<Coordinates, Color> values = new Dictionary<Coordinates, Color>();
             using (Manager.ActiveLayer.LayerBitmap.GetBitmapContext(ReadWriteMode.ReadOnly))
             {
+                coordinates = Manager.ActiveLayer.ConvertToRelativeCoordinates(coordinates);
                 for (int i = 0; i < coordinates.Length; i++)
                 {
-                    coordinates = Manager.ActiveLayer.ConvertToRelativeCoordinates(coordinates);
                     if (coordinates[i].X < 0 || coordinates[i].X > Manager.ActiveLayer.Width - 1 ||
                         coordinates[i].Y < 0 || coordinates[i].Y > Manager.ActiveLayer.Height - 1)
                         continue;

+ 39 - 13
PixiEditor/Models/Layers/Layer.cs

@@ -146,13 +146,12 @@ namespace PixiEditor.Models.Layers
 
         public Coordinates[] ConvertToRelativeCoordinates(Coordinates[] nonRelativeCords)
         {
-            Coordinates[] result = new Coordinates[nonRelativeCords.Length];
-            for (int i = 0; i < result.Length; i++)
+            for (int i = 0; i < nonRelativeCords.Length; i++)
             {
-                result[i] = new Coordinates(nonRelativeCords[i].X - OffsetX, nonRelativeCords[i].Y - OffsetY);
+                nonRelativeCords[i] = new Coordinates(nonRelativeCords[i].X - OffsetX, nonRelativeCords[i].Y - OffsetY);
             }
 
-            return result;
+            return nonRelativeCords;
         }
 
         /// <summary>
@@ -162,12 +161,14 @@ namespace PixiEditor.Models.Layers
         public void DynamicResize(BitmapPixelChanges pixels)
         {
             ResetOffset(pixels);
-            int newMaxX = pixels.ChangedPixels.Max(x => x.Key.X) - OffsetX;
-            int newMaxY = pixels.ChangedPixels.Max(x => x.Key.Y) - OffsetY;
-            int newMinX = pixels.ChangedPixels.Min(x => x.Key.X) - OffsetX;
-            int newMinY = pixels.ChangedPixels.Min(x => x.Key.Y) - OffsetY;
-
-            if (pixels.ChangedPixels.Any(x => x.Value.A != 0))
+            var borderData = ExtractBorderData(pixels);
+            DoubleCords minMaxCords = borderData.Item1;
+            int newMaxX = minMaxCords.Coords2.X - OffsetX;
+            int newMaxY = minMaxCords.Coords2.Y - OffsetY;
+            int newMinX = minMaxCords.Coords1.X - OffsetX;
+            int newMinY = minMaxCords.Coords1.Y - OffsetY;
+
+            if (pixels.ChangedPixels.First().Value.A != 0 && pixels.WasBuiltAsSingleColored)
             {
                 if (newMaxX + 1 > Width || newMaxY + 1 > Height)
                 {
@@ -177,14 +178,39 @@ namespace PixiEditor.Models.Layers
                 {
                     IncreaseSizeToTop(newMinX, newMinY);
                 }
-            } 
-            
-            if(pixels.ChangedPixels.Any(x=> IsBorderPixel(x.Key) && x.Value.A == 0))
+            }
+
+            if(borderData.Item2) //if clip is requested
             {
                 _clipRequested = true;
             }
         }
 
+        private Tuple<DoubleCords, bool> ExtractBorderData(BitmapPixelChanges pixels)
+        {
+            Coordinates firstCords = pixels.ChangedPixels.First().Key;
+            int minX = firstCords.X;
+            int minY = firstCords.Y;
+            int maxX = minX;
+            int maxY = minY;
+            bool clipRequested = false;
+
+            foreach (var pixel in pixels.ChangedPixels)
+            {
+                if (pixel.Key.X < minX) minX = pixel.Key.X;
+                else if (pixel.Key.X > maxX) maxX = pixel.Key.X;
+
+                if (pixel.Key.Y < minY) minY = pixel.Key.Y;
+                else if (pixel.Key.Y > maxY) maxY = pixel.Key.Y;
+
+                if (clipRequested == false && IsBorderPixel(pixel.Key) && pixel.Value.A == 0)
+                    clipRequested = true;
+
+            }
+            return new Tuple<DoubleCords, bool>(
+                new DoubleCords(new Coordinates(minX, minY), new Coordinates(maxX, maxY)), clipRequested);
+        }
+
         private bool IsBorderPixel(Coordinates cords)
         {
             return cords.X - OffsetX == 0 || cords.Y - OffsetY == 0 || cords.X - OffsetX == Width - 1 ||

+ 5 - 1
PixiEditor/Models/Tools/BitmapPixelChanges.cs

@@ -10,12 +10,16 @@ namespace PixiEditor.Models.Tools
 {
     public struct BitmapPixelChanges
     {
+
+        public bool WasBuiltAsSingleColored { get; private set; }
+
         public static BitmapPixelChanges Empty => new BitmapPixelChanges(new Dictionary<Coordinates, Color>());
         public Dictionary<Coordinates, Color> ChangedPixels { get; set; }
 
         public BitmapPixelChanges(Dictionary<Coordinates, Color> changedPixels)
         {
             ChangedPixels = changedPixels;
+            WasBuiltAsSingleColored = false;
         }
 
         /// <summary>
@@ -28,7 +32,7 @@ namespace PixiEditor.Models.Tools
         {
             Dictionary<Coordinates, Color> dict = new Dictionary<Coordinates, Color>();
             for (int i = 0; i < coordinates.Length; i++) dict.Add(coordinates[i], color);
-            return new BitmapPixelChanges(dict);
+            return new BitmapPixelChanges(dict) {WasBuiltAsSingleColored = true};
         }
 
         /// <summary>