PixelsOperation.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System.ComponentModel.DataAnnotations.Schema;
  2. using System.Linq;
  3. using ChunkyImageLib.DataHolders;
  4. using Drawie.Backend.Core.ColorsImpl;
  5. using Drawie.Backend.Core.Numerics;
  6. using Drawie.Backend.Core.Surfaces;
  7. using Drawie.Backend.Core.Surfaces.PaintImpl;
  8. using Drawie.Numerics;
  9. namespace ChunkyImageLib.Operations;
  10. internal class PixelsOperation : IMirroredDrawOperation
  11. {
  12. public bool IgnoreEmptyChunks => false;
  13. private readonly VecF[] pixels;
  14. private readonly Color color;
  15. private readonly BlendMode blendMode;
  16. private readonly Paint paint;
  17. public PixelsOperation(IEnumerable<VecI> pixels, Color color, BlendMode blendMode)
  18. {
  19. this.pixels = pixels.Select(pixel => new VecF(pixel.X, pixel.Y)).ToArray();
  20. this.color = color;
  21. this.blendMode = blendMode;
  22. paint = new Paint() { BlendMode = blendMode };
  23. }
  24. public void DrawOnChunk(Chunk targetChunk, VecI chunkPos)
  25. {
  26. // a hacky way to make the lines look slightly better on non full res chunks
  27. paint.Color = new Color(color.R, color.G, color.B, (byte)(color.A * targetChunk.Resolution.Multiplier()));
  28. DrawingSurface surf = targetChunk.Surface.DrawingSurface;
  29. surf.Canvas.Save();
  30. surf.Canvas.Scale((float)targetChunk.Resolution.Multiplier());
  31. surf.Canvas.Translate(-chunkPos * ChunkyImage.FullChunkSize);
  32. //surf.Canvas.DrawPoints(PointMode.Points, pixels, paint);
  33. // Drawing points with GPU chunks doesn't work well, that's why we draw rects instead
  34. foreach (var pixel in pixels)
  35. {
  36. surf.Canvas.DrawRect(new RectD((VecD)pixel, new VecD(1)), paint);
  37. }
  38. surf.Canvas.Restore();
  39. }
  40. public AffectedArea FindAffectedArea(VecI imageSize)
  41. {
  42. HashSet<VecI> affectedChunks = new HashSet<VecI>();
  43. RectI? affectedArea = null;
  44. foreach (var pixel in pixels)
  45. {
  46. affectedChunks.Add(OperationHelper.GetChunkPos(pixel, ChunkyImage.FullChunkSize));
  47. if (affectedArea is null)
  48. affectedArea = new RectI(pixel, VecI.One);
  49. else
  50. affectedArea = affectedArea.Value.Union(new RectI(pixel, VecI.One));
  51. }
  52. return new AffectedArea(affectedChunks, affectedArea);
  53. }
  54. public IDrawOperation AsMirrored(double? verAxisX, double? horAxisY)
  55. {
  56. var arr = pixels.Select(pixel => new VecI(
  57. verAxisX is not null ? (int)Math.Round(2 * (double)verAxisX - (int)pixel.X - 1) : (int)pixel.X,
  58. horAxisY is not null ? (int)Math.Round(2 * (double)horAxisY - (int)pixel.Y - 1) : (int)pixel.Y
  59. ));
  60. return new PixelsOperation(arr, color, blendMode);
  61. }
  62. public void Dispose()
  63. {
  64. paint.Dispose();
  65. }
  66. }