50 lines
1.8 KiB
C#
50 lines
1.8 KiB
C#
using System;
|
|
using Minint.Core.Models;
|
|
|
|
namespace Minint.Core.Services.Impl;
|
|
|
|
public sealed class FragmentService : IFragmentService
|
|
{
|
|
public void CopyFragment(
|
|
MinintDocument srcDoc, int srcLayerIndex,
|
|
int srcX, int srcY, int regionWidth, int regionHeight,
|
|
MinintDocument dstDoc, int dstLayerIndex,
|
|
int dstX, int dstY,
|
|
int containerWidth, int containerHeight)
|
|
{
|
|
ArgumentOutOfRangeException.ThrowIfNegative(srcLayerIndex);
|
|
ArgumentOutOfRangeException.ThrowIfNegative(dstLayerIndex);
|
|
if (srcLayerIndex >= srcDoc.Layers.Count)
|
|
throw new ArgumentOutOfRangeException(nameof(srcLayerIndex));
|
|
if (dstLayerIndex >= dstDoc.Layers.Count)
|
|
throw new ArgumentOutOfRangeException(nameof(dstLayerIndex));
|
|
|
|
var srcLayer = srcDoc.Layers[srcLayerIndex];
|
|
var dstLayer = dstDoc.Layers[dstLayerIndex];
|
|
|
|
int clippedSrcX = Math.Max(srcX, 0);
|
|
int clippedSrcY = Math.Max(srcY, 0);
|
|
int clippedEndX = Math.Min(srcX + regionWidth, containerWidth);
|
|
int clippedEndY = Math.Min(srcY + regionHeight, containerHeight);
|
|
|
|
for (int sy = clippedSrcY; sy < clippedEndY; sy++)
|
|
{
|
|
int dy = dstY + (sy - srcY);
|
|
if (dy < 0 || dy >= containerHeight) continue;
|
|
|
|
for (int sx = clippedSrcX; sx < clippedEndX; sx++)
|
|
{
|
|
int dx = dstX + (sx - srcX);
|
|
if (dx < 0 || dx >= containerWidth) continue;
|
|
|
|
int srcIdx = srcLayer.Pixels[sy * containerWidth + sx];
|
|
if (srcIdx == 0) continue; // skip transparent
|
|
|
|
RgbaColor color = srcDoc.Palette[srcIdx];
|
|
int dstIdx = dstDoc.EnsureColorCached(color);
|
|
dstLayer.Pixels[dy * containerWidth + dx] = dstIdx;
|
|
}
|
|
}
|
|
}
|
|
}
|