Przeglądaj źródła

Symmetry overlay fixed

flabbet 10 miesięcy temu
rodzic
commit
a96eb862ae

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit ad48bffad7514c7338d2f56c0174c2cc9cece396
+Subproject commit 3afa69b40c494569b6337e1f892eacf906145a81

+ 1 - 1
src/PixiEditor/Styles/PixiEditor.Handles.axaml

@@ -57,7 +57,7 @@
         </GeometryDrawing>
     </DrawingGroup>
 
-            <Path x:Key="MarkerHandle" Data="M -1.1146 -0.6603 c -0.1215 -0.1215 -0.3187 -0.1215 -0.4401 0 l -0.4401 0.4401 c -0.1215 0.1215 -0.1215 0.3187 0 0.4401 l 0.4401 0.4401 c 0.1215 0.1215 0.3187 0.1215 0.4401 0 l 0.4401 -0.4401 c 0.1215 -0.1215 0.1215 -0.3187 0 -0.4401 l -0.4401 -0.4401 Z M -0.5834 0.0012 l 0.5833 -0.0013"/>
+            <system:String x:Key="MarkerHandle">M -1.1146 -0.6603 c -0.1215 -0.1215 -0.3187 -0.1215 -0.4401 0 l -0.4401 0.4401 c -0.1215 0.1215 -0.1215 0.3187 0 0.4401 l 0.4401 0.4401 c 0.1215 0.1215 0.3187 0.1215 0.4401 0 l 0.4401 -0.4401 c 0.1215 -0.1215 0.1215 -0.3187 0 -0.4401 l -0.4401 -0.4401 Z M -0.5834 0.0012 l 0.5833 -0.0013</system:String>
 
             <Path x:Key="RotateHandle" Data="M -1.26 -0.455 Q 0 0.175 1.26 -0.455 L 1.12 -0.735 L 2.1 -0.7 L 1.54 0.105 L 1.4 -0.175 Q 0 0.525 -1.4 -0.175 L -1.54 0.105 L -2.1 -0.7 L -1.12 -0.735 Z"/>
             <SolidColorBrush x:Key="HandleBrush" Color="{DynamicResource GlyphColor}"/>

+ 7 - 3
src/PixiEditor/Views/Overlays/Handles/Handle.cs

@@ -6,6 +6,7 @@ using Avalonia.Media;
 using PixiEditor.Helpers;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Backend.Core.Surfaces.Vector;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
 using PixiEditor.Helpers.Extensions;
@@ -66,14 +67,17 @@ public abstract class Handle : IHandle
         return default!;
     }
 
-    public static Geometry GetHandleGeometry(string handleName)
+    public static VectorPath GetHandleGeometry(string handleName)
     {
         if (Application.Current.Styles.TryGetResource(handleName, null, out object shape))
         {
-            return ((Path)shape).Data.Clone();
+            if (shape is string path)
+            {
+                return VectorPath.FromSvgPath(path);
+            }
         }
 
-        return Geometry.Parse("M 0 0 L 1 0 M 0 0 L 0 1");
+        return VectorPath.FromSvgPath("M 0 0 L 1 0 M 0 0 L 0 1");
     }
 
     protected static Paint? GetPaint(string key, PaintStyle style = PaintStyle.Fill)

+ 90 - 70
src/PixiEditor/Views/Overlays/SymmetryOverlay/SymmetryOverlay.cs

@@ -1,18 +1,17 @@
-using System.Globalization;
-using System.Windows.Input;
+using System.Windows.Input;
 using Avalonia;
 using Avalonia.Input;
-using Avalonia.Interactivity;
 using Avalonia.Media;
-using PixiEditor.Helpers;
-using PixiEditor.Models.Controllers.InputDevice;
 using PixiEditor.ChangeableDocument.Enums;
-using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Text;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
 using PixiEditor.Views.Overlays.Handles;
+using Colors = Drawie.Backend.Core.ColorsImpl.Colors;
 using Point = Avalonia.Point;
 
 namespace PixiEditor.Views.Overlays.SymmetryOverlay;
@@ -87,19 +86,19 @@ internal class SymmetryOverlay : Overlay
     public static readonly StyledProperty<VecI> SizeProperty = AvaloniaProperty.Register<SymmetryOverlay, VecI>(nameof(Size));
 
     private const double HandleSize = 12;
-    private Geometry handleGeometry = Handle.GetHandleGeometry("MarkerHandle");
+    private VectorPath handleGeometry = Handle.GetHandleGeometry("MarkerHandle");
 
-    private const double DashWidth = 10.0;
+    private const float DashWidth = 10.0f;
     const int RulerOffset = -35;
     const int RulerWidth = 4;
 
-    private Brush handleFill = new SolidColorBrush(Brushes.Transparent.Color, 0);
-    private Pen rulerPen = new(Brushes.White, 1.0);
-    private Pen borderPen = new(new SolidColorBrush(Color.FromRgb(200, 200, 200)), 1.0);
-    private Pen checkerBlack = new(new SolidColorBrush(Color.FromRgb(170, 170, 170)), 1.0) { DashStyle = new DashStyle(new[] { DashWidth, DashWidth }, 0) };
-    private Pen checkerWhite = new(new SolidColorBrush(Color.FromRgb(100, 100, 100)), 1.0) { DashStyle = new DashStyle(new[] { DashWidth, DashWidth }, DashWidth) };
-
-    private double PenThickness => 1.0 / ZoomScale;
+    private Paint rulerPen = new Paint() {Color = Colors.White, StrokeWidth = 1, IsAntiAliased = true, Style = PaintStyle.Stroke}; 
+    private Paint borderPen = new Paint { Color = Drawie.Backend.Core.ColorsImpl.Color.FromRgb(200, 200, 200), StrokeWidth = 0.25f, IsAntiAliased = true, Style = PaintStyle.Stroke };
+    private Paint checkerBlack = new Paint() { Color = Colors.Black, StrokeWidth = 1, IsAntiAliased = true, Style = PaintStyle.Stroke, PathEffect = PathEffect.CreateDash(new float[] { DashWidth, DashWidth }, 0) };
+    private Paint checkerWhite = new Paint() { Color = Colors.White, StrokeWidth = 1, IsAntiAliased = true, Style = PaintStyle.Stroke, PathEffect = PathEffect.CreateDash(new float[] { DashWidth, DashWidth }, DashWidth) };
+    private Paint textPaint = new Paint() { Color = Colors.White, IsAntiAliased = true, Style = PaintStyle.Fill };
+    
+    private float PenThickness => 1.0f / (float)ZoomScale;
 
     public VecI Size    
     {
@@ -123,16 +122,19 @@ internal class SymmetryOverlay : Overlay
 
     public override void RenderOverlay(Canvas drawingContext, RectD canvasBounds)
     {
-        /*base.Render(drawingContext);
         if (!HorizontalAxisVisible && !VerticalAxisVisible)
             return;
 
-        borderPen.Thickness = 3 * PenThickness;
-        checkerBlack.Thickness = PenThickness;
-        checkerWhite.Thickness = PenThickness;
-        rulerPen.Thickness = PenThickness;
+        checkerBlack.StrokeWidth = PenThickness;
+        float dashWidth = DashWidth / (float)ZoomScale;
+        checkerWhite.PathEffect?.Dispose();
+        checkerWhite.PathEffect = PathEffect.CreateDash(new float[] { dashWidth, dashWidth }, dashWidth);
+        
+        checkerBlack.PathEffect?.Dispose();
+        checkerBlack.PathEffect = PathEffect.CreateDash(new float[] { dashWidth, dashWidth }, 0);
+        checkerWhite.StrokeWidth = PenThickness;
+        rulerPen.StrokeWidth = PenThickness;
 
-        handleGeometry.Transform = new ScaleTransform(HandleSize / ZoomScale, HandleSize / ZoomScale);
 
         if (HorizontalAxisVisible)
         {
@@ -149,16 +151,24 @@ internal class SymmetryOverlay : Overlay
                 }
             }
 
-            var transformState = drawingContext.PushTransform(new TranslateTransform(0, horizontalAxisY).Value);
-            drawingContext.DrawGeometry(handleFill, borderPen, handleGeometry);
-            var rotateState = drawingContext.PushTransform(new RotateTransform(180, Size.X / 2, 0).Value);
-            drawingContext.DrawGeometry(handleFill, borderPen, handleGeometry);
-
-            rotateState.Dispose();
-            transformState.Dispose();
-
-            drawingContext.DrawLine(checkerBlack, new(0, horizontalAxisY), new(Size.X, horizontalAxisY));
-            drawingContext.DrawLine(checkerWhite, new(0, horizontalAxisY), new(Size.X, horizontalAxisY));
+            int save = drawingContext.Save();
+            drawingContext.Translate(0, (float)horizontalAxisY);
+            drawingContext.Scale((float)HandleSize / (float)ZoomScale, (float)HandleSize / (float)ZoomScale);
+            
+            drawingContext.DrawPath(handleGeometry, borderPen);
+            
+            drawingContext.RestoreToCount(save);
+            
+            save = drawingContext.Save();
+            drawingContext.Translate(0, (float)horizontalAxisY);
+            drawingContext.RotateDegrees(180, Size.X / 2, 0);
+            drawingContext.Scale((float)HandleSize / (float)ZoomScale, (float)HandleSize / (float)ZoomScale);
+            drawingContext.DrawPath(handleGeometry, borderPen);
+
+            drawingContext.RestoreToCount(save);
+
+            drawingContext.DrawLine(new(0, horizontalAxisY), new(Size.X, horizontalAxisY), checkerBlack);
+            drawingContext.DrawLine(new(0, horizontalAxisY), new(Size.X, horizontalAxisY), checkerWhite);
         }
         if (VerticalAxisVisible)
         {
@@ -175,83 +185,93 @@ internal class SymmetryOverlay : Overlay
                 }
             }
 
-            var rotation = drawingContext.PushTransform(new RotateTransform(90).Value);
-            var translation = drawingContext.PushTransform(new TranslateTransform(0, -verticalAxisX).Value);
-            drawingContext.DrawGeometry(handleFill, borderPen, handleGeometry);
-            var rotation1 = drawingContext.PushTransform(new RotateTransform(180, Size.Y / 2, 0).Value);
-            drawingContext.DrawGeometry(handleFill, borderPen, handleGeometry);
-
-            rotation1.Dispose();
-            translation.Dispose();
-            rotation.Dispose();
-
-            drawingContext.DrawLine(checkerBlack, new(verticalAxisX, 0), new(verticalAxisX, Size.Y));
-            drawingContext.DrawLine(checkerWhite, new(verticalAxisX, 0), new(verticalAxisX, Size.Y));
-        }*/
+            int saved = drawingContext.Save();
+            
+            drawingContext.RotateDegrees(90);
+            drawingContext.Translate(0, (float)-verticalAxisX);
+            drawingContext.Scale((float)HandleSize / (float)ZoomScale, (float)HandleSize / (float)ZoomScale);
+            
+            drawingContext.DrawPath(handleGeometry, borderPen);
+            
+            drawingContext.RestoreToCount(saved);
+            
+            saved = drawingContext.Save();
+            drawingContext.RotateDegrees(90);
+            drawingContext.Translate(0, (float)-verticalAxisX);
+            drawingContext.RotateDegrees(180, Size.Y / 2, 0);
+            drawingContext.Scale((float)HandleSize / (float)ZoomScale, (float)HandleSize / (float)ZoomScale);
+            drawingContext.DrawPath(handleGeometry, borderPen);
+
+            drawingContext.RestoreToCount(saved);
+
+            drawingContext.DrawLine(new(verticalAxisX, 0), new(verticalAxisX, Size.Y), checkerBlack);
+            drawingContext.DrawLine(new(verticalAxisX, 0), new(verticalAxisX, Size.Y), checkerWhite);
+        }
     }
 
-    private void DrawHorizontalRuler(DrawingContext drawingContext, bool upper)
+    private void DrawHorizontalRuler(Canvas drawingContext, bool upper)
     {
         double start = upper ? Size.Y : 0;
         bool drawRight = pointerPosition.X > Size.X / 2;
         double xOffset = drawRight ? Size.X - RulerOffset * PenThickness * 2 : 0;
 
-        drawingContext.DrawLine(rulerPen, new Point(RulerOffset * PenThickness + xOffset, start), new Point(RulerOffset * PenThickness + xOffset, horizontalAxisY));
-        drawingContext.DrawLine(rulerPen, new Point((RulerOffset - RulerWidth) * PenThickness + xOffset, start), new Point((RulerOffset + RulerWidth) * PenThickness + xOffset, start));
-        drawingContext.DrawLine(rulerPen, new Point((RulerOffset - RulerWidth) * PenThickness + xOffset, horizontalAxisY), new Point((RulerOffset + RulerWidth) * PenThickness + xOffset, horizontalAxisY));
+        drawingContext.DrawLine(new VecD(RulerOffset * PenThickness + xOffset, start), new VecD(RulerOffset * PenThickness + xOffset, horizontalAxisY), rulerPen);
+        drawingContext.DrawLine(new VecD((RulerOffset - RulerWidth) * PenThickness + xOffset, start), new VecD((RulerOffset + RulerWidth) * PenThickness + xOffset, start), rulerPen);
+        drawingContext.DrawLine(new VecD((RulerOffset - RulerWidth) * PenThickness + xOffset, horizontalAxisY), new VecD((RulerOffset + RulerWidth) * PenThickness + xOffset, horizontalAxisY), rulerPen);
 
-        string text = upper ? $"{start - horizontalAxisY}{new LocalizedString("PIXEL_UNIT")} ({(start - horizontalAxisY) / Size.Y * 100:F1}%)" : $"{horizontalAxisY}{new LocalizedString("PIXEL_UNIT")} ({horizontalAxisY / Size.Y * 100:F1}%)";
+        string text = upper ? $"{start - horizontalAxisY}{new LocalizedString("PIXEL_UNIT")} ({(start - horizontalAxisY) / Size.Y * 100:F1}%)" : $"{horizontalAxisY}{new LocalizedString("PIXEL_UNIT")} ({horizontalAxisY / Size.Y * 100:F1}%)";
 
-        var formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
-            ILocalizationProvider.Current.CurrentLanguage.FlowDirection, new Typeface("Segeo UI"), 14.0 / ZoomScale, Brushes.White);
+        /*var formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
+            ILocalizationProvider.Current.CurrentLanguage.FlowDirection, new Typeface("Segeo UI"), 14.0 / ZoomScale, Brushes.White);*/
 
-        if (Size.Y < formattedText.Height * 2.5 || horizontalAxisY == (int)Size.Y && upper || horizontalAxisY == 0 && !upper)
+        using Font font = Font.CreateDefault(14f / (float)ZoomScale);
+        
+        if (Size.Y < font.FontSize * 2.5 || horizontalAxisY == (int)Size.Y && upper || horizontalAxisY == 0 && !upper)
         {
             return;
         }
 
-        formattedText.TextAlignment = drawRight ? TextAlignment.Left : TextAlignment.Right;
-
-        double textY = horizontalAxisY / 2.0 - formattedText.Height / 2;
+        double textY = horizontalAxisY / 2.0 - font.FontSize / 2;
 
         if (upper)
         {
-            textY += Size.Y / 2;
+            textY += Size.Y / 2f;
         }
 
-        drawingContext.DrawText(formattedText, new Point(RulerOffset * PenThickness - (drawRight ? -1 : 1) + xOffset, textY));
+        drawingContext.DrawText(text, new VecD(RulerOffset * PenThickness - (drawRight ? -1 : 1) + xOffset, textY), drawRight ? TextAlign.Left : TextAlign.Right, font, textPaint);
     }
 
-    private void DrawVerticalRuler(DrawingContext drawingContext, bool right)
+    private void DrawVerticalRuler(Canvas drawingContext, bool right)
     {
         double start = right ? Size.X : 0;
         bool drawBottom = pointerPosition.Y > Size.Y / 2;
         double yOffset = drawBottom ? Size.Y - RulerOffset * PenThickness * 2 : 0;
 
-        drawingContext.DrawLine(rulerPen, new Point(start, RulerOffset * PenThickness + yOffset), new Point(verticalAxisX, RulerOffset * PenThickness + yOffset));
-        drawingContext.DrawLine(rulerPen, new Point(start, (RulerOffset - RulerWidth) * PenThickness + yOffset), new Point(start, (RulerOffset + RulerWidth) * PenThickness + yOffset));
-        drawingContext.DrawLine(rulerPen, new Point(verticalAxisX, (RulerOffset - RulerWidth) * PenThickness + yOffset), new Point(verticalAxisX, (RulerOffset + RulerWidth) * PenThickness + yOffset));
+        drawingContext.DrawLine(new VecD(start, RulerOffset * PenThickness + yOffset), new VecD(verticalAxisX, RulerOffset * PenThickness + yOffset), rulerPen);
+        drawingContext.DrawLine(new VecD(start, (RulerOffset - RulerWidth) * PenThickness + yOffset), new VecD(start, (RulerOffset + RulerWidth) * PenThickness + yOffset), rulerPen);
+        drawingContext.DrawLine(new VecD(verticalAxisX, (RulerOffset - RulerWidth) * PenThickness + yOffset), new VecD(verticalAxisX, (RulerOffset + RulerWidth) * PenThickness + yOffset), rulerPen);
 
-        string text = right ? $"{start - verticalAxisX}{new LocalizedString("PIXEL_UNIT")} ({(start - verticalAxisX) / Size.X * 100:F1}%)" : $"{verticalAxisX}{new LocalizedString("PIXEL_UNIT")} ({verticalAxisX / Size.X * 100:F1}%)";
+        string text = right ? $"{start - verticalAxisX}{new LocalizedString("PIXEL_UNIT")} ({(start - verticalAxisX) / Size.X * 100:F1}%)" : $"{verticalAxisX}{new LocalizedString("PIXEL_UNIT")} ({verticalAxisX / Size.X * 100:F1}%)";
 
-        var formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
-            ILocalizationProvider.Current.CurrentLanguage.FlowDirection, new Typeface("Segeo UI"), 14.0 / ZoomScale, Brushes.White);
+        /*var formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
+            ILocalizationProvider.Current.CurrentLanguage.FlowDirection, new Typeface("Segeo UI"), 14.0 / ZoomScale, Brushes.White);*/
 
-        if (Size.X < formattedText.Width * 2.5 || verticalAxisX == (int)Size.X && right || verticalAxisX == 0 && !right)
+        using Font font = Font.CreateDefault(14f / (float)ZoomScale);
+        
+        if (Size.X < font.MeasureText(text) * 2.5 || verticalAxisX == (int)Size.X && right || verticalAxisX == 0 && !right)
         {
             return;
         }
 
-        formattedText.TextAlignment = TextAlignment.Center;
-
-        double textX = verticalAxisX / 2.0;
+        double textX = verticalAxisX / 2;
 
         if (right)
         {
             textX += Size.X / 2;
         }
 
-        drawingContext.DrawText(formattedText, new Point(textX, RulerOffset * PenThickness - (drawBottom ? -0.7 : 0.3 + formattedText.Height) + yOffset));
+        double textY = RulerOffset * PenThickness - ((drawBottom ? 5 : 2 + font.FontSize) * PenThickness) + yOffset;
+        drawingContext.DrawText(text, new VecD(textX, textY), TextAlign.Center, font, textPaint);
     }
 
     public override bool TestHit(VecD point)
@@ -282,7 +302,7 @@ internal class SymmetryOverlay : Overlay
         {
             SymmetryAxisDirection.Horizontal => new Cursor(StandardCursorType.SizeNorthSouth),
             SymmetryAxisDirection.Vertical => new Cursor(StandardCursorType.SizeWestEast),
-            _ => new Cursor(StandardCursorType.Arrow)
+            _ => null 
         };
 
         if (hoveredDirection == direction)

+ 5 - 4
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -11,6 +11,7 @@ using PixiEditor.Helpers;
 using PixiEditor.Helpers.Extensions;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.Vector;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Helpers.UI;
 using PixiEditor.Models.Controllers.InputDevice;
@@ -174,7 +175,7 @@ internal class TransformOverlay : Overlay
     private List<Handle> snapPoints = new();
     private Handle? snapHandleOfOrigin;
 
-    private Geometry rotateCursorGeometry = Handle.GetHandleGeometry("RotateHandle");
+    private VectorPath rotateCursorGeometry = Handle.GetHandleGeometry("RotateHandle");
 
     private VecD lastPointerPos;
 
@@ -360,7 +361,7 @@ internal class TransformOverlay : Overlay
 
     protected override void OnOverlayPointerExited(OverlayPointerArgs args)
     {
-        rotateCursorGeometry.Transform = new ScaleTransform(0, 0);
+        //rotateCursorGeometry.Transform = new ScaleTransform(0, 0);
         Refresh();
     }
 
@@ -564,7 +565,7 @@ internal class TransformOverlay : Overlay
     {
         if ((!CanRotate(mousePos) && !isRotating) || LockRotation)
         {
-            rotateCursorGeometry.Transform = new ScaleTransform(0, 0);
+            //rotateCursorGeometry.Transform = new ScaleTransform(0, 0);
             return false;
         }
 
@@ -572,7 +573,7 @@ internal class TransformOverlay : Overlay
         double angle = (mousePos - InternalState.Origin).Angle * 180 / Math.PI - 90;
         matrix = matrix.RotateAt(angle, mousePos.X, mousePos.Y);
         matrix = matrix.ScaleAt(8 / ZoomScale, 8 / ZoomScale, mousePos.X, mousePos.Y);
-        rotateCursorGeometry.Transform = new MatrixTransform(matrix);
+        //rotateCursorGeometry.Transform = new MatrixTransform(matrix);
         return true;
     }
 

+ 1 - 11
src/PixiEditor/Views/Rendering/Scene.cs

@@ -234,7 +234,7 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         renderTexture.Canvas.SetMatrix(matrix.ToSKMatrix().ToMatrix3X3());
 
         RectD dirtyBounds = new RectD(0, 0, Document.Width, Document.Height);
-        Cursor = DefaultCursor;
+        //Cursor = DefaultCursor;
         RenderScene(dirtyBounds);
 
         renderTexture.Canvas.Restore();
@@ -328,16 +328,6 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         }
     }
 
-    private void DrawCheckerboard(DrawingContext context, Rect dirtyBounds, RectI operationSurfaceRectToRender)
-    {
-        DrawCheckerBackgroundOperation checkerOperation = new DrawCheckerBackgroundOperation(
-            dirtyBounds,
-            (SKBitmap)checkerBitmap.Native,
-            (float)Scale,
-            operationSurfaceRectToRender.ToSkRect());
-        context.Custom(checkerOperation);
-    }
-
     protected override void OnPointerEntered(PointerEventArgs e)
     {
         base.OnPointerEntered(e);