Skip to content

Commit

Permalink
Fix ellipse drawing algorithm and brightness tool
Browse files Browse the repository at this point in the history
  • Loading branch information
Equbuxu committed Dec 3, 2021
1 parent 337bee7 commit 748ae49
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 94 deletions.
8 changes: 4 additions & 4 deletions PixiEditor/Models/DataHolders/Document/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void RaisePropertyChange(string name)
/// </summary>
public void ClipCanvas()
{
DoubleCords points = GetEdgePoints(Layers);
DoubleCoords points = GetEdgePoints(Layers);
int smallestX = points.Coords1.X;
int smallestY = points.Coords1.Y;
int biggestX = points.Coords2.X;
Expand Down Expand Up @@ -157,7 +157,7 @@ public void CenterContent()
return;
}

DoubleCords points = GetEdgePoints(layersToCenter);
DoubleCoords points = GetEdgePoints(layersToCenter);

int smallestX = points.Coords1.X;
int smallestY = points.Coords1.Y;
Expand Down Expand Up @@ -238,7 +238,7 @@ private int GetOffsetYForAnchor(int srcHeight, int destHeight, AnchorPoint ancho
return 0;
}

private DoubleCords GetEdgePoints(IEnumerable<Layer> layers)
private DoubleCoords GetEdgePoints(IEnumerable<Layer> layers)
{
if (Layers.Count == 0)
{
Expand Down Expand Up @@ -274,7 +274,7 @@ private DoubleCords GetEdgePoints(IEnumerable<Layer> layers)
}
}

return new DoubleCords(
return new DoubleCoords(
new Coordinates(smallestX, smallestY),
new Coordinates(biggestX, biggestY));
}
Expand Down
26 changes: 13 additions & 13 deletions PixiEditor/Models/ImageManipulation/ToolCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public static void GetLinearFillAbsolute(Layer layer, Coordinates startingCoords
List<Coordinates> output)
{

DoubleCords fixedCoordinates = CalculateCoordinatesForShapeRotation(start, end);
DoubleCoords fixedCoordinates = CalculateCoordinatesForShapeRotation(start, end);

CreateEllipse(fixedCoordinates.Coords1, fixedCoordinates.Coords2, output);

Expand All @@ -131,21 +131,21 @@ public static void GetLinearFillAbsolute(Layer layer, Coordinates startingCoords
Coordinates start,
Coordinates end, bool fill, int thickness, List<Coordinates> output)
{
DoubleCords fixedCoordinates = CalculateCoordinatesForShapeRotation(start, end);
DoubleCoords fixedCoordinates = CalculateCoordinatesForShapeRotation(start, end);
CalculateRectanglePoints(fixedCoordinates, output);

for (int i = 1; i < (int)Math.Floor(thickness / 2f) + 1; i++)
{
CalculateRectanglePoints(
new DoubleCords(
new DoubleCoords(
new Coordinates(fixedCoordinates.Coords1.X - i, fixedCoordinates.Coords1.Y - i),
new Coordinates(fixedCoordinates.Coords2.X + i, fixedCoordinates.Coords2.Y + i)), output);
}

for (int i = 1; i < (int)Math.Ceiling(thickness / 2f); i++)
{
CalculateRectanglePoints(
new DoubleCords(
new DoubleCoords(
new Coordinates(fixedCoordinates.Coords1.X + i, fixedCoordinates.Coords1.Y + i),
new Coordinates(fixedCoordinates.Coords2.X - i, fixedCoordinates.Coords2.Y - i)), output);
}
Expand All @@ -156,41 +156,41 @@ public static void GetLinearFillAbsolute(Layer layer, Coordinates startingCoords
}
}

public static DoubleCords CalculateCoordinatesForShapeRotation(
public static DoubleCoords CalculateCoordinatesForShapeRotation(
Coordinates startingCords,
Coordinates secondCoordinates)
{
Coordinates currentCoordinates = secondCoordinates;

if (startingCords.X > currentCoordinates.X && startingCords.Y > currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(currentCoordinates.X, currentCoordinates.Y),
new Coordinates(startingCords.X, startingCords.Y));
}

if (startingCords.X < currentCoordinates.X && startingCords.Y < currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(startingCords.X, startingCords.Y),
new Coordinates(currentCoordinates.X, currentCoordinates.Y));
}

if (startingCords.Y > currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(startingCords.X, currentCoordinates.Y),
new Coordinates(currentCoordinates.X, startingCords.Y));
}

if (startingCords.X > currentCoordinates.X && startingCords.Y <= currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(currentCoordinates.X, startingCords.Y),
new Coordinates(startingCords.X, currentCoordinates.Y));
}

return new DoubleCords(startingCords, secondCoordinates);
return new DoubleCoords(startingCords, secondCoordinates);
}

private static void CalculateFillForEllipse(List<Coordinates> outlineCoordinates)
Expand Down Expand Up @@ -308,9 +308,9 @@ private static void GetRegionPoints(double x, double xc, double y, double yc, Li
private static void CalculateRectangleFillNonAlloc(Coordinates start, Coordinates end, int thickness, List<Coordinates> output)
{
int offset = (int)Math.Ceiling(thickness / 2f);
DoubleCords fixedCords = CalculateCoordinatesForShapeRotation(start, end);
DoubleCoords fixedCords = CalculateCoordinatesForShapeRotation(start, end);

DoubleCords innerCords = new DoubleCords
DoubleCoords innerCords = new DoubleCoords
{
Coords1 = new Coordinates(fixedCords.Coords1.X + offset, fixedCords.Coords1.Y + offset),
Coords2 = new Coordinates(fixedCords.Coords2.X - (offset - 1), fixedCords.Coords2.Y - (offset - 1))
Expand All @@ -335,7 +335,7 @@ private static void CalculateRectangleFillNonAlloc(Coordinates start, Coordinate
}
}

private static void CalculateRectanglePoints(DoubleCords coordinates, List<Coordinates> output)
private static void CalculateRectanglePoints(DoubleCoords coordinates, List<Coordinates> output)
{
for (int i = coordinates.Coords1.X; i < coordinates.Coords2.X + 1; i++)
{
Expand Down
16 changes: 8 additions & 8 deletions PixiEditor/Models/Layers/Layer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,8 @@ public void DynamicResize(BitmapPixelChanges pixels)
}

ResetOffset(pixels);
Tuple<DoubleCords, bool> borderData = ExtractBorderData(pixels);
DoubleCords minMaxCords = borderData.Item1;
Tuple<DoubleCoords, bool> borderData = ExtractBorderData(pixels);
DoubleCoords minMaxCords = borderData.Item1;
int newMaxX = minMaxCords.Coords2.X - OffsetX;
int newMaxY = minMaxCords.Coords2.Y - OffsetY;
int newMinX = minMaxCords.Coords1.X - OffsetX;
Expand Down Expand Up @@ -463,7 +463,7 @@ public void DynamicResizeRelative(int newMaxX, int newMaxY, int newMinX, int new

public Int32Rect GetContentDimensions()
{
DoubleCords points = GetEdgePoints();
DoubleCoords points = GetEdgePoints();
int smallestX = points.Coords1.X;
int smallestY = points.Coords1.Y;
int biggestX = points.Coords2.X;
Expand Down Expand Up @@ -557,7 +557,7 @@ public void Crop(SKRectI intersect)
d => d.Value);
}

private Tuple<DoubleCords, bool> ExtractBorderData(BitmapPixelChanges pixels)
private Tuple<DoubleCoords, bool> ExtractBorderData(BitmapPixelChanges pixels)
{
Coordinates firstCords = pixels.ChangedPixels.First().Key;
int minX = firstCords.X;
Expand Down Expand Up @@ -592,8 +592,8 @@ public void Crop(SKRectI intersect)
}
}

return new Tuple<DoubleCords, bool>(
new DoubleCords(new Coordinates(minX, minY), new Coordinates(maxX, maxY)), clipRequested);
return new Tuple<DoubleCoords, bool>(
new DoubleCoords(new Coordinates(minX, minY), new Coordinates(maxX, maxY)), clipRequested);
}

private bool IsBorderPixel(Coordinates cords)
Expand Down Expand Up @@ -649,12 +649,12 @@ private void IncreaseSizeToTopAndLeft(int newMinX, int newMinY)
ResizeCanvas(offsetX, offsetY, 0, 0, newWidth, newHeight);
}

private DoubleCords GetEdgePoints()
private DoubleCoords GetEdgePoints()
{
Coordinates smallestPixel = CoordinatesCalculator.FindMinEdgeNonTransparentPixel(LayerBitmap);
Coordinates biggestPixel = CoordinatesCalculator.FindMostEdgeNonTransparentPixel(LayerBitmap);

return new DoubleCords(smallestPixel, biggestPixel);
return new DoubleCoords(smallestPixel, biggestPixel);
}

private void ResetOffset(BitmapPixelChanges pixels)
Expand Down
6 changes: 3 additions & 3 deletions PixiEditor/Models/Position/CoordinatesCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class CoordinatesCalculator
/// </summary>
/// <param name="startPosition">Top left position of rectangle.</param>
/// <param name="thickness">Thickness of rectangle.</param>
public static DoubleCords CalculateThicknessCenter(Coordinates startPosition, int thickness)
public static DoubleCoords CalculateThicknessCenter(Coordinates startPosition, int thickness)
{
int x1, x2, y1, y2;
if (thickness % 2 == 0)
Expand All @@ -31,7 +31,7 @@ public static DoubleCords CalculateThicknessCenter(Coordinates startPosition, in
y1 = y2 - thickness;
}

return new DoubleCords(new Coordinates(x1, y1), new Coordinates(x2 - 1, y2 - 1));
return new DoubleCoords(new Coordinates(x1, y1), new Coordinates(x2 - 1, y2 - 1));
}

public static Coordinates GetCenterPoint(Coordinates startingPoint, Coordinates endPoint)
Expand Down Expand Up @@ -78,7 +78,7 @@ public static void DrawRectangle(Layer layer, SKColor color, int x1, int y1, int
}
}

public static IEnumerable<Coordinates> RectangleToCoordinates(DoubleCords coordinates)
public static IEnumerable<Coordinates> RectangleToCoordinates(DoubleCoords coordinates)
{
return RectangleToCoordinates(coordinates.Coords1.X, coordinates.Coords1.Y, coordinates.Coords2.X, coordinates.Coords2.Y);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
namespace PixiEditor.Models.Position
{
public struct DoubleCords
{
public DoubleCords(Coordinates cords1, Coordinates cords2)
{
Coords1 = cords1;
Coords2 = cords2;
}

public Coordinates Coords1 { get; set; }

public Coordinates Coords2 { get; set; }
}
namespace PixiEditor.Models.Position
{
public struct DoubleCoords
{
public DoubleCoords(Coordinates cords1, Coordinates cords2)
{
Coords1 = cords1;
Coords2 = cords2;
}

public Coordinates Coords1 { get; set; }

public Coordinates Coords2 { get; set; }
}
}
2 changes: 1 addition & 1 deletion PixiEditor/Models/Tools/Brushes/CircleBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public override void Draw(Layer layer, int toolSize, Coordinates coordinates, SK
Coordinates topLeft = new Coordinates(coordinates.X - halfSize + modifier, coordinates.Y - halfSize + modifier);
Coordinates bottomRight = new Coordinates(coordinates.X + halfSize - 1, coordinates.Y + halfSize - 1);

CircleTool.DrawEllipseFromRect(layer, topLeft, bottomRight, paint.Color, paint.Color, 1, true);
CircleTool.DrawEllipseFromCoordinates(layer, topLeft, bottomRight, paint.Color, paint.Color, 1, true);
}
}
}
12 changes: 6 additions & 6 deletions PixiEditor/Models/Tools/ShapeTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,41 @@ namespace PixiEditor.Models.Tools
{
public abstract class ShapeTool : BitmapOperationTool
{
public static DoubleCords CalculateCoordinatesForShapeRotation(
public static DoubleCoords CalculateCoordinatesForShapeRotation(
Coordinates startingCords,
Coordinates secondCoordinates)
{
Coordinates currentCoordinates = secondCoordinates;

if (startingCords.X > currentCoordinates.X && startingCords.Y > currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(currentCoordinates.X, currentCoordinates.Y),
new Coordinates(startingCords.X, startingCords.Y));
}

if (startingCords.X < currentCoordinates.X && startingCords.Y < currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(startingCords.X, startingCords.Y),
new Coordinates(currentCoordinates.X, currentCoordinates.Y));
}

if (startingCords.Y > currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(startingCords.X, currentCoordinates.Y),
new Coordinates(currentCoordinates.X, startingCords.Y));
}

if (startingCords.X > currentCoordinates.X && startingCords.Y <= currentCoordinates.Y)
{
return new DoubleCords(
return new DoubleCoords(
new Coordinates(currentCoordinates.X, startingCords.Y),
new Coordinates(startingCords.X, currentCoordinates.Y));
}

return new DoubleCords(startingCords, secondCoordinates);
return new DoubleCoords(startingCords, secondCoordinates);
}

public ShapeTool()
Expand Down
52 changes: 33 additions & 19 deletions PixiEditor/Models/Tools/Tools/BrightnessTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class BrightnessTool : BitmapOperationTool
private const float CorrectionFactor = 5f; // Initial correction factor

private readonly List<Coordinates> pixelsVisited = new List<Coordinates>();
private List<Coordinates> circleCache = null;
private List<DoubleCoords> circleCache = new List<DoubleCoords>();
private int cachedCircleSize = -1;

public BrightnessTool()
Expand Down Expand Up @@ -77,29 +77,18 @@ public override void Use(Layer layer, List<Coordinates> coordinates, SKColor col
public void ChangeBrightness(Layer layer, Coordinates coordinates, int toolSize, float correctionFactor)
{
if (cachedCircleSize != toolSize)
{
cachedCircleSize = toolSize;
circleCache = CircleTool.GenerateMidpointEllipse(toolSize / 2.0, toolSize / 2.0, 0, 0);
circleCache.Sort((a, b) => a.Y != b.Y ? a.Y - b.Y : a.X - b.X);
for (int i = circleCache.Count - 2; i >= 1; i--)
{
if (circleCache[i].Y == circleCache[i - 1].Y && circleCache[i].Y == circleCache[i + 1].Y)
{
circleCache.RemoveAt(i);
}
}
}
UpdateCircleCache(toolSize);

int radius = (int)Math.Ceiling(toolSize / 2f);
layer.DynamicResizeAbsolute(coordinates.X + radius, coordinates.Y + radius, coordinates.X - radius, coordinates.Y - radius);

for (int i = 0; i < circleCache.Count; i += 2)
foreach (var pair in circleCache)
{
Coordinates left = circleCache[i];
Coordinates right = circleCache[i + 1];
Coordinates left = pair.Coords1;
Coordinates right = pair.Coords2;
int y = left.Y + coordinates.Y;

for (int x = left.X + coordinates.X; x < right.X + coordinates.X; x++)
for (int x = left.X + coordinates.X; x <= right.X + coordinates.X; x++)
{
if (Mode == BrightnessMode.Default)
{
Expand All @@ -117,8 +106,33 @@ public void ChangeBrightness(Layer layer, Coordinates coordinates, int toolSize,
layer.LayerBitmap.SkiaSurface.Canvas.DrawPoint(x - layer.OffsetX, y - layer.OffsetY, newColor);
}
}
Int32Rect rect = new(coordinates.X - radius, coordinates.Y - radius, radius * 2, radius * 2);
layer.InvokeLayerBitmapChange(rect);
layer.InvokeLayerBitmapChange(new(coordinates.X - radius, coordinates.Y - radius, radius * 2, radius * 2));
}

public void UpdateCircleCache(int newCircleSize)
{
cachedCircleSize = newCircleSize;
DoubleCoords rect = CoordinatesCalculator.CalculateThicknessCenter(new Coordinates(0, 0), newCircleSize);
List<Coordinates> circle = CircleTool.GenerateEllipseFromRect(rect);
circle.Sort((a, b) => a.Y != b.Y ? a.Y - b.Y : a.X - b.X);

circleCache.Clear();

int minX = int.MaxValue;
int maxX = int.MinValue;
for (int i = 0; i < circle.Count; i++)
{
if (i >= 1 && circle[i].Y != circle[i - 1].Y)
{
int prevY = circle[i - 1].Y;
circleCache.Add(new DoubleCoords(new(minX, prevY), new(maxX, prevY)));
minX = int.MaxValue;
maxX = int.MinValue;
}
minX = Math.Min(circle[i].X, minX);
maxX = Math.Max(circle[i].X, maxX);
}
circleCache.Add(new DoubleCoords(new(minX, circle[^1].Y), new(maxX, circle[^1].Y)));
}
}
}
Loading

0 comments on commit 748ae49

Please sign in to comment.