using ChunkyImageLib.DataHolders;
using ChunkyImageLib.Operations;
using Drawie.Backend.Core.Surfaces;
using Drawie.Backend.Core.Surfaces.PaintImpl;
using Drawie.Numerics;
namespace ChunkyImageLib;
public static class IReadOnlyChunkyImageEx
{
public static void DrawMostUpToDateRegionOn
(this IReadOnlyChunkyImage image, RectD fullResRegion, ChunkResolution resolution, Canvas surface,
VecD pos, Paint? paint = null, SamplingOptions? sampling = null, bool drawPaintOnEmpty = false)
{
DrawRegionOn(fullResRegion, resolution, surface, pos, image.DrawMostUpToDateChunkOn, paint, sampling, drawPaintOnEmpty);
}
public static void DrawMostUpToDateRegionOnWithAffected
(this IReadOnlyChunkyImage image, RectD fullResRegion, ChunkResolution resolution, Canvas surface,
AffectedArea affectedArea, VecD pos, Paint? paint = null, SamplingOptions? sampling = null, bool drawPaintOnEmpty = false)
{
DrawRegionOn(fullResRegion, resolution, surface, pos, image.DrawMostUpToDateChunkOn,
image.DrawCachedMostUpToDateChunkOn, affectedArea, paint, sampling, drawPaintOnEmpty);
}
public static void DrawMostUpToDateAffectedArea
(this IReadOnlyChunkyImage image, RectD fullResRegion, ChunkResolution resolution, Canvas surface,
AffectedArea affectedArea, VecD pos, Paint? paint = null, Paint? emptyPaint = null, SamplingOptions? sampling = null)
{
if (affectedArea.Chunks is null)
return;
int count = surface.Save();
surface.ClipRect(new RectD(pos, fullResRegion.Size));
VecI chunkTopLeft = OperationHelper.GetChunkPos((VecI)fullResRegion.TopLeft, ChunkyImage.FullChunkSize);
VecI chunkBotRight = OperationHelper.GetChunkPos((VecI)fullResRegion.BottomRight, ChunkyImage.FullChunkSize);
VecD offsetFullRes = (chunkTopLeft * ChunkyImage.FullChunkSize) - fullResRegion.Pos;
VecD offsetTargetRes = offsetFullRes * resolution.Multiplier();
foreach (var chunkPos in affectedArea.Chunks)
{
if (!image.DrawMostUpToDateChunkOn(chunkPos, resolution, surface,
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos, paint, sampling) && emptyPaint != null)
{
surface.DrawRect(new RectD(
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos,
new VecD(resolution.PixelSize())), emptyPaint);
}
}
surface.RestoreToCount(count);
}
public static void DrawCommittedRegionOn
(this IReadOnlyChunkyImage image, RectD fullResRegion, ChunkResolution resolution, Canvas surface,
VecI pos, Paint? paint = null, SamplingOptions? samplingOptions = null, bool drawPaintOnEmpty = false)
{
DrawRegionOn(fullResRegion, resolution, surface, pos, image.DrawCommittedChunkOn, paint, samplingOptions, drawPaintOnEmpty);
}
private static void DrawRegionOn(
RectD fullResRegion,
ChunkResolution resolution,
Canvas surface,
VecD pos,
Func<VecI, ChunkResolution, Canvas, VecD, Paint?, SamplingOptions?, bool> drawingFunc,
Paint? paint = null, SamplingOptions? samplingOptions = null, bool drawPaintOnEmpty = false)
{
int count = surface.Save();
surface.ClipRect(new RectD(pos, fullResRegion.Size));
VecI chunkTopLeft = OperationHelper.GetChunkPos((VecI)fullResRegion.TopLeft, ChunkyImage.FullChunkSize);
VecI chunkBotRight = OperationHelper.GetChunkPos((VecI)fullResRegion.BottomRight, ChunkyImage.FullChunkSize);
VecD offsetFullRes = (chunkTopLeft * ChunkyImage.FullChunkSize) - fullResRegion.Pos;
VecD offsetTargetRes = offsetFullRes * resolution.Multiplier();
for (int j = chunkTopLeft.Y; j <= chunkBotRight.Y; j++)
{
for (int i = chunkTopLeft.X; i <= chunkBotRight.X; i++)
{
var chunkPos = new VecI(i, j);
if (!drawingFunc(chunkPos, resolution, surface,
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos, paint,
samplingOptions) && paint != null && drawPaintOnEmpty)
{
surface.DrawRect(new RectD(
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos,
new VecD(resolution.PixelSize())), paint);
}
}
}
surface.RestoreToCount(count);
}
private static void DrawRegionOn(
RectD fullResRegion,
ChunkResolution resolution,
Canvas surface,
VecD pos,
Func<VecI, ChunkResolution, Canvas, VecD, Paint?, SamplingOptions?, bool> drawingFunc,
Func<VecI, ChunkResolution, Canvas, VecD, Paint?, SamplingOptions?, bool> quickDrawingFunc,
AffectedArea area,
Paint? paint = null, SamplingOptions? samplingOptions = null, bool drawPaintOnEmpty = false)
{
int count = surface.Save();
surface.ClipRect(new RectD(pos, fullResRegion.Size));
VecI chunkTopLeft = OperationHelper.GetChunkPos((VecI)fullResRegion.TopLeft, ChunkyImage.FullChunkSize);
VecI chunkBotRight = OperationHelper.GetChunkPos((VecI)fullResRegion.BottomRight, ChunkyImage.FullChunkSize);
VecD offsetFullRes = (chunkTopLeft * ChunkyImage.FullChunkSize) - fullResRegion.Pos;
VecD offsetTargetRes = offsetFullRes * resolution.Multiplier();
for (int j = chunkTopLeft.Y; j <= chunkBotRight.Y; j++)
{
for (int i = chunkTopLeft.X; i <= chunkBotRight.X; i++)
{
var chunkPos = new VecI(i, j);
if (area.Chunks != null && area.Chunks.Contains(chunkPos))
{
if (!drawingFunc(chunkPos, resolution, surface,
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos, paint,
samplingOptions) && paint != null && drawPaintOnEmpty)
{
surface.DrawRect(new RectD(
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos,
new VecD(resolution.PixelSize())), paint);
}
}
else
{
if (!quickDrawingFunc(chunkPos, resolution, surface,
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos, paint,
samplingOptions) && paint != null && drawPaintOnEmpty)
{
surface.DrawRect(new RectD(
offsetTargetRes + (chunkPos - chunkTopLeft) * resolution.PixelSize() + pos,
new VecD(resolution.PixelSize())), paint);
}
}
}
}
surface.RestoreToCount(count);
}
}