PixelOperation.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using ChunkyImageLib.DataHolders;
  2. using PixiEditor.DrawingApi.Core.ColorsImpl;
  3. using PixiEditor.DrawingApi.Core.Numerics;
  4. using PixiEditor.DrawingApi.Core.Surface;
  5. using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
  6. namespace ChunkyImageLib.Operations;
  7. public delegate Color PixelProcessor(Color commited, Color upToDate);
  8. internal class PixelOperation : IMirroredDrawOperation
  9. {
  10. public bool IgnoreEmptyChunks => false;
  11. private readonly VecI pixel;
  12. private readonly Color color;
  13. private readonly BlendMode blendMode;
  14. private readonly Paint paint;
  15. private readonly Func<VecI, Color>? getCommitedPixelFunc = null;
  16. private readonly PixelProcessor? colorProcessor = null;
  17. public PixelOperation(VecI pixel, Color color, BlendMode blendMode)
  18. {
  19. this.pixel = pixel;
  20. this.color = color;
  21. this.blendMode = blendMode;
  22. paint = new Paint() { BlendMode = blendMode };
  23. }
  24. public PixelOperation(VecI pixel, PixelProcessor colorProcessor, Func<VecI, Color> getCommitedPixelFunc, BlendMode blendMode)
  25. {
  26. this.pixel = pixel;
  27. this.colorProcessor = colorProcessor;
  28. this.blendMode = blendMode;
  29. this.getCommitedPixelFunc = getCommitedPixelFunc;
  30. paint = new Paint() { BlendMode = blendMode };
  31. }
  32. public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
  33. {
  34. // a hacky way to make the lines look slightly better on non full res chunks
  35. paint.Color = GetColor(targetChunk, chunkPos);
  36. DrawingSurface surf = targetChunk.Surface.DrawingSurface;
  37. surf.Canvas.Save();
  38. surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
  39. surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
  40. surf.Canvas.DrawPoint(pixel, paint);
  41. surf.Canvas.Restore();
  42. }
  43. private Color GetColor(Chunk chunk, VecI chunkPos)
  44. {
  45. Color pixelColor = color;
  46. if (colorProcessor != null && getCommitedPixelFunc != null)
  47. {
  48. var pos = pixel - chunkPos * ChunkyImage.FullChunkSize;
  49. pixelColor = colorProcessor(getCommitedPixelFunc(pos), chunk.Surface.GetSRGBPixel(pos));
  50. }
  51. return new Color(pixelColor.R, pixelColor.G, pixelColor.B, (byte)(pixelColor.A * chunk.Resolution.Multiplier()));
  52. }
  53. public AffectedArea FindAffectedArea(VecI imageSize)
  54. {
  55. return new AffectedArea(new HashSet<VecI>() { OperationHelper.GetChunkPos(pixel, ChunkyImage.FullChunkSize) }, new RectI(pixel, VecI.One));
  56. }
  57. public IDrawOperation AsMirrored(double? verAxisX, double? horAxisY)
  58. {
  59. RectI pixelRect = new RectI(pixel, new VecI(1, 1));
  60. if (verAxisX is not null)
  61. pixelRect = (RectI)pixelRect.ReflectX((double)verAxisX).Round();
  62. if (horAxisY is not null)
  63. pixelRect = (RectI)pixelRect.ReflectY((double)horAxisY);
  64. if (colorProcessor != null && getCommitedPixelFunc != null)
  65. {
  66. return new PixelOperation(pixelRect.Pos, colorProcessor, getCommitedPixelFunc, blendMode);
  67. }
  68. return new PixelOperation(pixelRect.Pos, color, blendMode);
  69. }
  70. public void Dispose()
  71. {
  72. paint.Dispose();
  73. }
  74. }