Browse Source

fix the bug where you can draw to the left of the canvas, make crash when merging misaligned layers explicit

Equbuxu 4 years ago
parent
commit
3aed62d253

+ 16 - 9
PixiEditor/Models/ImageManipulation/BitmapUtils.cs

@@ -1,13 +1,13 @@
-using System;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Layers;
+using PixiEditor.Models.Position;
+using PixiEditor.Parser;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Windows;
 using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Layers;
-using PixiEditor.Models.Position;
-using PixiEditor.Parser;
 
 
 namespace PixiEditor.Models.ImageManipulation
 namespace PixiEditor.Models.ImageManipulation
 {
 {
@@ -34,9 +34,9 @@ namespace PixiEditor.Models.ImageManipulation
         /// <summary>
         /// <summary>
         ///     Converts layers bitmaps into one bitmap.
         ///     Converts layers bitmaps into one bitmap.
         /// </summary>
         /// </summary>
-        /// <param name="layers">Layers to combine.</param>
         /// <param name="width">Width of final bitmap.</param>
         /// <param name="width">Width of final bitmap.</param>
         /// <param name="height">Height of final bitmap.</param>.
         /// <param name="height">Height of final bitmap.</param>.
+        /// <param name="layers">Layers to combine.</param>
         /// <returns>WriteableBitmap of layered bitmaps.</returns>
         /// <returns>WriteableBitmap of layered bitmaps.</returns>
         public static WriteableBitmap CombineLayers(int width, int height, params Layer[] layers)
         public static WriteableBitmap CombineLayers(int width, int height, params Layer[] layers)
         {
         {
@@ -49,6 +49,13 @@ namespace PixiEditor.Models.ImageManipulation
                     float layerOpacity = layers[i].Opacity;
                     float layerOpacity = layers[i].Opacity;
                     Layer layer = layers[i];
                     Layer layer = layers[i];
 
 
+                    if (layer.OffsetX < 0 || layer.OffsetY < 0 ||
+                        layer.Width + layer.OffsetX > layer.MaxWidth ||
+                        layer.Height + layer.OffsetY > layer.MaxHeight)
+                    {
+                        throw new InvalidOperationException("Layers must not extend beyond canvas borders");
+                    }
+
                     for (int y = 0; y < layers[i].Height; y++)
                     for (int y = 0; y < layers[i].Height; y++)
                     {
                     {
                         for (int x = 0; x < layers[i].Width; x++)
                         for (int x = 0; x < layers[i].Width; x++)
@@ -81,7 +88,7 @@ namespace PixiEditor.Models.ImageManipulation
             return finalBitmap;
             return finalBitmap;
         }
         }
 
 
-      /// <summary>
+        /// <summary>
         /// Generates simplified preview from Document, very fast, great for creating small previews. Creates uniform streched image.
         /// Generates simplified preview from Document, very fast, great for creating small previews. Creates uniform streched image.
         /// </summary>
         /// </summary>
         /// <param name="document">Document which be used to generate preview.</param>
         /// <param name="document">Document which be used to generate preview.</param>
@@ -118,7 +125,7 @@ namespace PixiEditor.Models.ImageManipulation
 
 
         public static Dictionary<Guid, Color[]> GetPixelsForSelection(Layer[] layers, Coordinates[] selection)
         public static Dictionary<Guid, Color[]> GetPixelsForSelection(Layer[] layers, Coordinates[] selection)
         {
         {
-            Dictionary<Guid, Color[]> result = new ();
+            Dictionary<Guid, Color[]> result = new();
 
 
             foreach (Layer layer in layers)
             foreach (Layer layer in layers)
             {
             {
@@ -187,4 +194,4 @@ namespace PixiEditor.Models.ImageManipulation
             return previewBitmap.Resize(newWidth, newHeight, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
             return previewBitmap.Resize(newWidth, newHeight, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
         }
         }
     }
     }
-}
+}

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

@@ -1,14 +1,14 @@
-using System;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Position;
+using PixiEditor.Models.Undo;
+using PixiEditor.ViewModels;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.Linq;
 using System.Linq;
 using System.Windows;
 using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Position;
-using PixiEditor.Models.Undo;
-using PixiEditor.ViewModels;
 
 
 namespace PixiEditor.Models.Layers
 namespace PixiEditor.Models.Layers
 {
 {
@@ -367,14 +367,14 @@ namespace PixiEditor.Models.Layers
 
 
             if (!(pixels.WasBuiltAsSingleColored && pixels.ChangedPixels.First().Value.A == 0))
             if (!(pixels.WasBuiltAsSingleColored && pixels.ChangedPixels.First().Value.A == 0))
             {
             {
-                if (newMaxX + 1 > Width || newMaxY + 1 > Height)
+                if ((newMaxX + 1 > Width && Width < MaxWidth) || (newMaxY + 1 > Height && Height < MaxHeight))
                 {
                 {
-                    IncreaseSizeToBottom(newMaxX, newMaxY);
+                    IncreaseSizeToBottomAndRight(newMaxX, newMaxY);
                 }
                 }
 
 
-                if (newMinX < 0 || newMinY < 0)
+                if ((newMinX < 0 && Width < MaxWidth) || (newMinY < 0 && Height < MaxHeight))
                 {
                 {
-                    IncreaseSizeToTop(newMinX, newMinY);
+                    IncreaseSizeToTopAndLeft(newMinX, newMinY);
                 }
                 }
             }
             }
 
 
@@ -493,7 +493,7 @@ namespace PixiEditor.Models.Layers
             }
             }
         }
         }
 
 
-        private void IncreaseSizeToBottom(int newMaxX, int newMaxY)
+        private void IncreaseSizeToBottomAndRight(int newMaxX, int newMaxY)
         {
         {
             if (MaxWidth - OffsetX < 0 || MaxHeight - OffsetY < 0)
             if (MaxWidth - OffsetX < 0 || MaxHeight - OffsetY < 0)
             {
             {
@@ -506,7 +506,7 @@ namespace PixiEditor.Models.Layers
             ResizeCanvas(0, 0, 0, 0, newMaxX, newMaxY);
             ResizeCanvas(0, 0, 0, 0, newMaxX, newMaxY);
         }
         }
 
 
-        private void IncreaseSizeToTop(int newMinX, int newMinY)
+        private void IncreaseSizeToTopAndLeft(int newMinX, int newMinY)
         {
         {
             newMinX = Math.Clamp(Math.Min(newMinX, Width), Math.Min(-OffsetX, OffsetX), 0);
             newMinX = Math.Clamp(Math.Min(newMinX, Width), Math.Min(-OffsetX, OffsetX), 0);
             newMinY = Math.Clamp(Math.Min(newMinY, Height), Math.Min(-OffsetY, OffsetY), 0);
             newMinY = Math.Clamp(Math.Min(newMinY, Height), Math.Min(-OffsetY, OffsetY), 0);
@@ -538,8 +538,8 @@ namespace PixiEditor.Models.Layers
         {
         {
             if (Width == 0 || Height == 0)
             if (Width == 0 || Height == 0)
             {
             {
-                int offsetX = pixels.ChangedPixels.Min(x => x.Key.X);
-                int offsetY = pixels.ChangedPixels.Min(x => x.Key.Y);
+                int offsetX = Math.Max(pixels.ChangedPixels.Min(x => x.Key.X), 0);
+                int offsetY = Math.Max(pixels.ChangedPixels.Min(x => x.Key.Y), 0);
                 Offset = new Thickness(offsetX, offsetY, 0, 0);
                 Offset = new Thickness(offsetX, offsetY, 0, 0);
             }
             }
         }
         }