CreateImageNode.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using PixiEditor.ChangeableDocument.Rendering;
  2. using Drawie.Backend.Core;
  3. using Drawie.Backend.Core.Bridge;
  4. using Drawie.Backend.Core.ColorsImpl;
  5. using Drawie.Backend.Core.ColorsImpl.Paintables;
  6. using Drawie.Backend.Core.Numerics;
  7. using Drawie.Backend.Core.Surfaces;
  8. using Drawie.Backend.Core.Surfaces.ImageData;
  9. using Drawie.Backend.Core.Surfaces.PaintImpl;
  10. using Drawie.Numerics;
  11. using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
  12. namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
  13. [NodeInfo("CreateImage")]
  14. public class CreateImageNode : Node, IPreviewRenderable
  15. {
  16. public OutputProperty<Texture> Output { get; }
  17. public InputProperty<VecI> Size { get; }
  18. public InputProperty<Paintable> Fill { get; }
  19. public RenderInputProperty Content { get; }
  20. public InputProperty<Matrix3X3> ContentMatrix { get; }
  21. public RenderOutputProperty RenderOutput { get; }
  22. private TextureCache textureCache = new();
  23. public CreateImageNode()
  24. {
  25. Output = CreateOutput<Texture>(nameof(Output), "IMAGE", null);
  26. Size = CreateInput(nameof(Size), "SIZE", new VecI(32, 32)).WithRules(v => v.Min(VecI.One));
  27. Fill = CreateInput<Paintable>(nameof(Fill), "FILL", new ColorPaintable(Colors.Transparent));
  28. Content = CreateRenderInput(nameof(Content), "CONTENT");
  29. ContentMatrix = CreateInput<Matrix3X3>(nameof(ContentMatrix), "MATRIX", Matrix3X3.Identity);
  30. RenderOutput = CreateRenderOutput("RenderOutput", "RENDER_OUTPUT", () => new Painter(OnPaint));
  31. }
  32. protected override void OnExecute(RenderContext context)
  33. {
  34. if (Size.Value.X <= 0 || Size.Value.Y <= 0)
  35. {
  36. return;
  37. }
  38. var surface = Render(context);
  39. Output.Value = surface;
  40. RenderOutput.ChainToPainterValue();
  41. }
  42. private Texture Render(RenderContext context)
  43. {
  44. var surface = textureCache.RequestTexture(0, Size.Value, context.ProcessingColorSpace, false);
  45. if (Fill.Value is ColorPaintable colorPaintable)
  46. {
  47. surface.DrawingSurface.Canvas.Clear(colorPaintable.Color);
  48. }
  49. else
  50. {
  51. using Paint paint = new Paint();
  52. paint.SetPaintable(Fill.Value);
  53. surface.DrawingSurface.Canvas.DrawRect(0, 0, Size.Value.X, Size.Value.Y, paint);
  54. }
  55. int saved = surface.DrawingSurface.Canvas.Save();
  56. RenderContext ctx = new RenderContext(surface.DrawingSurface, context.FrameTime, context.ChunkResolution,
  57. context.RenderOutputSize, context.DocumentSize, context.ProcessingColorSpace);
  58. surface.DrawingSurface.Canvas.SetMatrix(surface.DrawingSurface.Canvas.TotalMatrix.Concat(ContentMatrix.Value));
  59. Content.Value?.Paint(ctx, surface.DrawingSurface);
  60. surface.DrawingSurface.Canvas.RestoreToCount(saved);
  61. return surface;
  62. }
  63. private void OnPaint(RenderContext context, DrawingSurface surface)
  64. {
  65. if(Output.Value == null || Output.Value.IsDisposed) return;
  66. surface.Canvas.DrawSurface(Output.Value.DrawingSurface, 0, 0);
  67. }
  68. public override Node CreateCopy() => new CreateImageNode();
  69. public override void Dispose()
  70. {
  71. base.Dispose();
  72. textureCache.Dispose();
  73. }
  74. public RectD? GetPreviewBounds(int frame, string elementToRenderName = "")
  75. {
  76. if (Size.Value.X <= 0 || Size.Value.Y <= 0)
  77. {
  78. return null;
  79. }
  80. return new RectD(0, 0, Size.Value.X, Size.Value.Y);
  81. }
  82. public bool RenderPreview(DrawingSurface renderOn, RenderContext context, string elementToRenderName)
  83. {
  84. if (Size.Value.X <= 0 || Size.Value.Y <= 0)
  85. {
  86. return false;
  87. }
  88. if (Output.Value == null)
  89. {
  90. return false;
  91. }
  92. var surface = Render(context);
  93. if (surface == null || surface.IsDisposed)
  94. {
  95. return false;
  96. }
  97. renderOn.Canvas.DrawSurface(surface.DrawingSurface, 0, 0);
  98. return true;
  99. }
  100. }