using System; using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Layout; using Avalonia.Media; using Xunit; namespace Avalonia.Skia.RenderTests { public class CustomRenderTests : TestBase { public CustomRenderTests() : base(@"Controls\CustomRender") { } [Fact] public async Task Clip() { Decorator target = new Decorator { Padding = new Thickness(8), Width = 200, Height = 200, Child = new CustomRenderer((control, context) => { context.FillRectangle( Brushes.Red, new Rect(control.Bounds.Size), 4); using (context.PushClip(new Rect(control.Bounds.Size).Deflate(10))) { context.FillRectangle( Brushes.Blue, new Rect(control.Bounds.Size), 4); } }), }; await RenderToFile(target); CompareImages(); } [Fact] public async Task GeometryClip() { Decorator target = new Decorator { Padding = new Thickness(8), Width = 200, Height = 200, Child = new CustomRenderer((control, context) => { var clip = new EllipseGeometry(new Rect(control.Bounds.Size)); context.FillRectangle( Brushes.Red, new Rect(control.Bounds.Size), 4); using (context.PushGeometryClip(clip)) { context.FillRectangle( Brushes.Blue, new Rect(control.Bounds.Size), 4); } }), }; await RenderToFile(target); CompareImages(); } [Fact] public async Task GeometryClip_With_Transform() { var target = new Border { Background = Brushes.White, Width = 200, Height = 200, Child = new CustomRenderer((control, context) => { using (var transform = context.PushTransform(Matrix.CreateTranslation(100, 100))) using (var clip = context.PushClip(new Rect(0, 0, 100, 100))) { context.FillRectangle(Brushes.Blue, new Rect(0, 0, 200, 200)); } context.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100)); }), }; await RenderToFile(target); CompareImages(); } [Fact] public async Task Clip_With_Transform() { var target = new Border { Background = Brushes.White, Width = 200, Height = 200, Child = new CustomRenderer((control, context) => { using (var transform = context.PushTransform(Matrix.CreateTranslation(100, 100))) using (var clip = context.PushClip(new Rect(0, 0, 100, 100))) { context.FillRectangle(Brushes.Blue, new Rect(0, 0, 200, 200)); } context.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100)); }), }; await RenderToFile(target); CompareImages(); } [Fact] public async Task Opacity() { Decorator target = new Decorator { Padding = new Thickness(8), Width = 200, Height = 200, Child = new CustomRenderer((control, context) => { context.FillRectangle( Brushes.Red, new Rect(control.Bounds.Size), 4); using (context.PushOpacity(0.5)) { context.FillRectangle( Brushes.Blue, new Rect(control.Bounds.Size).Deflate(10), 4); } }), }; await RenderToFile(target); CompareImages(); } [Fact] public async Task OpacityMask() { Decorator target = new Decorator { Padding = new Thickness(8), Width = 200, Height = 200, Child = new CustomRenderer((control, context) => { var mask = new LinearGradientBrush { StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative), EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative), GradientStops = { new GradientStop(Color.FromUInt32(0xffffffff), 0), new GradientStop(Color.FromUInt32(0x00ffffff), 1) }, }; context.FillRectangle( Brushes.Red, new Rect(control.Bounds.Size), 4); using (context.PushOpacityMask(mask, new Rect(control.Bounds.Size))) { context.FillRectangle( Brushes.Blue, new Rect(control.Bounds.Size).Deflate(10), 4); } }), }; await RenderToFile(target); CompareImages(); } class CustomRenderer : Control { private Action _render; public CustomRenderer(Action render) => _render = render; public override void Render(DrawingContext context) => _render(this, context); } } }