Browse Source

Merge pull request #532 from PixiEditor/brightness-mode-fix

Fixed default mode for brightness tool
Krzysztof Krysiński 2 years ago
parent
commit
f94d766283

+ 1 - 1
src/ChunkyImageLib/ChunkyImage.cs

@@ -612,7 +612,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         lock (lockObject)
         {
             ThrowIfDisposed();
-            PixelOperation operation = new(pos, pixelProcessor, blendMode);
+            PixelOperation operation = new(pos, pixelProcessor, GetCommittedPixel, blendMode);
             EnqueueOperation(operation);
         }
     }

+ 2 - 2
src/ChunkyImageLib/Operations/ApplyMaskOperation.cs

@@ -22,9 +22,9 @@ internal class ApplyMaskOperation : IDrawOperation
         return new AffectedArea(mask.FindCommittedChunks());
     }
     
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        mask.DrawCommittedChunkOn(chunkPos, chunk.Resolution, chunk.Surface.DrawingSurface, VecI.Zero, clippingPaint);
+        mask.DrawCommittedChunkOn(chunkPos, targetChunk.Resolution, targetChunk.Surface.DrawingSurface, VecI.Zero, clippingPaint);
     }
 
     public void Dispose()

+ 4 - 4
src/ChunkyImageLib/Operations/BresenhamLineOperation.cs

@@ -25,14 +25,14 @@ internal class BresenhamLineOperation : IMirroredDrawOperation
         points = BresenhamLineHelper.GetBresenhamLine(from, to);
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
         // a hacky way to make the lines look slightly better on non full res chunks
-        paint.Color = new Color(color.R, color.G, color.B, (byte)(color.A * chunk.Resolution.Multiplier()));
+        paint.Color = new Color(color.R, color.G, color.B, (byte)(color.A * targetChunk.Resolution.Multiplier()));
 
-        var surf = chunk.Surface.DrawingSurface;
+        var surf = targetChunk.Surface.DrawingSurface;
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
         surf.Canvas.DrawPoints(PointMode.Points, points, paint);
         surf.Canvas.Restore();

+ 21 - 21
src/ChunkyImageLib/Operations/ChunkyImageOperation.cs

@@ -19,16 +19,16 @@ internal class ChunkyImageOperation : IMirroredDrawOperation
         this.mirrorVertical = mirrorVertical;
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        chunk.Surface.DrawingSurface.Canvas.Save();
+        targetChunk.Surface.DrawingSurface.Canvas.Save();
         {
             VecI pixelPos = chunkPos * ChunkyImage.FullChunkSize;
             VecI topLeftImageCorner = GetTopLeft();
             RectD clippingRect = RectD.Create(
-                OperationHelper.ConvertForResolution(topLeftImageCorner - pixelPos, chunk.Resolution),
-                OperationHelper.ConvertForResolution(imageToDraw.CommittedSize, chunk.Resolution));
-            chunk.Surface.DrawingSurface.Canvas.ClipRect(clippingRect);
+                OperationHelper.ConvertForResolution(topLeftImageCorner - pixelPos, targetChunk.Resolution),
+                OperationHelper.ConvertForResolution(imageToDraw.CommittedSize, targetChunk.Resolution));
+            targetChunk.Surface.DrawingSurface.Canvas.ClipRect(clippingRect);
         }
 
         VecI chunkPixelCenter = chunkPos * ChunkyImage.FullChunkSize;
@@ -36,15 +36,15 @@ internal class ChunkyImageOperation : IMirroredDrawOperation
         chunkPixelCenter.Y += ChunkyImage.FullChunkSize / 2;
 
         VecI chunkCenterOnImage = chunkPixelCenter - targetPos;
-        VecI chunkSize = chunk.PixelSize;
+        VecI chunkSize = targetChunk.PixelSize;
         if (mirrorHorizontal)
         {
-            chunk.Surface.DrawingSurface.Canvas.Scale(-1, 1, chunkSize.X / 2f, chunkSize.Y / 2f);
+            targetChunk.Surface.DrawingSurface.Canvas.Scale(-1, 1, chunkSize.X / 2f, chunkSize.Y / 2f);
             chunkCenterOnImage.X = -chunkCenterOnImage.X;
         }
         if (mirrorVertical)
         {
-            chunk.Surface.DrawingSurface.Canvas.Scale(1, -1, chunkSize.X / 2f, chunkSize.Y / 2f);
+            targetChunk.Surface.DrawingSurface.Canvas.Scale(1, -1, chunkSize.X / 2f, chunkSize.Y / 2f);
             chunkCenterOnImage.Y = -chunkCenterOnImage.Y;
         }
 
@@ -59,37 +59,37 @@ internal class ChunkyImageOperation : IMirroredDrawOperation
 
         imageToDraw.DrawCommittedChunkOn(
             topLeft,
-            chunk.Resolution,
-            chunk.Surface.DrawingSurface,
-            (VecI)((topLeft * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * chunk.Resolution.Multiplier()));
+            targetChunk.Resolution,
+            targetChunk.Surface.DrawingSurface,
+            (VecI)((topLeft * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * targetChunk.Resolution.Multiplier()));
 
         VecI gridShift = targetPos % ChunkyImage.FullChunkSize;
         if (gridShift.X != 0)
         {
             imageToDraw.DrawCommittedChunkOn(
             topRight,
-            chunk.Resolution,
-            chunk.Surface.DrawingSurface,
-            (VecI)((topRight * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * chunk.Resolution.Multiplier()));
+            targetChunk.Resolution,
+            targetChunk.Surface.DrawingSurface,
+            (VecI)((topRight * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * targetChunk.Resolution.Multiplier()));
         }
         if (gridShift.Y != 0)
         {
             imageToDraw.DrawCommittedChunkOn(
             bottomLeft,
-            chunk.Resolution,
-            chunk.Surface.DrawingSurface,
-            (VecI)((bottomLeft * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * chunk.Resolution.Multiplier()));
+            targetChunk.Resolution,
+            targetChunk.Surface.DrawingSurface,
+            (VecI)((bottomLeft * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * targetChunk.Resolution.Multiplier()));
         }
         if (gridShift.X != 0 && gridShift.Y != 0)
         {
             imageToDraw.DrawCommittedChunkOn(
             bottomRight,
-            chunk.Resolution,
-            chunk.Surface.DrawingSurface,
-            (VecI)((bottomRight * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * chunk.Resolution.Multiplier()));
+            targetChunk.Resolution,
+            targetChunk.Surface.DrawingSurface,
+            (VecI)((bottomRight * ChunkyImage.FullChunkSize - chunkCenterOnImage).Add(ChunkyImage.FullChunkSize / 2) * targetChunk.Resolution.Multiplier()));
         }
 
-        chunk.Surface.DrawingSurface.Canvas.Restore();
+        targetChunk.Surface.DrawingSurface.Canvas.Restore();
     }
 
     public AffectedArea FindAffectedArea(VecI imageSize)

+ 6 - 6
src/ChunkyImageLib/Operations/ClearPathOperation.cs

@@ -16,17 +16,17 @@ internal class ClearPathOperation : IMirroredDrawOperation
         this.pathTightBounds = (pathTightBounds ?? (RectI)path.TightBounds);
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        chunk.Surface.DrawingSurface.Canvas.Save();
+        targetChunk.Surface.DrawingSurface.Canvas.Save();
 
         using VectorPath transformedPath = new(path);
-        float scale = (float)chunk.Resolution.Multiplier();
+        float scale = (float)targetChunk.Resolution.Multiplier();
         VecD trans = -chunkPos * ChunkyImage.FullChunkSize * scale;
         transformedPath.Transform(Matrix3X3.CreateScaleTranslation(scale, scale, (float)trans.X, (float)trans.Y));
-        chunk.Surface.DrawingSurface.Canvas.ClipPath(transformedPath);
-        chunk.Surface.DrawingSurface.Canvas.Clear();
-        chunk.Surface.DrawingSurface.Canvas.Restore();
+        targetChunk.Surface.DrawingSurface.Canvas.ClipPath(transformedPath);
+        targetChunk.Surface.DrawingSurface.Canvas.Clear();
+        targetChunk.Surface.DrawingSurface.Canvas.Restore();
     }
 
     public AffectedArea FindAffectedArea(VecI imageSize)

+ 7 - 7
src/ChunkyImageLib/Operations/ClearRegionOperation.cs

@@ -14,15 +14,15 @@ internal class ClearRegionOperation : IMirroredDrawOperation
         this.rect = rect;
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        VecI convPos = OperationHelper.ConvertForResolution(rect.Pos, chunk.Resolution);
-        VecI convSize = OperationHelper.ConvertForResolution(rect.Size, chunk.Resolution);
+        VecI convPos = OperationHelper.ConvertForResolution(rect.Pos, targetChunk.Resolution);
+        VecI convSize = OperationHelper.ConvertForResolution(rect.Size, targetChunk.Resolution);
 
-        chunk.Surface.DrawingSurface.Canvas.Save();
-        chunk.Surface.DrawingSurface.Canvas.ClipRect(RectD.Create(convPos - chunkPos.Multiply(chunk.PixelSize), convSize));
-        chunk.Surface.DrawingSurface.Canvas.Clear();
-        chunk.Surface.DrawingSurface.Canvas.Restore();
+        targetChunk.Surface.DrawingSurface.Canvas.Save();
+        targetChunk.Surface.DrawingSurface.Canvas.ClipRect(RectD.Create(convPos - chunkPos.Multiply(targetChunk.PixelSize), convSize));
+        targetChunk.Surface.DrawingSurface.Canvas.Clear();
+        targetChunk.Surface.DrawingSurface.Canvas.Restore();
     }
 
     public AffectedArea FindAffectedArea(VecI imageSize)

+ 4 - 4
src/ChunkyImageLib/Operations/DrawingSurfaceLineOperation.cs

@@ -27,12 +27,12 @@ internal class DrawingSurfaceLineOperation : IMirroredDrawOperation
         this.to = to;
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        paint.IsAntiAliased = chunk.Resolution != ChunkResolution.Full;
-        var surf = chunk.Surface.DrawingSurface;
+        paint.IsAntiAliased = targetChunk.Resolution != ChunkResolution.Full;
+        var surf = targetChunk.Surface.DrawingSurface;
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
         surf.Canvas.DrawLine(from, to, paint);
         surf.Canvas.Restore();

+ 4 - 4
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -53,16 +53,16 @@ internal class EllipseOperation : IMirroredDrawOperation
         }
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
         if (!init)
             Init();
-        var surf = chunk.Surface.DrawingSurface;
+        var surf = targetChunk.Surface.DrawingSurface;
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
 
-        paint.IsAntiAliased = chunk.Resolution != ChunkResolution.Full;
+        paint.IsAntiAliased = targetChunk.Resolution != ChunkResolution.Full;
 
         if (strokeWidth == 1)
         {

+ 1 - 1
src/ChunkyImageLib/Operations/IDrawOperation.cs

@@ -6,6 +6,6 @@ namespace ChunkyImageLib.Operations;
 internal interface IDrawOperation : IOperation
 {
     bool IgnoreEmptyChunks { get; }
-    void DrawOnChunk(Chunk chunk, VecI chunkPos);
+    void DrawOnChunk(Chunk targetChunk, VecI chunkPos);
     AffectedArea FindAffectedArea(VecI imageSize);
 }

+ 6 - 6
src/ChunkyImageLib/Operations/ImageOperation.cs

@@ -79,19 +79,19 @@ internal class ImageOperation : IMirroredDrawOperation
 
 
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
         //customPaint.FilterQuality = chunk.Resolution != ChunkResolution.Full;
-        float scaleMult = (float)chunk.Resolution.Multiplier();
+        float scaleMult = (float)targetChunk.Resolution.Multiplier();
         VecD trans = -chunkPos * ChunkPool.FullChunkSize;
 
         var scaleTrans = Matrix3X3.CreateScaleTranslation(scaleMult, scaleMult, (float)trans.X * scaleMult, (float)trans.Y * scaleMult);
         var finalMatrix = Matrix3X3.Concat(scaleTrans, transformMatrix);
 
-        chunk.Surface.DrawingSurface.Canvas.Save();
-        chunk.Surface.DrawingSurface.Canvas.SetMatrix(finalMatrix);
-        chunk.Surface.DrawingSurface.Canvas.DrawSurface(toPaint.DrawingSurface, 0, 0, customPaint);
-        chunk.Surface.DrawingSurface.Canvas.Restore();
+        targetChunk.Surface.DrawingSurface.Canvas.Save();
+        targetChunk.Surface.DrawingSurface.Canvas.SetMatrix(finalMatrix);
+        targetChunk.Surface.DrawingSurface.Canvas.DrawSurface(toPaint.DrawingSurface, 0, 0, customPaint);
+        targetChunk.Surface.DrawingSurface.Canvas.Restore();
     }
 
     public AffectedArea FindAffectedArea(VecI imageSize)

+ 4 - 4
src/ChunkyImageLib/Operations/PathOperation.cs

@@ -24,12 +24,12 @@ internal class PathOperation : IMirroredDrawOperation
         bounds = floatBounds.Inflate((int)Math.Ceiling(strokeWidth) + 1);
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        paint.IsAntiAliased = chunk.Resolution != ChunkResolution.Full;
-        var surf = chunk.Surface.DrawingSurface;
+        paint.IsAntiAliased = targetChunk.Resolution != ChunkResolution.Full;
+        var surf = targetChunk.Surface.DrawingSurface;
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
         surf.Canvas.DrawPath(path, paint);
         surf.Canvas.Restore();

+ 15 - 12
src/ChunkyImageLib/Operations/PixelOperation.cs

@@ -6,7 +6,7 @@ using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib.Operations;
 
-public delegate Color PixelProcessor(Color input);
+public delegate Color PixelProcessor(Color commited, Color upToDate);
 internal class PixelOperation : IMirroredDrawOperation
 {
     public bool IgnoreEmptyChunks => false;
@@ -14,8 +14,9 @@ internal class PixelOperation : IMirroredDrawOperation
     private readonly Color color;
     private readonly BlendMode blendMode;
     private readonly Paint paint;
+    private readonly Func<VecI, Color>? getCommitedPixelFunc = null;
 
-    private readonly PixelProcessor? _colorProcessor = null;
+    private readonly PixelProcessor? colorProcessor = null;
 
     public PixelOperation(VecI pixel, Color color, BlendMode blendMode)
     {
@@ -25,22 +26,23 @@ internal class PixelOperation : IMirroredDrawOperation
         paint = new Paint() { BlendMode = blendMode };
     }
 
-    public PixelOperation(VecI pixel, PixelProcessor colorProcessor, BlendMode blendMode)
+    public PixelOperation(VecI pixel, PixelProcessor colorProcessor, Func<VecI, Color> getCommitedPixelFunc, BlendMode blendMode)
     {
         this.pixel = pixel;
-        this._colorProcessor = colorProcessor;
+        this.colorProcessor = colorProcessor;
         this.blendMode = blendMode;
+        this.getCommitedPixelFunc = getCommitedPixelFunc;
         paint = new Paint() { BlendMode = blendMode };
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
         // a hacky way to make the lines look slightly better on non full res chunks
-        paint.Color = GetColor(chunk, chunkPos);
+        paint.Color = GetColor(targetChunk, chunkPos);
 
-        DrawingSurface surf = chunk.Surface.DrawingSurface;
+        DrawingSurface surf = targetChunk.Surface.DrawingSurface;
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
         surf.Canvas.DrawPoint(pixel, paint);
         surf.Canvas.Restore();
@@ -49,9 +51,10 @@ internal class PixelOperation : IMirroredDrawOperation
     private Color GetColor(Chunk chunk, VecI chunkPos)
     {
         Color pixelColor = color;
-        if (_colorProcessor != null)
+        if (colorProcessor != null && getCommitedPixelFunc != null)
         {
-            pixelColor = _colorProcessor(chunk.Surface.GetSRGBPixel(pixel - chunkPos * ChunkyImage.FullChunkSize));
+            var pos = pixel - chunkPos * ChunkyImage.FullChunkSize;
+            pixelColor = colorProcessor(getCommitedPixelFunc(pixel), chunk.Surface.GetSRGBPixel(pos));
         }
 
         return new Color(pixelColor.R, pixelColor.G, pixelColor.B, (byte)(pixelColor.A * chunk.Resolution.Multiplier()));
@@ -69,9 +72,9 @@ internal class PixelOperation : IMirroredDrawOperation
             pixelRect = (RectI)pixelRect.ReflectX((double)verAxisX).Round();
         if (horAxisY is not null)
             pixelRect = (RectI)pixelRect.ReflectY((double)horAxisY);
-        if (_colorProcessor != null)
+        if (colorProcessor != null && getCommitedPixelFunc != null)
         {
-            return new PixelOperation(pixelRect.Pos, _colorProcessor, blendMode);
+            return new PixelOperation(pixelRect.Pos, colorProcessor, getCommitedPixelFunc, blendMode);
         }
 
         return new PixelOperation(pixelRect.Pos, color, blendMode);

+ 4 - 4
src/ChunkyImageLib/Operations/PixelsOperation.cs

@@ -24,14 +24,14 @@ internal class PixelsOperation : IMirroredDrawOperation
         paint = new Paint() { BlendMode = blendMode };
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
         // a hacky way to make the lines look slightly better on non full res chunks
-        paint.Color = new Color(color.R, color.G, color.B, (byte)(color.A * chunk.Resolution.Multiplier()));
+        paint.Color = new Color(color.R, color.G, color.B, (byte)(color.A * targetChunk.Resolution.Multiplier()));
 
-        DrawingSurface surf = chunk.Surface.DrawingSurface;
+        DrawingSurface surf = targetChunk.Surface.DrawingSurface;
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
         surf.Canvas.DrawPoints(PointMode.Points, pixels, paint);
         surf.Canvas.Restore();

+ 4 - 4
src/ChunkyImageLib/Operations/RectangleOperation.cs

@@ -15,11 +15,11 @@ internal class RectangleOperation : IMirroredDrawOperation
 
     public bool IgnoreEmptyChunks => false;
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        var skiaSurf = chunk.Surface.DrawingSurface;
+        var skiaSurf = targetChunk.Surface.DrawingSurface;
 
-        var surf = chunk.Surface.DrawingSurface;
+        var surf = targetChunk.Surface.DrawingSurface;
 
         var rect = RectD.FromCenterAndSize(Data.Center, Data.Size.Abs());
         var innerRect = rect.Inflate(-Data.StrokeWidth);
@@ -27,7 +27,7 @@ internal class RectangleOperation : IMirroredDrawOperation
             innerRect = RectD.Empty;
 
         surf.Canvas.Save();
-        surf.Canvas.Scale((float)chunk.Resolution.Multiplier());
+        surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
         surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
         skiaSurf.Canvas.RotateRadians((float)Data.Angle, (float)rect.Center.X, (float)rect.Center.Y);
 

+ 2 - 2
src/ChunkyImageLib/Operations/ReplaceColorOperation.cs

@@ -22,9 +22,9 @@ internal class ReplaceColorOperation : IDrawOperation
         newColorBits = newColor.ToULong();
     }
 
-    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
+    public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
     {
-        ReplaceColor(oldColorBounds, newColorBits, chunk);
+        ReplaceColor(oldColorBounds, newColorBits, targetChunk);
     }
 
     private static unsafe void ReplaceColor(ColorBounds oldColorBounds, ulong newColorBits, Chunk chunk)

+ 7 - 25
src/PixiEditor.ChangeableDocument/Changes/Drawing/ChangeBrightness_UpdateableChange.cs

@@ -14,8 +14,7 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
     private readonly List<VecI> positions = new();
     private bool ignoreUpdate = false;
     private readonly bool repeat;
-    
-    private Surface tempSurface;
+
     private List<VecI> ellipseLines;
     
     private CommittedChunkStorage? savedChunks;
@@ -29,7 +28,6 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
         this.repeat = repeat;
 
         ellipseLines = EllipseHelper.SplitEllipseIntoLines((EllipseHelper.GenerateEllipseFromRect(new RectI(0, 0, strokeWidth, strokeWidth))));
-        tempSurface = new Surface(new VecI(strokeWidth, strokeWidth));
     }
 
     [UpdateChangeMethod]
@@ -58,7 +56,7 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
 
         int queueLength = layer.LayerImage.QueueLength;
         
-        ChangeBrightness(ellipseLines, strokeWidth, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat, tempSurface, layer.LayerImage);
+        ChangeBrightness(ellipseLines, strokeWidth, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat, layer.LayerImage);
         
         var affected = layer.LayerImage.FindAffectedArea(queueLength);
         
@@ -66,20 +64,9 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
     }
     
     private static void ChangeBrightness(
-        List<VecI> circleLines, int circleDiameter, VecI offset, float correctionFactor, bool repeat, Surface tempSurface, ChunkyImage layerImage)
+        List<VecI> circleLines, int circleDiameter, VecI offset, float correctionFactor, bool repeat, ChunkyImage layerImage)
     {
-        tempSurface.DrawingSurface.Canvas.Clear();
-        if (repeat)
-        {
-            layerImage.DrawMostUpToDateRegionOn
-                (new RectI(offset, new(circleDiameter, circleDiameter)), ChunkResolution.Full, tempSurface.DrawingSurface, new VecI(0));
-        }
-        else
-        {
-            layerImage.DrawCommittedRegionOn
-                (new RectI(offset, new(circleDiameter, circleDiameter)), ChunkResolution.Full, tempSurface.DrawingSurface, new VecI(0));
-        }
-        
+
         for (var i = 0; i < circleLines.Count - 1; i++)
         {
             VecI left = circleLines[i];
@@ -90,9 +77,9 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
             {
                 layerImage.EnqueueDrawPixel(
                     pos + offset,
-                    (pixel) =>
+                    (commitedColor, upToDateColor) =>
                     {
-                        Color newColor = ColorHelper.ChangeColorBrightness(pixel, correctionFactor);
+                        Color newColor = ColorHelper.ChangeColorBrightness(repeat ? upToDateColor : commitedColor, correctionFactor);
                         return ColorHelper.ChangeColorBrightness(newColor, correctionFactor);
                     },
                     BlendMode.Src);
@@ -113,7 +100,7 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
             DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, layer.LayerImage, layerGuid, false);
             foreach (VecI pos in positions)
             {
-                ChangeBrightness(ellipseLines, strokeWidth, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat, tempSurface, layer.LayerImage);
+                ChangeBrightness(ellipseLines, strokeWidth, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat, layer.LayerImage);
             }
         }
 
@@ -130,9 +117,4 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
         var affected = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, layerGuid, false, ref savedChunks);
         return new LayerImageArea_ChangeInfo(layerGuid, affected);
     }
-
-    public override void Dispose()
-    {
-        tempSurface.Dispose();
-    }
 }

+ 9 - 5
src/PixiEditor/ViewModels/SubViewModels/Main/ToolsViewModel.cs

@@ -50,7 +50,7 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
     private bool shiftIsDown;
     private bool ctrlIsDown;
     private bool altIsDown;
-    
+
     private ToolViewModel _preTransientTool;
 
 
@@ -97,7 +97,7 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
     {
         SetActiveTool(tool, false);
     }
-    
+
     public void SetActiveTool(ToolViewModel tool, bool transient)
     {
         if (ActiveTool == tool)
@@ -122,7 +122,7 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
 
         LastActionTool = ActiveTool;
         ActiveTool = tool;
-        
+
         if (shareToolbar)
         {
             ActiveTool.Toolbar.LoadSharedSettings();
@@ -171,8 +171,12 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
     }
 
     [Evaluator.CanExecute("PixiEditor.Tools.CanChangeToolSize")]
-    public bool CanChangeToolSize() => Owner.ToolsSubViewModel.ActiveTool is PenToolViewModel { PixelPerfectEnabled: false };
-    
+    public bool CanChangeToolSize() => Owner.ToolsSubViewModel.ActiveTool.Toolbar is BasicToolbar
+                                       && Owner.ToolsSubViewModel.ActiveTool is not PenToolViewModel
+                                       {
+                                           PixelPerfectEnabled: true
+                                       };
+
     public void SetActiveTool(Type toolType, bool transient)
     {
         if (!typeof(ToolViewModel).IsAssignableFrom(toolType))