2
0

PixelOperation.cs 3.1 KB

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