Browse Source

baby steps

Krzysztof Krysiński 4 years ago
parent
commit
a1c0bede78

+ 4 - 6
PixiEditor/Models/Tools/ShapeTool.cs

@@ -58,17 +58,15 @@ namespace PixiEditor.Models.Tools
         // TODO: Add cache for lines 31, 32 (hopefully it would speed up calculation)
         public abstract override void Use(Layer layer, List<Coordinates> coordinates, Color color);
 
-        protected static IEnumerable<Coordinates> GetThickShape(IEnumerable<Coordinates> shape, int thickness)
+        protected static void ThickenShape(Layer layer, Color color, IEnumerable<Coordinates> shape, int thickness)
         {
-            List<Coordinates> output = new List<Coordinates>();
             foreach (Coordinates item in shape)
             {
-                output.AddRange(
+                var changes = BitmapPixelChanges.FromSingleColoredArray(
                     CoordinatesCalculator.RectangleToCoordinates(
-                        CoordinatesCalculator.CalculateThicknessCenter(item, thickness)));
+                   CoordinatesCalculator.CalculateThicknessCenter(item, thickness)), color);
+                layer.SetPixels(changes);
             }
-
-            return output.Distinct();
         }
     }
 }

+ 26 - 20
PixiEditor/Models/Tools/Tools/CircleTool.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Windows.Input;
 using System.Windows.Media;
+using System.Windows.Media.Imaging;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Layers;
@@ -79,33 +80,25 @@ namespace PixiEditor.Models.Tools.Tools
         /// <param name="startCoordinates">Top left coordinate of ellipse.</param>
         /// <param name="endCoordinates">Bottom right coordinate of ellipse.</param>
         /// <param name="thickness">Thickness of ellipse.</param>
-        /// <returns>Coordinates for ellipse.</returns>
-        public IEnumerable<Coordinates> CreateEllipse(Coordinates startCoordinates, Coordinates endCoordinates, int thickness)
+        public void CreateEllipse(Layer layer, Color color, Coordinates startCoordinates, Coordinates endCoordinates, int thickness)
         {
             double radiusX = (endCoordinates.X - startCoordinates.X) / 2.0;
             double radiusY = (endCoordinates.Y - startCoordinates.Y) / 2.0;
             double centerX = (startCoordinates.X + endCoordinates.X + 1) / 2.0;
             double centerY = (startCoordinates.Y + endCoordinates.Y + 1) / 2.0;
 
-            List<Coordinates> output = new List<Coordinates>();
-            IEnumerable<Coordinates> ellipse = MidpointEllipse(radiusX, radiusY, centerX, centerY);
-            if (thickness == 1)
+            IEnumerable<Coordinates> ellipse = GenerateMidpointEllipse(radiusX, radiusY, centerX, centerY);
+            if (thickness > 1)
             {
-                output.AddRange(ellipse);
+                ThickenShape(layer, color, ellipse, thickness);
             }
-            else
-            {
-                output.AddRange(GetThickShape(ellipse, thickness));
-            }
-
-            return output.Distinct();
         }
 
-        public IEnumerable<Coordinates> MidpointEllipse(double halfWidth, double halfHeight, double centerX, double centerY)
+        public List<Coordinates> GenerateMidpointEllipse(Layer layer, Color color, double halfWidth, double halfHeight, double centerX, double centerY)
         {
             if (halfWidth < 1 || halfHeight < 1)
             {
-                return FallbackRectangle(halfWidth, halfHeight, centerX, centerY);
+                return FallbackRectangle(layer, color, halfWidth, halfHeight, centerX, centerY);
             }
 
             // ellipse formula: halfHeight^2 * x^2 + halfWidth^2 * y^2 - halfHeight^2 * halfWidth^2 = 0
@@ -182,22 +175,35 @@ namespace PixiEditor.Models.Tools.Tools
             return finalCoordinates;
         }
 
-        private Coordinates[] FallbackRectangle(double halfWidth, double halfHeight, double centerX, double centerY)
+        private List<Coordinates> FallbackRectangle(Layer layer, Color color, double halfWidth, double halfHeight, double centerX, double centerY)
         {
+            using var ctx = layer.LayerBitmap.GetBitmapContext();
+
             List<Coordinates> coordinates = new List<Coordinates>();
+
             for (double x = centerX - halfWidth; x <= centerX + halfWidth; x++)
             {
-                coordinates.Add(new Coordinates((int)x, (int)(centerY - halfHeight)));
-                coordinates.Add(new Coordinates((int)x, (int)(centerY + halfHeight)));
+                var cords = new Coordinates((int)x, (int)(centerY - halfHeight));
+                coordinates.Add(cords);
+                layer.SetPixel(cords, color);
+
+                cords = new Coordinates((int)x, (int)(centerY + halfHeight));
+                coordinates.Add(cords);
+                layer.SetPixel(cords, color);
             }
 
             for (double y = centerY - halfHeight + 1; y <= centerY + halfHeight - 1; y++)
             {
-                coordinates.Add(new Coordinates((int)(centerX - halfWidth), (int)y));
-                coordinates.Add(new Coordinates((int)(centerX + halfWidth), (int)y));
+                var cords = new Coordinates((int)(centerX - halfWidth), (int)y);
+                coordinates.Add(cords);
+                layer.SetPixel(cords, color);
+
+                cords = new Coordinates((int)(centerX + halfWidth), (int)y);
+                coordinates.Add(cords);
+                layer.SetPixel(cords, color);
             }
 
-            return coordinates.ToArray();
+            return coordinates;
         }
 
         private Coordinates[] GetRegionPoints(double x, double xc, double y, double yc)

+ 39 - 27
PixiEditor/Models/Tools/Tools/LineTool.cs

@@ -44,73 +44,73 @@ namespace PixiEditor.Models.Tools.Tools
         public override void Use(Layer layer, List<Coordinates> coordinates, Color color)
         {
             CreateLine(
+                layer, color,
                 coordinates,
                 Toolbar.GetSetting<SizeSetting>("ToolSize").Value,
                 CapType.Square,
                 CapType.Square);
         }
 
-        public void CreateLine(Coordinates start, Coordinates end, int thickness)
+        public void CreateLine(Layer layer, Color color, Coordinates start, Coordinates end, int thickness)
         {
-            CreateLineFastest(start, end, thickness);
+            CreateLineFastest(layer, color, start, end, thickness);
         }
 
-        public void CreateLine(Coordinates start, Coordinates end, int thickness, CapType startCap, CapType endCap)
+        public void CreateLine(Layer layer, Color color, Coordinates start, Coordinates end, int thickness, CapType startCap, CapType endCap)
         {
-            CreateLine(new List<Coordinates>() { end, start }, thickness, startCap, endCap);
+            CreateLine(layer, color, new List<Coordinates>() { end, start }, thickness, startCap, endCap);
         }
 
-        private void CreateLine(IEnumerable<Coordinates> coordinates, int thickness, CapType startCap, CapType endCap)
+        private void CreateLine(Layer layer, Color color, IEnumerable<Coordinates> coordinates, int thickness, CapType startCap, CapType endCap)
         {
             Coordinates startingCoordinates = coordinates.Last();
             Coordinates latestCoordinates = coordinates.First();
             if (thickness == 1)
             {
-                BresenhamLine(startingCoordinates.X, startingCoordinates.Y, latestCoordinates.X, latestCoordinates.Y);
+                BresenhamLine(layer, color, startingCoordinates.X, startingCoordinates.Y, latestCoordinates.X, latestCoordinates.Y);
             }
 
-            GetLinePoints(startingCoordinates, latestCoordinates, thickness, startCap, endCap);
+            GenerateLine(layer, color, startingCoordinates, latestCoordinates, thickness, startCap, endCap);
         }
 
-        private IEnumerable<Coordinates> CreateLineFastest(Coordinates start, Coordinates end, int thickness)
+        private void CreateLineFastest(Layer layer, Color color, Coordinates start, Coordinates end, int thickness)
         {
-            IEnumerable<Coordinates> line = BresenhamLine(start.X, start.Y, end.X, end.Y);
+            var line = BresenhamLine(layer, color, start.X, start.Y, end.X, end.Y);
             if (thickness == 1)
             {
-                return line;
+                return;
             }
 
-            return GetThickShape(line, thickness);
+            ThickenShape(layer, color, line, thickness);
         }
 
-        private void GetLinePoints(Coordinates start, Coordinates end, int thickness, CapType startCap, CapType endCap)
+        private void GenerateLine(Layer layer, Color color, Coordinates start, Coordinates end, int thickness, CapType startCap, CapType endCap)
         {
-            GetCapCoordinates(startCap, start, thickness);
+            ApplyCap(layer, color, startCap, start, thickness);
             if (start == end)
             {
                 return;
             }
 
-            BresenhamLine(start.X, start.Y, end.X, end.Y);
+            var line = BresenhamLine(layer, color, start.X, start.Y, end.X, end.Y);
 
-            GetCapCoordinates(endCap, end, thickness);
+            ApplyCap(layer, color, endCap, end, thickness);
             if (line.Count() > 2)
             {
-                output.AddRange(GetThickShape(line.Except(new[] { start, end }), thickness));
+                ThickenShape(layer, color, line.Except(new[] { start, end }), thickness);
             }
         }
 
-        private void GetCapCoordinates(CapType cap, Coordinates position, int thickness)
+        private void ApplyCap(Layer layer, Color color, CapType cap, Coordinates position, int thickness)
         {
             switch (cap)
             {
                 case CapType.Round:
-
-                    GetRoundCap(position, thickness); // Round cap is not working very well, circle tool must be improved
+                    ApplyRoundCap(position, thickness); // Round cap is not working very well, circle tool must be improved
                     break;
 
                 default:
-                    GetThickShape(new[] { position }, thickness);
+                    ThickenShape(layer, color, new[] { position }, thickness);
                     break;
             }
         }
@@ -120,19 +120,23 @@ namespace PixiEditor.Models.Tools.Tools
         /// </summary>
         /// <param name="position">Starting position of cap.</param>
         /// <param name="thickness">Thickness of cap.</param>
-        private void GetRoundCap(Coordinates position, int thickness)
+        private void ApplyRoundCap(Coordinates position, int thickness)
         {
             IEnumerable<Coordinates> rectangleCords = CoordinatesCalculator.RectangleToCoordinates(
                 CoordinatesCalculator.CalculateThicknessCenter(position, thickness));
             circleTool.CreateEllipse(rectangleCords.First(), rectangleCords.Last(), 1, true);
         }
 
-        private void BresenhamLine(Layer layer, Color color, int x1, int y1, int x2, int y2)
+        private List<Coordinates> BresenhamLine(Layer layer, Color color, int x1, int y1, int x2, int y2)
         {
-            using var context = layer.LayerBitmap.GetBitmapContext();
+            using BitmapContext context = layer.LayerBitmap.GetBitmapContext();
+            Coordinates cords;
+            List<Coordinates> linePoints = new List<Coordinates>();
             if (x1 == x2 && y1 == y2)
             {
-                layer.SetPixel(new Coordinates(x1, y1), color);
+                cords = new Coordinates(x1, y1);
+                layer.SetPixel(cords, color);
+                linePoints.Add(cords);
             }
 
             int d, dx, dy, ai, bi, xi, yi;
@@ -160,7 +164,9 @@ namespace PixiEditor.Models.Tools.Tools
                 dy = y1 - y2;
             }
 
-            layer.SetPixel(new Coordinates(x, y), color);
+            cords = new Coordinates(x, y);
+            layer.SetPixel(cords, color);
+            linePoints.Add(cords);
 
             if (dx > dy)
             {
@@ -182,7 +188,9 @@ namespace PixiEditor.Models.Tools.Tools
                         x += xi;
                     }
 
-                    layer.SetPixel(new Coordinates(x, y), color);
+                    cords = new Coordinates(x, y);
+                    layer.SetPixel(cords, color);
+                    linePoints.Add(cords);
                 }
             }
             else
@@ -205,9 +213,13 @@ namespace PixiEditor.Models.Tools.Tools
                         y += yi;
                     }
 
-                    layer.SetPixel(new Coordinates(x, y), color);
+                    cords = new Coordinates(x, y);
+                    layer.SetPixel(cords, color);
+                    linePoints.Add(cords);
                 }
             }
+
+            return linePoints;
         }
     }
 }

+ 14 - 22
PixiEditor/Models/Tools/Tools/PenTool.cs

@@ -51,7 +51,8 @@ namespace PixiEditor.Models.Tools.Tools
         public override void Use(Layer layer, List<Coordinates> coordinates, Color color)
         {
             Coordinates startingCords = coordinates.Count > 1 ? coordinates[1] : coordinates[0];
-            BitmapPixelChanges pixels = Draw(
+            Draw(
+                layer,
                 startingCords,
                 coordinates[0],
                 color,
@@ -60,12 +61,12 @@ namespace PixiEditor.Models.Tools.Tools
                 BitmapManager.ActiveDocument.PreviewLayer);
         }
 
-        public BitmapPixelChanges Draw(Coordinates startingCoords, Coordinates latestCords, Color color, int toolSize, bool pixelPerfect = false, Layer previewLayer = null)
+        public void Draw(Layer layer, Coordinates startingCoords, Coordinates latestCords, Color color, int toolSize, bool pixelPerfect = false, Layer previewLayer = null)
         {
             if (!pixelPerfect)
             {
-                return BitmapPixelChanges.FromSingleColoredArray(
-                    lineTool.CreateLine(startingCoords, latestCords, toolSize), color);
+                lineTool.CreateLine(layer, color, startingCoords, latestCords, toolSize);
+                return;
             }
 
             if (previewLayer != null && previewLayer.GetPixelWithOffset(latestCords.X, latestCords.Y).A > 0)
@@ -78,7 +79,7 @@ namespace PixiEditor.Models.Tools.Tools
 
             if (changedPixelsindex == 2)
             {
-                var changes = ApplyPixelPerfectToPixels(
+                ApplyPixelPerfectToPixels(
                     lastChangedPixels[0],
                     lastChangedPixels[1],
                     lastChangedPixels[2],
@@ -87,20 +88,15 @@ namespace PixiEditor.Models.Tools.Tools
 
                 MovePixelsToCheck(changes);
 
-                changes.ChangedPixels.AddRangeNewOnly(
-                    BitmapPixelChanges.FromSingleColoredArray(GetThickShape(latestPixels, toolSize), color).ChangedPixels);
-
-                return changes;
+                ThickenShape(latestPixels, toolSize);
             }
 
             changedPixelsindex += changedPixelsindex >= 2 ? (byte)0 : (byte)1;
 
-            var result = BitmapPixelChanges.FromSingleColoredArray(GetThickShape(latestPixels, toolSize), color);
-
-            return result;
+            ThickenShape(latestPixels, toolSize);
         }
-		public override bool UsesShift => false;
-		private void MovePixelsToCheck(BitmapPixelChanges changes)
+        public override bool UsesShift => false;
+        private void MovePixelsToCheck(BitmapPixelChanges changes)
         {
             if (changes.ChangedPixels[lastChangedPixels[1]].A != 0)
             {
@@ -127,19 +123,15 @@ namespace PixiEditor.Models.Tools.Tools
             }
         }
 
-        private BitmapPixelChanges ApplyPixelPerfectToPixels(Coordinates p1, Coordinates p2, Coordinates p3, Color color, int toolSize)
+        private void ApplyPixelPerfectToPixels(Coordinates p1, Coordinates p2, Coordinates p3, Color color, int toolSize)
         {
             if (Math.Abs(p3.X - p1.X) == 1 && Math.Abs(p3.Y - p1.Y) == 1 && !confirmedPixels.Contains(p2))
             {
-                var changes = BitmapPixelChanges.FromSingleColoredArray(GetThickShape(new Coordinates[] { p1, p3 }, toolSize), color);
-                changes.ChangedPixels.AddRangeNewOnly(
-                    BitmapPixelChanges.FromSingleColoredArray(
-                        GetThickShape(new[] { p2 }, toolSize),
-                        System.Windows.Media.Colors.Transparent).ChangedPixels);
-                return changes;
+                ThickenShape(new Coordinates[] { p1, p3 }, toolSize);
+                ThickenShape(new[] { p2 }, toolSize);
             }
 
-            return BitmapPixelChanges.FromSingleColoredArray(GetThickShape(new Coordinates[] { p2, p3 }.Distinct(), toolSize), color);
+            ThickenShape(new Coordinates[] { p2, p3 }.Distinct(), toolSize);
         }
 
         private void PixelPerfectSettingValueChanged(object sender, SettingValueChangedEventArgs<bool> e)