Browse Source

Merge remote-tracking branch 'origin/quickfill' into quickfill

flabbet 3 years ago
parent
commit
a177a8edfa

+ 1 - 3
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -19,8 +19,6 @@ namespace PixiEditor.Models.Controllers
 
         public ToolsViewModel Tools { get; set; }
 
-        private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
-
         public BitmapOperationsUtility(BitmapManager manager, ToolsViewModel tools)
         {
             Manager = manager;
@@ -95,7 +93,7 @@ namespace PixiEditor.Models.Controllers
                     activeLayer.LayerBitmap.SkiaSurface.Canvas,
                     previewLayer.OffsetX - activeLayer.OffsetX,
                     previewLayer.OffsetY - activeLayer.OffsetY,
-                    BlendingPaint
+                    Surface.BlendingPaint
                 );
 
             Manager.ActiveLayer.InvokeLayerBitmapChange(dirtyRect);

+ 46 - 15
PixiEditor/Models/Controllers/ClipboardController.cs

@@ -35,31 +35,47 @@ namespace PixiEditor.Models.Controllers
         public static void CopyToClipboard(Document document)
         {
             CopyToClipboard(
-                document.Layers.Where(x => document.GetFinalLayerIsVisible(x)).ToArray(),
-                document.ActiveSelection.SelectedPoints.ToArray(),
-                //new Coordinates[] { (0, 0), (15, 15) },
+                document.Layers.Where(x => document.GetFinalLayerIsVisible(x) && x.IsActive).ToArray(),
+                document.ActiveSelection.SelectionLayer,
+                document.LayerStructure,
                 document.Width,
                 document.Height,
-                document.ToSerializable());
+                null/*document.ToSerializable()*/);
+        }
+
+        private static Surface CreateMaskedCombinedSurface(Layer[] layers, LayerStructure structure, Layer selLayer)
+        {
+            if (layers.Length == 0)
+                throw new ArgumentException("Can't combine 0 layers");
+            selLayer.ClipCanvas();
+
+            Surface combined = BitmapUtils.CombineLayers(new Int32Rect(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height), layers, structure);
+            using SKImage snapshot = selLayer.LayerBitmap.SkiaSurface.Snapshot();
+            combined.SkiaSurface.Canvas.DrawImage(snapshot, 0, 0, Surface.MaskingPaint);
+            return combined;
         }
 
         /// <summary>
         ///     Copies the selection to clipboard in PNG, Bitmap and DIB formats.
         /// </summary>
         /// <param name="layers">Layers where selection is.</param>
-        public static void CopyToClipboard(Layer[] layers, Coordinates[] selection, int originalImageWidth, int originalImageHeight, SerializableDocument document = null)
+        public static void CopyToClipboard(Layer[] layers, Layer selLayer, LayerStructure structure, int originalImageWidth, int originalImageHeight, SerializableDocument document = null)
         {
             if (!ClipboardHelper.TryClear())
                 return;
+            if (layers.Length == 0)
+                return;
 
-            using Surface surface = BitmapUtils.CombineLayers(new Int32Rect(0, 0, originalImageWidth, originalImageHeight), layers);
+            using Surface surface = CreateMaskedCombinedSurface(layers, structure, selLayer);
             DataObject data = new DataObject();
 
-            WriteableBitmap combinedBitmaps = surface.ToWriteableBitmap();
-            BitmapSource croppedBmp = BitmapSelectionToBmpSource(combinedBitmaps, selection, out int offsetX, out int offsetY, out int width, out int height);
-            data.SetData(typeof(CropData), new CropData(width, height, offsetX, offsetY).ToStream());
 
-            using (SKData pngData = surface.SkiaSurface.Snapshot(SKRectI.Create(offsetX, offsetY, width, height)).Encode())
+            //BitmapSource croppedBmp = BitmapSelectionToBmpSource(finalBitmap, selLayer, out int offsetX, out int offsetY, out int width, out int height);
+
+            //Remove for now
+            //data.SetData(typeof(CropData), new CropData(width, height, offsetX, offsetY).ToStream());
+
+            using (SKData pngData = surface.SkiaSurface.Snapshot().Encode())
             {
                 // Stream should not be disposed
                 MemoryStream pngStream = new MemoryStream();
@@ -74,9 +90,12 @@ namespace PixiEditor.Models.Controllers
                 data.SetFileDropList(new StringCollection() { TempCopyFilePath });
             }
 
-            data.SetData(DataFormats.Bitmap, croppedBmp, true); // Bitmap, no transparency
-            data.SetImage(croppedBmp); // DIB format, no transparency
+            WriteableBitmap finalBitmap = surface.ToWriteableBitmap();
+            data.SetData(DataFormats.Bitmap, finalBitmap, true); // Bitmap, no transparency
+            data.SetImage(finalBitmap); // DIB format, no transparency
 
+            // Remove pixi copying for now
+            /*
             if (document != null)
             {
                 MemoryStream memoryStream = new();
@@ -84,6 +103,7 @@ namespace PixiEditor.Models.Controllers
                 data.SetData("PIXI", memoryStream); // PIXI, supports transparency, layers, groups and swatches
                 ClipboardHelper.TrySetDataObject(data, true);
             }
+            */
 
             ClipboardHelper.TrySetDataObject(data, true);
         }
@@ -93,7 +113,15 @@ namespace PixiEditor.Models.Controllers
         /// </summary>
         public static void PasteFromClipboard()
         {
-            IEnumerable<Layer> layers = GetLayersFromClipboard();
+            IEnumerable<Layer> layers;
+            try
+            {
+                layers = GetLayersFromClipboard();
+            }
+            catch
+            {
+                return;
+            }
 
             Document activeDocument = ViewModelMain.Current.BitmapManager.ActiveDocument;
             int startIndex = activeDocument.Layers.Count;
@@ -117,6 +145,8 @@ namespace PixiEditor.Models.Controllers
             if (data == null)
                 yield break;
 
+            //Remove pixi for now
+            /*
             if (data.GetDataPresent("PIXI"))
             {
                 SerializableDocument document = GetSerializable(data, out CropData crop);
@@ -126,7 +156,7 @@ namespace PixiEditor.Models.Controllers
                 {
                     SKRectI intersect;
 
-                    if (/*layer.OffsetX > crop.OffsetX + crop.Width || layer.OffsetY > crop.OffsetY + crop.Height ||*/
+                    if (//layer.OffsetX > crop.OffsetX + crop.Width || layer.OffsetY > crop.OffsetY + crop.Height ||
                         !sLayer.IsVisible || sLayer.Opacity == 0 ||
                         (intersect = SKRectI.Intersect(cropRect, sLayer.GetRect())) == SKRectI.Empty)
                     {
@@ -140,7 +170,8 @@ namespace PixiEditor.Models.Controllers
                     yield return layer;
                 }
             }
-            else if (TryFromSingleImage(data, out Surface singleImage))
+            else */
+            if (TryFromSingleImage(data, out Surface singleImage))
             {
                 yield return new Layer("Image", singleImage);
             }

+ 4 - 1
PixiEditor/Models/DataHolders/Surface.cs

@@ -15,7 +15,10 @@ namespace PixiEditor.Models.DataHolders
 {
     public class Surface : IDisposable
     {
-        public static SKPaint ReplacingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.Src };
+        public static SKPaint ReplacingPaint { get; } = new() { BlendMode = SKBlendMode.Src };
+        public static SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
+        public static SKPaint MaskingPaint { get; } = new() { BlendMode = SKBlendMode.DstIn };
+        public static SKPaint InverseMaskingPaint { get; } = new() { BlendMode = SKBlendMode.DstOut };
 
         private static readonly SKPaint nearestNeighborReplacingPaint = new SKPaint() { BlendMode = SKBlendMode.Src, FilterQuality = SKFilterQuality.None };
 

+ 32 - 2
PixiEditor/Models/ImageManipulation/BitmapUtils.cs

@@ -9,14 +9,13 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Windows;
-using System.Windows.Media;
 using System.Windows.Media.Imaging;
 
 namespace PixiEditor.Models.ImageManipulation
 {
     public static class BitmapUtils
     {
-        public static Surface CombineLayers(Int32Rect portion, IEnumerable<Layer> layers,  LayerStructure structure = null)
+        public static Surface CombineLayers(Int32Rect portion, IEnumerable<Layer> layers, LayerStructure structure = null)
         {
             Surface finalSurface = new(portion.Width, portion.Height);
             using SKPaint paint = new();
@@ -49,6 +48,37 @@ namespace PixiEditor.Models.ImageManipulation
             return finalSurface;
         }
 
+        public static Surface[] ExtractSelectedPortions(Layer selLayer, Layer[] extractFrom, bool eraceFromLayers)
+        {
+            using var selSnap = selLayer.LayerBitmap.SkiaSurface.Snapshot();
+            Surface[] output = new Surface[extractFrom.Length];
+
+            int count = 0;
+            foreach (Layer layer in extractFrom)
+            {
+                Surface portion = new Surface(selLayer.Width, selLayer.Height);
+                SKRect selLayerRect = new SKRect(0, 0, selLayer.Width, selLayer.Height);
+
+                int x = selLayer.OffsetX - layer.OffsetX;
+                int y = selLayer.OffsetY - layer.OffsetY;
+
+                using (var layerSnap = layer.LayerBitmap.SkiaSurface.Snapshot())
+                    portion.SkiaSurface.Canvas.DrawImage(layerSnap, new SKRect(x, y, x + selLayer.Width, y + selLayer.Height), selLayerRect, Surface.ReplacingPaint);
+                portion.SkiaSurface.Canvas.DrawImage(selSnap, 0, 0, Surface.MaskingPaint);
+                output[count] = portion;
+                count++;
+
+                if (eraceFromLayers)
+                {
+                    layer.LayerBitmap.SkiaSurface.Canvas.DrawImage(selSnap, new SKRect(0, 0, selLayer.Width, selLayer.Height),
+                        new SKRect(selLayer.OffsetX - layer.OffsetX, selLayer.OffsetY - layer.OffsetY, selLayer.OffsetX - layer.OffsetX + selLayer.Width, selLayer.OffsetY - layer.OffsetY + selLayer.Height),
+                        Surface.InverseMaskingPaint);
+                    layer.InvokeLayerBitmapChange(new Int32Rect(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height));
+                }
+            }
+            return output;
+        }
+
         /// <summary>
         /// Generates simplified preview from Document, very fast, great for creating small previews. Creates uniform streched image.
         /// </summary>

+ 2 - 40
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -16,16 +16,6 @@ namespace PixiEditor.Models.Tools.Tools
 {
     internal class MoveTool : BitmapOperationTool
     {
-        private static readonly SKPaint maskingPaint = new()
-        {
-            BlendMode = SKBlendMode.DstIn,
-        };
-
-        private static readonly SKPaint inverseMaskingPaint = new()
-        {
-            BlendMode = SKBlendMode.DstOut,
-        };
-
         private Layer[] affectedLayers;
         private Surface[] currentlyDragged;
         private Coordinates[] currentlyDraggedPositions;
@@ -98,7 +88,7 @@ namespace PixiEditor.Models.Tools.Tools
 
             if (anySelection)
             {
-                currentlyDragged = ExtractDraggedPortions(anySelection ? selLayer : null, affectedLayers);
+                currentlyDragged = BitmapUtils.ExtractSelectedPortions(selLayer, affectedLayers, true);
                 currentlyDraggedPositions = Enumerable.Repeat(new Coordinates(selLayer.OffsetX, selLayer.OffsetY), affectedLayers.Length).ToArray();
             }
             else
@@ -116,7 +106,7 @@ namespace PixiEditor.Models.Tools.Tools
             if (selLayer != null)
             {
                 using var selSnap = selLayer.LayerBitmap.SkiaSurface.Snapshot();
-                combined.SkiaSurface.Canvas.DrawImage(selSnap, 0, 0, maskingPaint);
+                combined.SkiaSurface.Canvas.DrawImage(selSnap, 0, 0, Surface.MaskingPaint);
             }
             return combined;
         }
@@ -141,34 +131,6 @@ namespace PixiEditor.Models.Tools.Tools
             return (outCoords, outSurfaces);
         }
 
-        private static Surface[] ExtractDraggedPortions(Layer selLayer, Layer[] draggedLayers)
-        {
-            using var selSnap = selLayer.LayerBitmap.SkiaSurface.Snapshot();
-            Surface[] output = new Surface[draggedLayers.Length];
-
-            int count = 0;
-            foreach (Layer layer in draggedLayers)
-            {
-                Surface portion = new Surface(selLayer.Width, selLayer.Height);
-                SKRect selLayerRect = new SKRect(0, 0, selLayer.Width, selLayer.Height);
-
-                int x = selLayer.OffsetX - layer.OffsetX;
-                int y = selLayer.OffsetY - layer.OffsetY;
-
-                using (var layerSnap = layer.LayerBitmap.SkiaSurface.Snapshot())
-                    portion.SkiaSurface.Canvas.DrawImage(layerSnap, new SKRect(x, y, x + selLayer.Width, y + selLayer.Height), selLayerRect, Surface.ReplacingPaint);
-                portion.SkiaSurface.Canvas.DrawImage(selSnap, 0, 0, maskingPaint);
-                output[count] = portion;
-                count++;
-
-                layer.LayerBitmap.SkiaSurface.Canvas.DrawImage(selSnap, new SKRect(0, 0, selLayer.Width, selLayer.Height),
-                    new SKRect(selLayer.OffsetX - layer.OffsetX, selLayer.OffsetY - layer.OffsetY, selLayer.OffsetX - layer.OffsetX + selLayer.Width, selLayer.OffsetY - layer.OffsetY + selLayer.Height),
-                    inverseMaskingPaint);
-                layer.InvokeLayerBitmapChange(new Int32Rect(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height));
-            }
-            return output;
-        }
-
         public override void Use(Layer activeLayer, Layer previewLayer, IEnumerable<Layer> allLayers, IReadOnlyList<Coordinates> recordedMouseMovement, SKColor color)
         {
             Coordinates newPos = recordedMouseMovement[^1];