|
@@ -62,7 +62,10 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
private static Paint ClippingPaint { get; } = new Paint() { BlendMode = BlendMode.DstIn };
|
|
|
private static Paint InverseClippingPaint { get; } = new Paint() { BlendMode = BlendMode.DstOut };
|
|
|
private static Paint ReplacingPaint { get; } = new Paint() { BlendMode = BlendMode.Src };
|
|
|
- private static Paint SmoothReplacingPaint { get; } = new Paint() { BlendMode = BlendMode.Src, FilterQuality = FilterQuality.Medium };
|
|
|
+
|
|
|
+ private static Paint SmoothReplacingPaint { get; } =
|
|
|
+ new Paint() { BlendMode = BlendMode.Src, FilterQuality = FilterQuality.Medium };
|
|
|
+
|
|
|
private static Paint AddingPaint { get; } = new Paint() { BlendMode = BlendMode.Plus };
|
|
|
private readonly Paint blendModePaint = new Paint() { BlendMode = BlendMode.Src };
|
|
|
|
|
@@ -130,6 +133,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
rect ??= chunkBounds;
|
|
|
rect = rect.Value.Union(chunkBounds);
|
|
|
}
|
|
|
+
|
|
|
foreach (var operation in queuedOperations)
|
|
|
{
|
|
|
foreach (var pos in operation.affectedArea.Chunks)
|
|
@@ -139,6 +143,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
rect = rect.Value.Union(chunkBounds);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return rect;
|
|
|
}
|
|
|
}
|
|
@@ -156,6 +161,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
rect ??= chunkBounds;
|
|
|
rect = rect.Value.Union(chunkBounds);
|
|
|
}
|
|
|
+
|
|
|
return rect;
|
|
|
}
|
|
|
}
|
|
@@ -179,7 +185,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
if (committedChunks[suggestedResolution].TryGetValue(chunkPos, out Chunk? requestedResChunk))
|
|
|
{
|
|
|
- RectI visibleArea = new RectI(chunkPos * chunkSize, new VecI(chunkSize)).Intersect(scaledCommittedSize).Translate(-chunkPos * chunkSize);
|
|
|
+ RectI visibleArea = new RectI(chunkPos * chunkSize, new VecI(chunkSize))
|
|
|
+ .Intersect(scaledCommittedSize).Translate(-chunkPos * chunkSize);
|
|
|
|
|
|
RectI? chunkPreciseBounds = requestedResChunk.FindPreciseBounds(visibleArea);
|
|
|
if (chunkPreciseBounds is null)
|
|
@@ -191,17 +198,20 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- RectI visibleArea = new RectI(chunkPos * FullChunkSize, new VecI(FullChunkSize)).Intersect(new RectI(VecI.Zero, CommittedSize)).Translate(-chunkPos * FullChunkSize);
|
|
|
+ RectI visibleArea = new RectI(chunkPos * FullChunkSize, new VecI(FullChunkSize))
|
|
|
+ .Intersect(new RectI(VecI.Zero, CommittedSize)).Translate(-chunkPos * FullChunkSize);
|
|
|
|
|
|
RectI? chunkPreciseBounds = fullResChunk.FindPreciseBounds(visibleArea);
|
|
|
if (chunkPreciseBounds is null)
|
|
|
continue;
|
|
|
- RectI globalChunkBounds = (RectI)chunkPreciseBounds.Value.Scale(multiplier).Offset(chunkPos * chunkSize).RoundOutwards();
|
|
|
+ RectI globalChunkBounds = (RectI)chunkPreciseBounds.Value.Scale(multiplier)
|
|
|
+ .Offset(chunkPos * chunkSize).RoundOutwards();
|
|
|
|
|
|
preciseBounds ??= globalChunkBounds;
|
|
|
preciseBounds = preciseBounds.Value.Union(globalChunkBounds);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
preciseBounds = (RectI?)preciseBounds?.Scale(suggestedResolution.InvertedMultiplier()).RoundOutwards();
|
|
|
preciseBounds = preciseBounds?.Intersect(new RectI(preciseBounds.Value.Pos, CommittedSize));
|
|
|
|
|
@@ -281,12 +291,12 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
Chunk? committedChunk = MaybeGetCommittedChunk(chunkPos, ChunkResolution.Full);
|
|
|
Chunk? latestChunk = GetLatestChunk(chunkPos, ChunkResolution.Full);
|
|
|
- Color committedColor = committedChunk is null ?
|
|
|
- Colors.Transparent :
|
|
|
- committedChunk.Surface.GetSRGBPixel(posInChunk);
|
|
|
- Color latestColor = latestChunk is null ?
|
|
|
- Colors.Transparent :
|
|
|
- latestChunk.Surface.GetSRGBPixel(posInChunk);
|
|
|
+ Color committedColor = committedChunk is null
|
|
|
+ ? Colors.Transparent
|
|
|
+ : committedChunk.Surface.GetSRGBPixel(posInChunk);
|
|
|
+ Color latestColor = latestChunk is null
|
|
|
+ ? Colors.Transparent
|
|
|
+ : latestChunk.Surface.GetSRGBPixel(posInChunk);
|
|
|
// using a whole chunk just to draw 1 pixel is kinda dumb,
|
|
|
// but this should be faster than any approach that requires allocations
|
|
|
using Chunk tempChunk = Chunk.Create(ChunkResolution.Eighth);
|
|
@@ -303,7 +313,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
/// True if the chunk existed and was drawn, otherwise false
|
|
|
/// </returns>
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
- public bool DrawMostUpToDateChunkOn(VecI chunkPos, ChunkResolution resolution, DrawingSurface surface, VecI pos, Paint? paint = null)
|
|
|
+ public bool DrawMostUpToDateChunkOn(VecI chunkPos, ChunkResolution resolution, DrawingSurface surface, VecI pos,
|
|
|
+ Paint? paint = null)
|
|
|
{
|
|
|
lock (lockObject)
|
|
|
{
|
|
@@ -346,9 +357,11 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
|
|
|
// combine with committed and then draw
|
|
|
using var tempChunk = Chunk.Create(resolution);
|
|
|
- tempChunk.Surface.DrawingSurface.Canvas.DrawSurface(committedChunk.Surface.DrawingSurface, 0, 0, ReplacingPaint);
|
|
|
+ tempChunk.Surface.DrawingSurface.Canvas.DrawSurface(committedChunk.Surface.DrawingSurface, 0, 0,
|
|
|
+ ReplacingPaint);
|
|
|
blendModePaint.BlendMode = blendMode;
|
|
|
- tempChunk.Surface.DrawingSurface.Canvas.DrawSurface(latestChunk.AsT2.Surface.DrawingSurface, 0, 0, blendModePaint);
|
|
|
+ tempChunk.Surface.DrawingSurface.Canvas.DrawSurface(latestChunk.AsT2.Surface.DrawingSurface, 0, 0,
|
|
|
+ blendModePaint);
|
|
|
if (lockTransparency)
|
|
|
OperationHelper.ClampAlpha(tempChunk.Surface.DrawingSurface, committedChunk.Surface.DrawingSurface);
|
|
|
tempChunk.DrawOnSurface(surface, pos, paint);
|
|
@@ -377,7 +390,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
}
|
|
|
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
- public bool DrawCommittedChunkOn(VecI chunkPos, ChunkResolution resolution, DrawingSurface surface, VecI pos, Paint? paint = null)
|
|
|
+ public bool DrawCommittedChunkOn(VecI chunkPos, ChunkResolution resolution, DrawingSurface surface, VecI pos,
|
|
|
+ Paint? paint = null)
|
|
|
{
|
|
|
lock (lockObject)
|
|
|
{
|
|
@@ -442,7 +456,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
if (queuedOperations.Count > 0)
|
|
|
- throw new InvalidOperationException("This function can only be executed when there are no queued operations");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "This function can only be executed when there are no queued operations");
|
|
|
activeClips.Add(clippingMask);
|
|
|
}
|
|
|
}
|
|
@@ -454,7 +469,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
if (queuedOperations.Count > 0)
|
|
|
- throw new InvalidOperationException("This function can only be executed when there are no queued operations");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "This function can only be executed when there are no queued operations");
|
|
|
this.clippingPath = clippingPath;
|
|
|
}
|
|
|
}
|
|
@@ -469,7 +485,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
if (queuedOperations.Count > 0)
|
|
|
- throw new InvalidOperationException("This function can only be executed when there are no queued operations");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "This function can only be executed when there are no queued operations");
|
|
|
blendMode = mode;
|
|
|
}
|
|
|
}
|
|
@@ -481,7 +498,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
if (queuedOperations.Count > 0)
|
|
|
- throw new InvalidOperationException("This function can only be executed when there are no queued operations");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "This function can only be executed when there are no queued operations");
|
|
|
horizontalSymmetryAxis = position;
|
|
|
}
|
|
|
}
|
|
@@ -493,7 +511,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
if (queuedOperations.Count > 0)
|
|
|
- throw new InvalidOperationException("This function can only be executed when there are no queued operations");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "This function can only be executed when there are no queued operations");
|
|
|
verticalSymmetryAxis = position;
|
|
|
}
|
|
|
}
|
|
@@ -531,7 +550,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
}
|
|
|
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
- public void EnqueueDrawEllipse(RectI location, Color strokeColor, Color fillColor, int strokeWidth, Paint? paint = null)
|
|
|
+ public void EnqueueDrawEllipse(RectI location, Color strokeColor, Color fillColor, int strokeWidth,
|
|
|
+ Paint? paint = null)
|
|
|
{
|
|
|
lock (lockObject)
|
|
|
{
|
|
@@ -585,7 +605,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
EnqueueOperation(operation);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public void EnqueueApplyMask(ChunkyImage mask)
|
|
|
{
|
|
|
lock (lockObject)
|
|
@@ -598,7 +618,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
|
|
|
/// <param name="customBounds">Bounds used for affected chunks, will be computed from path in O(n) if null is passed</param>
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
- public void EnqueueDrawPath(VectorPath path, Color color, float strokeWidth, StrokeCap strokeCap, BlendMode blendMode, RectI? customBounds = null)
|
|
|
+ public void EnqueueDrawPath(VectorPath path, Color color, float strokeWidth, StrokeCap strokeCap,
|
|
|
+ BlendMode blendMode, RectI? customBounds = null)
|
|
|
{
|
|
|
lock (lockObject)
|
|
|
{
|
|
@@ -620,7 +641,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
}
|
|
|
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
- public void EnqueueDrawSkiaLine(VecI from, VecI to, StrokeCap strokeCap, float strokeWidth, Color color, BlendMode blendMode)
|
|
|
+ public void EnqueueDrawSkiaLine(VecI from, VecI to, StrokeCap strokeCap, float strokeWidth, Color color,
|
|
|
+ BlendMode blendMode)
|
|
|
{
|
|
|
lock (lockObject)
|
|
|
{
|
|
@@ -663,6 +685,16 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public void EnqueueDrawShader(Shader shader)
|
|
|
+ {
|
|
|
+ lock (lockObject)
|
|
|
+ {
|
|
|
+ ThrowIfDisposed();
|
|
|
+ ShaderOperation operation = new(shader);
|
|
|
+ EnqueueOperation(operation);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
public void EnqueueDrawCommitedChunkyImage(VecI pos, ChunkyImage image, bool flipHor = false, bool flipVer = false)
|
|
|
{
|
|
@@ -673,13 +705,14 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
EnqueueOperation(operation);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
public void EnqueueDrawUpToDateChunkyImage(VecI pos, ChunkyImage image, bool flipHor = false, bool flipVer = false)
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
ChunkyImageOperation operation = new(image, pos, flipHor, flipVer, true);
|
|
|
EnqueueOperation(operation);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/// <exception cref="ObjectDisposedException">This image is disposed</exception>
|
|
|
public void EnqueueClearRegion(RectI region)
|
|
|
{
|
|
@@ -842,7 +875,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
if (resolution == ChunkResolution.Full)
|
|
|
{
|
|
|
- throw new InvalidOperationException("Trying to commit a full res chunk that wasn't fully processed");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "Trying to commit a full res chunk that wasn't fully processed");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -891,13 +925,17 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
if (lockTransparency)
|
|
|
{
|
|
|
using Chunk tempChunk = Chunk.Create(resolution);
|
|
|
- tempChunk.Surface.DrawingSurface.Canvas.DrawSurface(maybeCommitted.Surface.DrawingSurface, 0, 0, ReplacingPaint);
|
|
|
- maybeCommitted.Surface.DrawingSurface.Canvas.DrawSurface(chunk.Surface.DrawingSurface, 0, 0, blendModePaint);
|
|
|
- OperationHelper.ClampAlpha(maybeCommitted.Surface.DrawingSurface, tempChunk.Surface.DrawingSurface);
|
|
|
+ tempChunk.Surface.DrawingSurface.Canvas.DrawSurface(maybeCommitted.Surface.DrawingSurface, 0, 0,
|
|
|
+ ReplacingPaint);
|
|
|
+ maybeCommitted.Surface.DrawingSurface.Canvas.DrawSurface(chunk.Surface.DrawingSurface, 0, 0,
|
|
|
+ blendModePaint);
|
|
|
+ OperationHelper.ClampAlpha(maybeCommitted.Surface.DrawingSurface,
|
|
|
+ tempChunk.Surface.DrawingSurface);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- maybeCommitted.Surface.DrawingSurface.Canvas.DrawSurface(chunk.Surface.DrawingSurface, 0, 0, blendModePaint);
|
|
|
+ maybeCommitted.Surface.DrawingSurface.Canvas.DrawSurface(chunk.Surface.DrawingSurface, 0, 0,
|
|
|
+ blendModePaint);
|
|
|
}
|
|
|
|
|
|
chunk.Dispose();
|
|
@@ -912,7 +950,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
if (resolution == ChunkResolution.Full)
|
|
|
continue;
|
|
|
- if (!latestChunksData[resolution].TryGetValue(pos, out var halfChunk) || halfChunk.QueueProgress != queuedOperations.Count)
|
|
|
+ if (!latestChunksData[resolution].TryGetValue(pos, out var halfChunk) ||
|
|
|
+ halfChunk.QueueProgress != queuedOperations.Count)
|
|
|
{
|
|
|
if (committedChunks[resolution].TryGetValue(pos, out var committedLowResChunk))
|
|
|
{
|
|
@@ -971,7 +1010,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
ThrowIfDisposed();
|
|
|
var chunks = new HashSet<VecI>();
|
|
|
RectI? rect = null;
|
|
|
-
|
|
|
+
|
|
|
for (int i = fromOperationIndex; i < queuedOperations.Count; i++)
|
|
|
{
|
|
|
var (_, area) = queuedOperations[i];
|
|
@@ -992,7 +1031,10 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
private void MaybeCreateAndProcessQueueForChunk(VecI chunkPos, ChunkResolution resolution)
|
|
|
{
|
|
|
if (!latestChunksData[resolution].TryGetValue(chunkPos, out LatestChunkData chunkData))
|
|
|
- chunkData = new() { QueueProgress = 0, IsDeleted = !committedChunks[ChunkResolution.Full].ContainsKey(chunkPos) };
|
|
|
+ chunkData = new()
|
|
|
+ {
|
|
|
+ QueueProgress = 0, IsDeleted = !committedChunks[ChunkResolution.Full].ContainsKey(chunkPos)
|
|
|
+ };
|
|
|
if (chunkData.QueueProgress == queuedOperations.Count)
|
|
|
return;
|
|
|
|
|
@@ -1015,12 +1057,14 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
}
|
|
|
|
|
|
if (chunkData.QueueProgress <= i)
|
|
|
- chunkData.IsDeleted = ApplyOperationToChunk(operation, affArea, combinedRasterClips, targetChunk!, chunkPos, resolution, chunkData);
|
|
|
+ chunkData.IsDeleted = ApplyOperationToChunk(operation, affArea, combinedRasterClips, targetChunk!,
|
|
|
+ chunkPos, resolution, chunkData);
|
|
|
}
|
|
|
|
|
|
if (initialized)
|
|
|
{
|
|
|
- if (lockTransparency && !chunkData.IsDeleted && MaybeGetCommittedChunk(chunkPos, ChunkResolution.Full) is not null)
|
|
|
+ if (lockTransparency && !chunkData.IsDeleted &&
|
|
|
+ MaybeGetCommittedChunk(chunkPos, ChunkResolution.Full) is not null)
|
|
|
{
|
|
|
var committed = GetCommittedChunk(chunkPos, resolution);
|
|
|
OperationHelper.ClampAlpha(targetChunk!.Surface.DrawingSurface, committed!.Surface.DrawingSurface);
|
|
@@ -1053,7 +1097,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
if (mask.CommittedChunkExists(chunkPos))
|
|
|
{
|
|
|
- mask.DrawCommittedChunkOn(chunkPos, resolution, intersection.Surface.DrawingSurface, VecI.Zero, ClippingPaint);
|
|
|
+ mask.DrawCommittedChunkOn(chunkPos, resolution, intersection.Surface.DrawingSurface, VecI.Zero,
|
|
|
+ ClippingPaint);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -1118,7 +1163,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
return chunkData.IsDeleted;
|
|
|
}
|
|
|
|
|
|
- private void CallDrawWithClip(IDrawOperation operation, RectI? operationAffectedArea, Chunk targetChunk, ChunkResolution resolution, VecI chunkPos)
|
|
|
+ private void CallDrawWithClip(IDrawOperation operation, RectI? operationAffectedArea, Chunk targetChunk,
|
|
|
+ ChunkResolution resolution, VecI chunkPos)
|
|
|
{
|
|
|
if (operationAffectedArea is null)
|
|
|
return;
|
|
@@ -1130,7 +1176,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
using VectorPath transformedPath = new(clippingPath);
|
|
|
VecD trans = -chunkPos * FullChunkSize * scale;
|
|
|
-
|
|
|
+
|
|
|
transformedPath.Transform(Matrix3X3.CreateScaleTranslation(scale, scale, (float)trans.X, (float)trans.Y));
|
|
|
targetChunk.Surface.DrawingSurface.Canvas.ClipPath(transformedPath);
|
|
|
}
|
|
@@ -1156,7 +1202,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
{
|
|
|
ThrowIfDisposed();
|
|
|
if (queuedOperations.Count > 0)
|
|
|
- throw new InvalidOperationException("This function can only be used when there are no queued operations");
|
|
|
+ throw new InvalidOperationException(
|
|
|
+ "This function can only be used when there are no queued operations");
|
|
|
FindAndDeleteEmptyCommittedChunks();
|
|
|
return committedChunks[ChunkResolution.Full].Count == 0;
|
|
|
}
|
|
@@ -1171,7 +1218,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
|
|
|
private static bool IsOutsideBounds(VecI chunkPos, VecI imageSize)
|
|
|
{
|
|
|
- return chunkPos.X < 0 || chunkPos.Y < 0 || chunkPos.X * FullChunkSize >= imageSize.X || chunkPos.Y * FullChunkSize >= imageSize.Y;
|
|
|
+ return chunkPos.X < 0 || chunkPos.Y < 0 || chunkPos.X * FullChunkSize >= imageSize.X ||
|
|
|
+ chunkPos.Y * FullChunkSize >= imageSize.Y;
|
|
|
}
|
|
|
|
|
|
private void FindAndDeleteEmptyCommittedChunks()
|
|
@@ -1223,7 +1271,8 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
newChunk.Surface.DrawingSurface.Canvas.Save();
|
|
|
newChunk.Surface.DrawingSurface.Canvas.Scale((float)resolution.Multiplier());
|
|
|
|
|
|
- newChunk.Surface.DrawingSurface.Canvas.DrawSurface(existingFullResChunk.Surface.DrawingSurface, 0, 0, SmoothReplacingPaint);
|
|
|
+ newChunk.Surface.DrawingSurface.Canvas.DrawSurface(existingFullResChunk.Surface.DrawingSurface, 0, 0,
|
|
|
+ SmoothReplacingPaint);
|
|
|
newChunk.Surface.DrawingSurface.Canvas.Restore();
|
|
|
committedChunks[resolution][chunkPos] = newChunk;
|
|
|
return newChunk;
|
|
@@ -1329,5 +1378,5 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable
|
|
|
ChunkyImage clone = CloneFromCommitted();
|
|
|
return clone;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
}
|