BUG-2378, BUG-2435, BUG-2486, BUG-2463, BUG-2309, BUG-2307, BUG-2249 : This should solve the issue, without requiring a lock. Just use an atomic assignment.

This commit is contained in:
Krom, Robertus 2020-02-11 12:30:07 +01:00
commit 2386ea15aa

View file

@ -36,9 +36,6 @@ namespace Greenshot.Drawing {
public class FreehandContainer : DrawableContainer { public class FreehandContainer : DrawableContainer {
private static readonly float [] PointOffset = {0.5f, 0.25f, 0.75f}; private static readonly float [] PointOffset = {0.5f, 0.25f, 0.75f};
[NonSerialized]
private readonly object _freehandPathLock = new object();
[NonSerialized] [NonSerialized]
private GraphicsPath freehandPath = new GraphicsPath(); private GraphicsPath freehandPath = new GraphicsPath();
private Rectangle myBounds = Rectangle.Empty; private Rectangle myBounds = Rectangle.Empty;
@ -113,12 +110,9 @@ namespace Greenshot.Drawing {
} }
//path.AddCurve(new Point[]{lastMouse, new Point(mouseX, mouseY)}); //path.AddCurve(new Point[]{lastMouse, new Point(mouseX, mouseY)});
lastMouse = new Point(mouseX, mouseY); lastMouse = new Point(mouseX, mouseY);
lock (_freehandPathLock)
{
freehandPath.AddLine(lastMouse, new Point(mouseX, mouseY)); freehandPath.AddLine(lastMouse, new Point(mouseX, mouseY));
// Only re-calculate the bounds & redraw when we added something to the path // Only re-calculate the bounds & redraw when we added something to the path
myBounds = Rectangle.Round(freehandPath.GetBounds()); myBounds = Rectangle.Round(freehandPath.GetBounds());
}
Invalidate(); Invalidate();
return true; return true;
@ -139,12 +133,9 @@ namespace Greenshot.Drawing {
/// Here we recalculate the freehand path by smoothing out the lines with Beziers. /// Here we recalculate the freehand path by smoothing out the lines with Beziers.
/// </summary> /// </summary>
private void RecalculatePath() { private void RecalculatePath() {
lock (_freehandPathLock) // Store the previous path, to dispose it later when we are finished
{ var previousFreehandPath = freehandPath;
isRecalculated = true; var newFreehandPath = new GraphicsPath();
// Dispose the previous path, if we have one
freehandPath?.Dispose();
freehandPath = new GraphicsPath();
// Here we can put some cleanup... like losing all the uninteresting points. // Here we can put some cleanup... like losing all the uninteresting points.
if (capturePoints.Count >= 3) if (capturePoints.Count >= 3)
@ -155,18 +146,22 @@ namespace Greenshot.Drawing {
// duplicate points, first at 50% than 25% than 75% // duplicate points, first at 50% than 25% than 75%
capturePoints.Insert((int)(capturePoints.Count * PointOffset[index]), capturePoints[(int)(capturePoints.Count * PointOffset[index++])]); capturePoints.Insert((int)(capturePoints.Count * PointOffset[index]), capturePoints[(int)(capturePoints.Count * PointOffset[index++])]);
} }
freehandPath.AddBeziers(capturePoints.ToArray()); newFreehandPath.AddBeziers(capturePoints.ToArray());
} }
else if (capturePoints.Count == 2) else if (capturePoints.Count == 2)
{ {
freehandPath.AddLine(capturePoints[0], capturePoints[1]); newFreehandPath.AddLine(capturePoints[0], capturePoints[1]);
} }
// Recalculate the bounds // Recalculate the bounds
myBounds = Rectangle.Round(freehandPath.GetBounds()); myBounds = Rectangle.Round(newFreehandPath.GetBounds());
} // assign
isRecalculated = true;
freehandPath = newFreehandPath;
// dispose previous
previousFreehandPath?.Dispose();
} }
/// <summary> /// <summary>
@ -196,13 +191,15 @@ namespace Greenshot.Drawing {
pen.LineJoin = LineJoin.Round; pen.LineJoin = LineJoin.Round;
// Move to where we need to draw // Move to where we need to draw
graphics.TranslateTransform(Left, Top); graphics.TranslateTransform(Left, Top);
lock (_freehandPathLock) var currentFreehandPath = freehandPath;
if (currentFreehandPath != null)
{ {
if (isRecalculated && Selected && renderMode == RenderMode.EDIT) if (isRecalculated && Selected && renderMode == RenderMode.EDIT)
{ {
DrawSelectionBorder(graphics, pen, freehandPath); isRecalculated = false;
DrawSelectionBorder(graphics, pen, currentFreehandPath);
} }
graphics.DrawPath(pen, freehandPath); graphics.DrawPath(pen, currentFreehandPath);
} }
// Move back, otherwise everything is shifted // Move back, otherwise everything is shifted
@ -262,11 +259,8 @@ namespace Greenshot.Drawing {
} }
public override int GetHashCode() { public override int GetHashCode() {
lock (_freehandPathLock)
{
return freehandPath?.GetHashCode() ?? 0; return freehandPath?.GetHashCode() ?? 0;
} }
}
public override bool ClickableAt(int x, int y) { public override bool ClickableAt(int x, int y) {
bool returnValue = base.ClickableAt(x, y); bool returnValue = base.ClickableAt(x, y);
@ -276,10 +270,7 @@ namespace Greenshot.Drawing {
{ {
Width = lineThickness + 10 Width = lineThickness + 10
}; };
lock (_freehandPathLock)
{
returnValue = freehandPath.IsOutlineVisible(x - Left, y - Top, pen); returnValue = freehandPath.IsOutlineVisible(x - Left, y - Top, pen);
}
} }
return returnValue; return returnValue;
} }