Skip to content

Commit

Permalink
Fix crash when drawing outside canvas
Browse files Browse the repository at this point in the history
  • Loading branch information
Equbuxu committed Dec 6, 2021
1 parent 41522e1 commit 307460c
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 24 deletions.
5 changes: 3 additions & 2 deletions PixiEditor/Models/Controllers/BitmapOperationsUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ public void ApplyPreviewLayer()
var previewLayer = Manager.ActiveDocument.PreviewLayer;
var activeLayer = Manager.ActiveLayer;

activeLayer.DynamicResizeAbsolute(previewLayer.OffsetX + previewLayer.Width, previewLayer.OffsetY + previewLayer.Height, previewLayer.OffsetX, previewLayer.OffsetY);
Int32Rect dirtyRect = new Int32Rect(previewLayer.OffsetX, previewLayer.OffsetY, previewLayer.Width, previewLayer.Height);
activeLayer.DynamicResizeAbsolute(dirtyRect);
previewLayer.LayerBitmap.SkiaSurface.Draw(
activeLayer.LayerBitmap.SkiaSurface.Canvas,
previewLayer.OffsetX - activeLayer.OffsetX,
previewLayer.OffsetY - activeLayer.OffsetY,
BlendingPaint
);
Manager.ActiveLayer.InvokeLayerBitmapChange(new Int32Rect(previewLayer.OffsetX, previewLayer.OffsetY, previewLayer.Width, previewLayer.Height));
Manager.ActiveLayer.InvokeLayerBitmapChange(dirtyRect);
// Don't forget about firing BitmapChanged
BitmapChanged?.Invoke(this, null);
Manager.ActiveDocument.PreviewLayer.Reset();
Expand Down
2 changes: 1 addition & 1 deletion PixiEditor/Models/DataHolders/Selection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void SetSelection(Int32Rect rect, bool isCirclular, SelectionType mode)
break;
}

SelectionLayer.DynamicResizeAbsolute(rect.X + rect.Width - 1, rect.Y + rect.Height - 1, rect.X, rect.Y);
SelectionLayer.DynamicResizeAbsolute(new Int32Rect(rect.X, rect.Y, rect.Width, rect.Height));
if (isCirclular)
{
float cx = rect.X + rect.Width / 2f;
Expand Down
19 changes: 11 additions & 8 deletions PixiEditor/Models/Layers/Layer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,19 +426,22 @@ public void DynamicResize(BitmapPixelChanges pixels)
}
}

public void DynamicResizeAbsolute(int newMaxX, int newMaxY, int newMinX, int newMinY)
public void DynamicResizeAbsolute(Int32Rect newSize)
{
if (newMinX < 0) newMinX = 0;
if (newMinY < 0) newMinY = 0;
if (newMaxX >= MaxWidth) newMaxX = MaxWidth - 1;
if (newMaxY >= MaxHeight) newMaxY = MaxHeight - 1;

newSize = newSize.Intersect(new Int32Rect(0, 0, MaxWidth, MaxHeight));
if (newSize.IsEmpty)
return;
if (IsReset)
{
Offset = new Thickness(newMinX, newMinY, 0, 0);
Offset = new Thickness(newSize.X, newSize.Y, 0, 0);
}

DynamicResizeRelative(newMaxX - OffsetX, newMaxY - OffsetY, newMinX - OffsetX, newMinY - OffsetY);
int relX = newSize.X - OffsetX;
int relY = newSize.Y - OffsetY;
int maxX = relX + newSize.Width - 1;
int maxY = relY + newSize.Height - 1;

DynamicResizeRelative(maxX, maxY, relX, relY);
}

/// <summary>
Expand Down
5 changes: 3 additions & 2 deletions PixiEditor/Models/Tools/Tools/BrightnessTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public void ChangeBrightness(Layer layer, Coordinates coordinates, int toolSize,
UpdateCircleCache(toolSize);

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

foreach (var pair in circleCache)
{
Expand All @@ -108,7 +109,7 @@ public void ChangeBrightness(Layer layer, Coordinates coordinates, int toolSize,
layer.LayerBitmap.SkiaSurface.Canvas.DrawPoint(x - layer.OffsetX, y - layer.OffsetY, newColor);
}
}
layer.InvokeLayerBitmapChange(new(coordinates.X - radius, coordinates.Y - radius, radius * 2, radius * 2));
layer.InvokeLayerBitmapChange(dirtyRect);
}

public void UpdateCircleCache(int newCircleSize)
Expand Down
2 changes: 1 addition & 1 deletion PixiEditor/Models/Tools/Tools/CircleTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class CircleTool : ShapeTool
corners.Coords1.Y - halfThickness,
corners.Coords2.X + halfThickness * 2 - corners.Coords1.X,
corners.Coords2.Y + halfThickness * 2 - corners.Coords1.Y);
layer.DynamicResizeAbsolute(dirtyRect.X + dirtyRect.Width - 1, dirtyRect.Y + dirtyRect.Height - 1, dirtyRect.X, dirtyRect.Y);
layer.DynamicResizeAbsolute(dirtyRect);

using (SKPaint paint = new SKPaint())
{
Expand Down
4 changes: 4 additions & 0 deletions PixiEditor/Models/Tools/Tools/ColorPickerTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public ColorPickerTool(DocumentProvider documentProvider, BitmapManager bitmapMa
public override void Use(List<Coordinates> coordinates)
{
var coords = coordinates.First();
var doc = _docProvider.GetSurface();
if (coords.X < 0 || coords.Y < 0 || coords.X >= doc.Width || coords.Y >= doc.Height)
return;

ViewModelMain.Current.ColorsSubViewModel.PrimaryColor = GetColorAt(coords.X, coords.Y);
}

Expand Down
4 changes: 2 additions & 2 deletions PixiEditor/Models/Tools/Tools/FloodFillTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override void Use(Layer layer, List<Coordinates> coordinates, SKColor col
{
if (layer.IsReset)
{
layer.DynamicResizeAbsolute(BitmapManager.ActiveDocument.Width, BitmapManager.ActiveDocument.Height, 0, 0);
layer.DynamicResizeAbsolute(new(0, 0, BitmapManager.ActiveDocument.Width, BitmapManager.ActiveDocument.Height));
layer.LayerBitmap.SkiaSurface.Canvas.Clear(color);
layer.InvokeLayerBitmapChange();
}
Expand Down Expand Up @@ -93,7 +93,7 @@ public void LinearFill(Layer layer, Coordinates startingCoords, SKColor newColor
}
int lastCheckedPixelRight = fillXRight - 1;

layer.DynamicResizeAbsolute(lastCheckedPixelRight, coords.Y, lastCheckedPixelLeft, coords.Y);
layer.DynamicResizeAbsolute(new(lastCheckedPixelLeft, coords.Y, lastCheckedPixelRight - lastCheckedPixelLeft + 1, 1));
int relativeY = coords.Y - layer.OffsetY;
layer.LayerBitmap.SkiaSurface.Canvas.DrawLine(lastCheckedPixelLeft - layer.OffsetX, relativeY, lastCheckedPixelRight - layer.OffsetX + 1, relativeY, fillPaint);
dirtyRect = dirtyRect.Expand(new Int32Rect(lastCheckedPixelLeft, coords.Y, lastCheckedPixelRight - lastCheckedPixelLeft + 1, 1));
Expand Down
2 changes: 1 addition & 1 deletion PixiEditor/Models/Tools/Tools/LineTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public override void Use(Layer layer, List<Coordinates> coordinates, SKColor col
Math.Max(y1, y) + thickness - dirtyY);
if (AutomaticallyResizeCanvas)
{
layer.DynamicResizeAbsolute(dirtyRect.X + dirtyRect.Width - 1, dirtyRect.Y + dirtyRect.Height - 1, dirtyRect.X, dirtyRect.Y);
layer.DynamicResizeAbsolute(dirtyRect);
}

x -= layer.OffsetX;
Expand Down
12 changes: 7 additions & 5 deletions PixiEditor/Models/Tools/Tools/MoveTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,11 @@ public override void Use(Layer layer, List<Coordinates> mouseMove, SKColor color

int newX = moveStartRect.X + dX;
int newY = moveStartRect.Y + dY;

layer.DynamicResizeAbsolute(newX + moveStartRect.Width, newY + moveStartRect.Height, newX, newY);

Int32Rect dirtyRect = new Int32Rect(newX, newY, moveStartRect.Width, moveStartRect.Height);
layer.DynamicResizeAbsolute(dirtyRect);
previewLayerData.SkiaSurface.Draw(layer.LayerBitmap.SkiaSurface.Canvas, newX - layer.OffsetX, newY - layer.OffsetY, Surface.ReplacingPaint);
layer.InvokeLayerBitmapChange(new Int32Rect(newX, newY, moveStartRect.Width, moveStartRect.Height));
layer.InvokeLayerBitmapChange(dirtyRect);
}

public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
Expand All @@ -254,9 +255,10 @@ private static void ApplySurfacesToLayers(Surface[] surfaces, Coordinates[] star
var layer = layers[count];
using SKImage snapshot = surface.SkiaSurface.Snapshot();
Coordinates position = new Coordinates(startPositions[count].X + delta.X, startPositions[count].Y + delta.Y);
layer.DynamicResizeAbsolute(position.X + surface.Width, position.Y + surface.Height, position.X, position.Y);
Int32Rect dirtyRect = new Int32Rect(position.X, position.Y, surface.Width, surface.Height);
layer.DynamicResizeAbsolute(dirtyRect);
layer.LayerBitmap.SkiaSurface.Canvas.DrawImage(snapshot, position.X - layer.OffsetX, position.Y - layer.OffsetY);
layer.InvokeLayerBitmapChange(new Int32Rect(position.X, position.Y, surface.Width, surface.Height));
layer.InvokeLayerBitmapChange(dirtyRect);

count++;
}
Expand Down
6 changes: 5 additions & 1 deletion PixiEditor/Models/Tools/Tools/PenTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ public override void Use(Layer layer, List<Coordinates> coordinates, SKColor col
paint.Color = color;
if (AutomaticallyResizeCanvas)
{
layer.DynamicResizeAbsolute(coordinates.Max(x => x.X), coordinates.Max(x => x.Y), coordinates.Min(x => x.X), coordinates.Min(x => x.Y));
int maxX = coordinates.Max(x => x.X);
int maxY = coordinates.Max(x => x.Y);
int minX = coordinates.Min(x => x.X);
int minY = coordinates.Min(x => x.Y);
layer.DynamicResizeAbsolute(new(minX, minY, maxX - minX + 1, maxX - minX + 1));
}
Draw(
layer,
Expand Down
2 changes: 1 addition & 1 deletion PixiEditor/Models/Tools/Tools/RectangleTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void CreateRectangle(Layer layer, SKColor color, SKColor? fillColor, List
fixedCoordinates.Coords1.Y - halfThickness,
fixedCoordinates.Coords2.X + halfThickness * 2 - fixedCoordinates.Coords1.X,
fixedCoordinates.Coords2.Y + halfThickness * 2 - fixedCoordinates.Coords1.Y);
layer.DynamicResizeAbsolute(dirtyRect.X + dirtyRect.Width - 1, dirtyRect.Y + dirtyRect.Height - 1, dirtyRect.X, dirtyRect.Y);
layer.DynamicResizeAbsolute(dirtyRect);

using (SKPaint paint = new SKPaint())
{
Expand Down

0 comments on commit 307460c

Please sign in to comment.