ReplaceColorOperation.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using ChunkyImageLib.DataHolders;
  2. using ChunkyImageLib.Shaders;
  3. using ComputeSharp;
  4. using PixiEditor.DrawingApi.Core.ColorsImpl;
  5. using PixiEditor.DrawingApi.Core.Numerics;
  6. namespace ChunkyImageLib.Operations;
  7. internal class ReplaceColorOperation : IDrawOperation
  8. {
  9. private readonly Color oldColor;
  10. private readonly Color newColor;
  11. private readonly ColorBounds oldColorBounds;
  12. private readonly HlslColorBounds oldColorBoundsHlsl;
  13. private readonly ulong newColorBits;
  14. public bool IgnoreEmptyChunks => true;
  15. public ReplaceColorOperation(Color oldColor, Color newColor)
  16. {
  17. this.oldColor = oldColor;
  18. this.newColor = newColor;
  19. oldColorBounds = new ColorBounds(oldColor);
  20. oldColorBoundsHlsl = new HlslColorBounds(new Float4(oldColor.R, oldColor.G, oldColor.B, oldColor.A));
  21. newColorBits = newColor.ToULong();
  22. }
  23. public void DrawOnChunk(Chunk chunk, VecI chunkPos)
  24. {
  25. ReplaceColor(oldColorBoundsHlsl, newColor, chunk);
  26. }
  27. private static void ReplaceColor(HlslColorBounds oldColorBounds, Color newColor, Chunk chunk)
  28. {
  29. Span<UInt2> span = chunk.Surface.DrawingSurface.PeekPixels().GetPixelSpan<UInt2>();
  30. using var texture = GraphicsDevice.GetDefault()
  31. .AllocateReadWriteTexture2D<UInt2>(chunk.PixelSize.X, chunk.PixelSize.Y);
  32. texture.CopyFrom(span);
  33. UInt2 packedColor = ShaderUtils.PackPixel(newColor);
  34. GraphicsDevice.GetDefault().For(texture.Width, texture.Height,
  35. new ReplaceColorShader(
  36. texture,
  37. oldColorBounds,
  38. packedColor));
  39. texture.CopyTo(span);
  40. }
  41. public HashSet<VecI> FindAffectedChunks(VecI imageSize)
  42. {
  43. return OperationHelper.FindChunksTouchingRectangle(new RectI(VecI.Zero, imageSize), ChunkyImage.FullChunkSize);
  44. }
  45. public IDrawOperation AsMirrored(int? verAxisX, int? horAxisY)
  46. {
  47. return new ReplaceColorOperation(oldColor, newColor);
  48. }
  49. public void Dispose() { }
  50. }