Browse Source

Fixed clip canvas

flabbet 8 months ago
parent
commit
aba0c541be

+ 10 - 4
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/EllipseVectorData.cs

@@ -16,6 +16,9 @@ public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
     public override RectD GeometryAABB =>
     public override RectD GeometryAABB =>
         new ShapeCorners(Center, Radius * 2).AABBBounds;
         new ShapeCorners(Center, Radius * 2).AABBBounds;
 
 
+    public override RectD VisualAABB =>
+        RectD.FromCenterAndSize(Center, Radius * 2).Inflate(StrokeWidth / 2);
+
     public override ShapeCorners TransformationCorners =>
     public override ShapeCorners TransformationCorners =>
         new ShapeCorners(Center, Radius * 2).WithMatrix(TransformationMatrix);
         new ShapeCorners(Center, Radius * 2).WithMatrix(TransformationMatrix);
 
 
@@ -51,10 +54,13 @@ public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
         shapePaint.Style = PaintStyle.Fill;
         shapePaint.Style = PaintStyle.Fill;
         drawingSurface.Canvas.DrawOval(Center, Radius, shapePaint);
         drawingSurface.Canvas.DrawOval(Center, Radius, shapePaint);
 
 
-        shapePaint.Color = StrokeColor;
-        shapePaint.Style = PaintStyle.Stroke;
-        shapePaint.StrokeWidth = StrokeWidth;
-        drawingSurface.Canvas.DrawOval(Center, Radius, shapePaint);
+        if (StrokeWidth > 0)
+        {
+            shapePaint.Color = StrokeColor;
+            shapePaint.Style = PaintStyle.Stroke;
+            shapePaint.StrokeWidth = StrokeWidth;
+            drawingSurface.Canvas.DrawOval(Center, Radius, shapePaint);
+        }
 
 
         if (applyTransform)
         if (applyTransform)
         {
         {

+ 17 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/LineVectorData.cs

@@ -29,10 +29,26 @@ public class LineVectorData(VecD startPos, VecD pos) : ShapeVectorData, IReadOnl
     {
     {
         get
         get
         {
         {
-            return RectD.FromTwoPoints(Start, End).Inflate(StrokeWidth);
+            var dir = (End - Start).Normalize();
+            var cross = new VecD(-dir.Y, dir.X);
+            VecD offset = cross * StrokeWidth / 2;
+
+            VecD topLeft = Start + offset;
+            VecD bottomRight = End - offset;
+            VecD bottomLeft = Start - offset;
+            VecD topRight = End + offset;
+
+            ShapeCorners corners = new ShapeCorners()
+            {
+                TopLeft = topLeft, BottomRight = bottomRight, BottomLeft = bottomLeft, TopRight = topRight
+            };
+
+            return corners.AABBBounds;
         }
         }
     }
     }
 
 
+    public override RectD VisualAABB => GeometryAABB;
+
     public override ShapeCorners TransformationCorners => new ShapeCorners(GeometryAABB)
     public override ShapeCorners TransformationCorners => new ShapeCorners(GeometryAABB)
         .WithMatrix(TransformationMatrix);
         .WithMatrix(TransformationMatrix);
 
 

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/PathVectorData.cs

@@ -11,7 +11,8 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 public class PathVectorData : ShapeVectorData, IReadOnlyPathData
 public class PathVectorData : ShapeVectorData, IReadOnlyPathData
 {
 {
     public VectorPath Path { get; }
     public VectorPath Path { get; }
-    public override RectD GeometryAABB => Path.TightBounds.Inflate(StrokeWidth);
+    public override RectD GeometryAABB => Path.TightBounds;
+    public override RectD VisualAABB => GeometryAABB.Inflate(StrokeWidth / 2);
 
 
     public override ShapeCorners TransformationCorners =>
     public override ShapeCorners TransformationCorners =>
         new ShapeCorners(GeometryAABB).WithMatrix(TransformationMatrix);
         new ShapeCorners(GeometryAABB).WithMatrix(TransformationMatrix);

+ 2 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/PointsVectorData.cs

@@ -17,6 +17,8 @@ public class PointsVectorData : ShapeVectorData
     public override RectD GeometryAABB => new RectD(Points.Min(p => p.X), Points.Min(p => p.Y), Points.Max(p => p.X),
     public override RectD GeometryAABB => new RectD(Points.Min(p => p.X), Points.Min(p => p.Y), Points.Max(p => p.X),
         Points.Max(p => p.Y));
         Points.Max(p => p.Y));
 
 
+    public override RectD VisualAABB => GeometryAABB;
+
     public override ShapeCorners TransformationCorners => new ShapeCorners(
     public override ShapeCorners TransformationCorners => new ShapeCorners(
         GeometryAABB).WithMatrix(TransformationMatrix);
         GeometryAABB).WithMatrix(TransformationMatrix);
 
 

+ 17 - 4
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/RectangleVectorData.cs

@@ -14,6 +14,16 @@ public class RectangleVectorData : ShapeVectorData, IReadOnlyRectangleData
 
 
     public override RectD GeometryAABB => RectD.FromCenterAndSize(Center, Size);
     public override RectD GeometryAABB => RectD.FromCenterAndSize(Center, Size);
 
 
+    public override RectD VisualAABB
+    {
+        get
+        {
+            RectD bounds = RectD.FromCenterAndSize(Center, Size);
+            bounds = bounds.Inflate(StrokeWidth / 2);
+            return bounds;
+        }
+    }
+
     public override ShapeCorners TransformationCorners =>
     public override ShapeCorners TransformationCorners =>
         new ShapeCorners(Center, Size).WithMatrix(TransformationMatrix);
         new ShapeCorners(Center, Size).WithMatrix(TransformationMatrix);
 
 
@@ -49,11 +59,14 @@ public class RectangleVectorData : ShapeVectorData, IReadOnlyRectangleData
         paint.Style = PaintStyle.Fill;
         paint.Style = PaintStyle.Fill;
         drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(Center, Size), paint);
         drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(Center, Size), paint);
 
 
-        paint.Color = StrokeColor;
-        paint.Style = PaintStyle.Stroke;
+        if (StrokeWidth > 0)
+        {
+            paint.Color = StrokeColor;
+            paint.Style = PaintStyle.Stroke;
 
 
-        paint.StrokeWidth = StrokeWidth;
-        drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(Center, Size), paint);
+            paint.StrokeWidth = StrokeWidth;
+            drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(Center, Size), paint);
+        }
 
 
         if (applyTransform)
         if (applyTransform)
         {
         {

+ 3 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/ShapeVectorData.cs

@@ -15,8 +15,10 @@ public abstract class ShapeVectorData : ICacheable, ICloneable, IReadOnlyShapeVe
     public Color StrokeColor { get; set; } = Colors.White;
     public Color StrokeColor { get; set; } = Colors.White;
     public Color FillColor { get; set; } = Colors.White;
     public Color FillColor { get; set; } = Colors.White;
     public float StrokeWidth { get; set; } = 1;
     public float StrokeWidth { get; set; } = 1;
-    public abstract RectD GeometryAABB { get; }
+    public abstract RectD GeometryAABB { get; } 
+    public abstract RectD VisualAABB { get; }
     public RectD TransformedAABB => new ShapeCorners(GeometryAABB).WithMatrix(TransformationMatrix).AABBBounds;
     public RectD TransformedAABB => new ShapeCorners(GeometryAABB).WithMatrix(TransformationMatrix).AABBBounds;
+    public RectD TransformedVisualAABB => new ShapeCorners(VisualAABB).WithMatrix(TransformationMatrix).AABBBounds;
     public abstract ShapeCorners TransformationCorners { get; } 
     public abstract ShapeCorners TransformationCorners { get; } 
     
     
     protected void ApplyTransformTo(DrawingSurface drawingSurface)
     protected void ApplyTransformTo(DrawingSurface drawingSurface)

+ 3 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/VectorLayerNode.cs

@@ -79,7 +79,7 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
         }
         }
         else
         else
         {
         {
-            return ShapeData?.TransformedAABB;
+            return ShapeData?.TransformedVisualAABB;
         }
         }
         
         
         return null;
         return null;
@@ -95,7 +95,7 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
 
 
         using var paint = new Paint();
         using var paint = new Paint();
 
 
-        VecI tightBoundsSize = (VecI)ShapeData.TransformedAABB.Size;
+        VecI tightBoundsSize = (VecI)ShapeData.TransformedVisualAABB.Size;
 
 
         VecI translation = new VecI(
         VecI translation = new VecI(
             (int)Math.Max(ShapeData.TransformedAABB.TopLeft.X, 0),
             (int)Math.Max(ShapeData.TransformedAABB.TopLeft.X, 0),
@@ -149,7 +149,7 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
 
 
     public override RectD? GetTightBounds(KeyFrameTime frameTime)
     public override RectD? GetTightBounds(KeyFrameTime frameTime)
     {
     {
-        return ShapeData?.TransformedAABB ?? null;
+        return ShapeData?.TransformedVisualAABB ?? null;
     }
     }
 
 
     public override ShapeCorners GetTransformationCorners(KeyFrameTime frameTime)
     public override ShapeCorners GetTransformationCorners(KeyFrameTime frameTime)

+ 25 - 13
src/PixiEditor.ChangeableDocument/Changes/Root/ClipCanvas_Change.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.ChangeInfos.Root;
 using PixiEditor.ChangeableDocument.ChangeInfos.Root;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Numerics;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Root;
 namespace PixiEditor.ChangeableDocument.Changes.Root;
 
 
@@ -16,29 +17,34 @@ internal class ClipCanvas_Change : ResizeBasedChangeBase
 
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
     {
     {
-        RectI? bounds = null;
+        RectD? bounds = null;
         target.ForEveryMember((member) =>
         target.ForEveryMember((member) =>
         {
         {
-            if (member is LayerNode layer)
+            if (member.IsVisible.Value)
             {
             {
-                var layerBounds = layer.GetTightBounds(frameToClip);
-                if (layerBounds.HasValue)
+                if (member is LayerNode layer)
                 {
                 {
-                    bounds ??= (RectI)layerBounds.Value;
-                    bounds = bounds.Value.Union((RectI)layerBounds.Value);
+                    var layerBounds = layer.GetTightBounds(frameToClip);
+                    if (layerBounds is { IsZeroOrNegativeArea: false })
+                    {
+                        bounds ??= layerBounds.Value;
+                        bounds = bounds.Value.Union(layerBounds.Value);
+                    }
                 }
                 }
             }
             }
         });
         });
 
 
-        if (!bounds.HasValue || bounds.Value.IsZeroOrNegativeArea || bounds.Value == new RectI(VecI.Zero, target.Size))
+        if (!bounds.HasValue || bounds.Value.IsZeroOrNegativeArea || bounds.Value == new RectD(VecI.Zero, target.Size))
         {
         {
             ignoreInUndo = true;
             ignoreInUndo = true;
             return new None();
             return new None();
         }
         }
         
         
-        RectI newBounds = bounds.Value;
+        RectD newBounds = bounds.Value;
         
         
-        target.Size = newBounds.Size;
+        VecI size = (VecI)newBounds.Size.Ceiling();
+        
+        target.Size = size;
         target.VerticalSymmetryAxisX = Math.Clamp(_originalVerAxisX, 0, target.Size.X);
         target.VerticalSymmetryAxisX = Math.Clamp(_originalVerAxisX, 0, target.Size.X);
         target.HorizontalSymmetryAxisY = Math.Clamp(_originalHorAxisY, 0, target.Size.Y);
         target.HorizontalSymmetryAxisY = Math.Clamp(_originalHorAxisY, 0, target.Size.Y);
         
         
@@ -48,17 +54,23 @@ internal class ClipCanvas_Change : ResizeBasedChangeBase
             {
             {
                 layer.ForEveryFrame(img =>
                 layer.ForEveryFrame(img =>
                 {
                 {
-                    Resize(img, layer.Id, newBounds.Size, -newBounds.Pos, deletedChunks);
+                    Resize(img, layer.Id, size, -(VecI)newBounds.Pos, deletedChunks);
                 });
                 });
             }
             }
-            
+            else if (member is ITransformableObject transformableObject)
+            {
+                originalTransformations[member.Id] = transformableObject.TransformationMatrix;
+                VecD floor = new VecD(-(float)newBounds.Pos.X, -(float)newBounds.Pos.Y);
+                transformableObject.TransformationMatrix = transformableObject.TransformationMatrix.PostConcat(Matrix3X3.CreateTranslation((float)floor.X, (float)floor.Y));
+            }
+
             if (member.EmbeddedMask is null)
             if (member.EmbeddedMask is null)
                 return;
                 return;
             
             
-            Resize(member.EmbeddedMask, member.Id, newBounds.Size, -newBounds.Pos, deletedMaskChunks);
+            Resize(member.EmbeddedMask, member.Id, size, -(VecI)newBounds.Pos, deletedMaskChunks);
         });
         });
 
 
         ignoreInUndo = false;
         ignoreInUndo = false;
-        return new Size_ChangeInfo(newBounds.Size, target.VerticalSymmetryAxisX, target.HorizontalSymmetryAxisY);
+        return new Size_ChangeInfo(size, target.VerticalSymmetryAxisX, target.HorizontalSymmetryAxisY);
     }
     }
 }
 }

+ 10 - 2
src/PixiEditor.ChangeableDocument/Changes/Root/ResizeBasedChangeBase.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.ChangeInfos.Root;
 using PixiEditor.ChangeableDocument.ChangeInfos.Root;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Numerics;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Root;
 namespace PixiEditor.ChangeableDocument.Changes.Root;
 
 
@@ -12,6 +13,8 @@ internal abstract class ResizeBasedChangeBase : Change
     protected double _originalVerAxisX;
     protected double _originalVerAxisX;
     protected Dictionary<Guid, List<CommittedChunkStorage>> deletedChunks = new();
     protected Dictionary<Guid, List<CommittedChunkStorage>> deletedChunks = new();
     protected Dictionary<Guid, List<CommittedChunkStorage>> deletedMaskChunks = new();
     protected Dictionary<Guid, List<CommittedChunkStorage>> deletedMaskChunks = new();
+    
+    protected Dictionary<Guid, Matrix3X3> originalTransformations = new();
 
 
     public ResizeBasedChangeBase()
     public ResizeBasedChangeBase()
     {
     {
@@ -57,8 +60,13 @@ internal abstract class ResizeBasedChangeBase : Change
                     img.CommitChanges();
                     img.CommitChanges();
                 });
                 });
             }
             }
-
-            // TODO: Add support for different Layer types?
+            else if (member is ITransformableObject transformableObject)
+            {
+                if (originalTransformations.TryGetValue(member.Id, out var transformation))
+                {
+                    transformableObject.TransformationMatrix = transformation;
+                }
+            }
 
 
             if (member.EmbeddedMask is null)
             if (member.EmbeddedMask is null)
                 return;
                 return;