diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs
index 5e3e301461..fa5b78c278 100644
--- a/samples/ControlCatalog.NetCore/Program.cs
+++ b/samples/ControlCatalog.NetCore/Program.cs
@@ -10,6 +10,7 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Fonts.Inter;
using Avalonia.Headless;
using Avalonia.LogicalTree;
+using Avalonia.Rendering.Composition;
using Avalonia.Threading;
using ControlCatalog.Pages;
@@ -130,6 +131,10 @@ namespace ControlCatalog.NetCore
UseDBusMenu = true,
EnableIme = true
})
+ .With(new CompositionOptions()
+ {
+ UseRegionDirtyRectClipping = true
+ })
.UseSkia()
.WithInterFont()
.AfterSetup(builder =>
diff --git a/samples/ControlCatalog/Pages/CompositionPage.axaml b/samples/ControlCatalog/Pages/CompositionPage.axaml
index 602b9b768d..4d9bb41781 100644
--- a/samples/ControlCatalog/Pages/CompositionPage.axaml
+++ b/samples/ControlCatalog/Pages/CompositionPage.axaml
@@ -50,6 +50,10 @@
+ Precise dirty rects
diff --git a/samples/ControlCatalog/Pages/CompositionPage.axaml.cs b/samples/ControlCatalog/Pages/CompositionPage.axaml.cs
index 5bf46510dc..da12accd58 100644
--- a/samples/ControlCatalog/Pages/CompositionPage.axaml.cs
+++ b/samples/ControlCatalog/Pages/CompositionPage.axaml.cs
@@ -24,7 +24,7 @@ public partial class CompositionPage : UserControl
public CompositionPage()
{
- AvaloniaXamlLoader.Load(this);
+ InitializeComponent();
AttachAnimatedSolidVisual(this.FindControl("SolidVisualHost")!);
AttachCustomVisual(this.FindControl("CustomVisualHost")!);
}
@@ -206,6 +206,7 @@ public partial class CompositionPage : UserControl
_customVisual = compositor.CreateCustomVisual(new CustomVisualHandler());
ElementComposition.SetElementChildVisual(v, _customVisual);
_customVisual.SendHandlerMessage(CustomVisualHandler.StartMessage);
+ PreciseDirtyRectsCheckboxCustomVisualChanged(this, new());
Update();
};
@@ -221,10 +222,16 @@ public partial class CompositionPage : UserControl
private TimeSpan _animationElapsed;
private TimeSpan? _lastServerTime;
private bool _running;
+ private bool _preciseDirtyRects;
- public static readonly object StopMessage = new(), StartMessage = new();
-
- public override void OnRender(ImmediateDrawingContext drawingContext)
+ public static readonly object StopMessage = new(),
+ StartMessage = new(),
+ UsePreciseDirtyRects = new(),
+ UseNonPreciseDirtyRects = new();
+
+ private List<(Point center, double size, ImmutableSolidColorBrush brush)> _ellipses = new();
+
+ void UpdateRects()
{
if (_running)
{
@@ -232,6 +239,8 @@ public partial class CompositionPage : UserControl
_lastServerTime = CompositionNow;
}
+ _ellipses.Clear();
+
const int cnt = 20;
var maxPointSizeX = EffectiveSize.X / (cnt * 1.6);
var maxPointSizeY = EffectiveSize.Y / 4;
@@ -250,16 +259,22 @@ public partial class CompositionPage : UserControl
var posY = (EffectiveSize.Y - pointSize) * (1 + Math.Sin(stage * 3.14 * 3 + sinOffset)) / 2 + pointSize / 2;
var opacity = Math.Sin(stage * 3.14);
-
- drawingContext.DrawEllipse(new ImmutableSolidColorBrush(Color.FromArgb(
- 255,
- (byte)(255 - 255 * colorStage),
- (byte)(255 * Math.Abs(0.5 - colorStage) * 2),
- (byte)(255 * colorStage)
- ), opacity), null,
- new Point(posX, posY), pointSize / 2, pointSize / 2);
+ _ellipses.Add((new Point(posX, posY), pointSize / 2, new ImmutableSolidColorBrush(Color.FromArgb(
+ 255,
+ (byte)(255 - 255 * colorStage),
+ (byte)(255 * Math.Abs(0.5 - colorStage) * 2),
+ (byte)(255 * colorStage)
+ ), opacity)));
}
+ }
+
+ public override void OnRender(ImmediateDrawingContext drawingContext)
+ {
+ if (_ellipses.Count == 0)
+ UpdateRects();
+ foreach(var e in _ellipses)
+ drawingContext.DrawEllipse(e.brush, null, e.center, e.size, e.size);
}
public override void OnMessage(object message)
@@ -272,13 +287,29 @@ public partial class CompositionPage : UserControl
}
else if (message == StopMessage)
_running = false;
+ else if (message == UsePreciseDirtyRects)
+ _preciseDirtyRects = true;
+ else if (message == UseNonPreciseDirtyRects)
+ _preciseDirtyRects = false;
}
+ void InvalidateCurrentEllipseRects()
+ {
+ foreach (var e in _ellipses)
+ Invalidate(new Rect(e.center.X - e.size, e.center.Y - e.size, e.size * 2, e.size * 2));
+ }
+
public override void OnAnimationFrameUpdate()
{
if (_running)
{
- Invalidate();
+ if (_preciseDirtyRects)
+ InvalidateCurrentEllipseRects();
+ else
+ Invalidate();
+ UpdateRects();
+ if(_preciseDirtyRects)
+ InvalidateCurrentEllipseRects();
RegisterForNextAnimationFrameUpdate();
}
}
@@ -298,6 +329,13 @@ public partial class CompositionPage : UserControl
{
_customVisual?.SendHandlerMessage(CustomVisualHandler.StopMessage);
}
+
+ private void PreciseDirtyRectsCheckboxCustomVisualChanged(object sender, RoutedEventArgs e)
+ {
+ _customVisual?.SendHandlerMessage(PreciseDirtyRectsCheckboxCustomVisual?.IsChecked == true
+ ? CustomVisualHandler.UsePreciseDirtyRects
+ : CustomVisualHandler.UseNonPreciseDirtyRects);
+ }
}
public class CompositionPageColorItem
diff --git a/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs b/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs
index b1c9c81b39..9f41177223 100644
--- a/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs
+++ b/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs
@@ -77,7 +77,7 @@ namespace Avalonia.Media.Imaging
/// The drawing context.
public DrawingContext CreateDrawingContext(bool clear)
{
- var platform = PlatformImpl.Item.CreateDrawingContext();
+ var platform = PlatformImpl.Item.CreateDrawingContext(true);
if(clear)
platform.Clear(Colors.Transparent);
return new PlatformDrawingContext(platform);
diff --git a/src/Avalonia.Base/PixelSize.cs b/src/Avalonia.Base/PixelSize.cs
index 5a34c6f6b5..251fe6ff85 100644
--- a/src/Avalonia.Base/PixelSize.cs
+++ b/src/Avalonia.Base/PixelSize.cs
@@ -166,6 +166,17 @@ namespace Avalonia
public static PixelSize FromSize(Size size, double scale) => new PixelSize(
(int)Math.Ceiling(size.Width * scale),
(int)Math.Ceiling(size.Height * scale));
+
+ ///
+ /// A reversible variant of that uses Round instead of Ceiling to make it reversible from ToSize
+ ///
+ /// The size.
+ /// The scaling factor.
+ /// The device-independent size.
+ internal static PixelSize FromSizeRounded(Size size, double scale) => new PixelSize(
+ (int)Math.Round(size.Width * scale),
+ (int)Math.Round(size.Height * scale));
+
///
/// Converts a to device pixels using the specified scaling factor.
diff --git a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs
index fe411c350d..f367ed89ca 100644
--- a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs
+++ b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs
@@ -3,6 +3,7 @@ using Avalonia.Media;
using Avalonia.Utilities;
using Avalonia.Metadata;
using Avalonia.Media.Imaging;
+using Avalonia.Media.Immutable;
namespace Avalonia.Platform
{
@@ -75,6 +76,18 @@ namespace Avalonia.Platform
///
void DrawRectangle(IBrush? brush, IPen? pen, RoundedRect rect,
BoxShadows boxShadows = default);
+
+ ///
+ /// Draws the specified region with the specified Brush and Pen.
+ ///
+ /// The brush used to fill the rectangle, or null for no fill.
+ /// The pen used to stroke the rectangle, or null for no stroke.
+ /// The region to draw.
+ ///
+ /// The brush and the pen can both be null. If the brush is null, then no fill is performed.
+ /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible.
+ ///
+ void DrawRegion(IBrush? brush, IPen? pen, IPlatformRenderInterfaceRegion region);
///
/// Draws an ellipse with the specified Brush and Pen.
@@ -108,7 +121,7 @@ namespace Avalonia.Platform
/// has to do a format conversion each time a standard render target bitmap is rendered,
/// but a layer created via this method has no such overhead.
///
- IDrawingContextLayerImpl CreateLayer(Size size);
+ IDrawingContextLayerImpl CreateLayer(PixelSize size);
///
/// Pushes a clip rectangle.
@@ -121,12 +134,28 @@ namespace Avalonia.Platform
///
/// The clip rounded rectangle
void PushClip(RoundedRect clip);
-
+
+ ///
+ /// Pushes a clip region.
+ ///
+ /// The clip region
+ void PushClip(IPlatformRenderInterfaceRegion region);
+
///
/// Pops the latest pushed clip rectangle.
///
void PopClip();
+ ///
+ /// Enforces rendering to happen on an intermediate surface
+ ///
+ void PushLayer(Rect bounds);
+
+ ///
+ /// Pops the latest pushed intermediate surface layer.
+ ///
+ void PopLayer();
+
///
/// Pushes an opacity value.
///
diff --git a/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs b/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs
index c783a5ea65..0ead242a27 100644
--- a/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs
+++ b/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs
@@ -199,6 +199,9 @@ namespace Avalonia.Platform
public PixelFormat DefaultPixelFormat { get; }
bool IsSupportedBitmapPixelFormat(PixelFormat format);
+
+ bool SupportsRegions { get; }
+ IPlatformRenderInterfaceRegion CreateRegion();
}
[Unstable, PrivateApi]
diff --git a/src/Avalonia.Base/Platform/IPlatformRenderInterfaceRegion.cs b/src/Avalonia.Base/Platform/IPlatformRenderInterfaceRegion.cs
new file mode 100644
index 0000000000..682609391c
--- /dev/null
+++ b/src/Avalonia.Base/Platform/IPlatformRenderInterfaceRegion.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Metadata;
+
+namespace Avalonia.Platform;
+
+[Unstable, PrivateApi]
+public interface IPlatformRenderInterfaceRegion : IDisposable
+{
+ void AddRect(PixelRect rect);
+ void Reset();
+ bool IsEmpty { get; }
+ PixelRect Bounds { get; }
+ IList Rects { get; }
+ bool Intersects(Rect rect);
+ bool Contains(Point pt);
+}
\ No newline at end of file
diff --git a/src/Avalonia.Base/Platform/IRenderTarget.cs b/src/Avalonia.Base/Platform/IRenderTarget.cs
index 2b4584483e..a1f33db6c7 100644
--- a/src/Avalonia.Base/Platform/IRenderTarget.cs
+++ b/src/Avalonia.Base/Platform/IRenderTarget.cs
@@ -16,7 +16,8 @@ namespace Avalonia.Platform
///
/// Creates an for a rendering session.
///
- IDrawingContextImpl CreateDrawingContext();
+ /// Apply DPI reported by the render target as a hidden transform matrix
+ IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing);
///
/// Indicates if the render target is no longer usable and needs to be recreated
diff --git a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
index eef5188564..2a4345f702 100644
--- a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
+++ b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
@@ -172,7 +172,8 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
v.SynchronizeCompositionChildVisuals();
_dirty.Clear();
_recalculateChildren.Clear();
- CompositionTarget.Size = _root.ClientSize;
+
+ CompositionTarget.PixelSize = PixelSize.FromSizeRounded(_root.ClientSize, _root.RenderScaling);
CompositionTarget.Scaling = _root.RenderScaling;
var commit = _compositor.RequestCommitAsync();
diff --git a/src/Avalonia.Base/Rendering/Composition/CompositionCustomVisual.cs b/src/Avalonia.Base/Rendering/Composition/CompositionCustomVisual.cs
index 1d7887cd0e..79f2cc3fb9 100644
--- a/src/Avalonia.Base/Rendering/Composition/CompositionCustomVisual.cs
+++ b/src/Avalonia.Base/Rendering/Composition/CompositionCustomVisual.cs
@@ -1,12 +1,15 @@
using System.Collections.Generic;
using System.Numerics;
+using Avalonia.Media;
using Avalonia.Rendering.Composition.Server;
using Avalonia.Rendering.Composition.Transport;
+using Avalonia.Threading;
namespace Avalonia.Rendering.Composition;
public sealed class CompositionCustomVisual : CompositionContainerVisual
{
+ private static readonly ThreadSafeObjectPool> s_messageListPool = new();
private List
public Matrix Transform
{
- get { return _deviceContext.Transform.ToAvalonia(); }
- set { _deviceContext.Transform = value.ToDirect2D(); }
+ get { return _transform; }
+ set
+ {
+ _transform = value;
+ _deviceContext.Transform =
+ (_postTransform.HasValue ? value * _postTransform.Value : value).ToDirect2D();
+ }
}
public Matrix4x4 Transform4x4
@@ -353,6 +366,11 @@ namespace Avalonia.Direct2D1.Media
}
}
+ public void DrawRegion(IBrush brush, IPen pen, IPlatformRenderInterfaceRegion region)
+ {
+ throw new NotSupportedException();
+ }
+
///
public void DrawEllipse(IBrush brush, IPen pen, Rect rect)
{
@@ -410,17 +428,17 @@ namespace Avalonia.Direct2D1.Media
}
}
- public IDrawingContextLayerImpl CreateLayer(Size size)
+ public IDrawingContextLayerImpl CreateLayer(PixelSize pixelSize)
{
+ var dpi = new Vector(_deviceContext.DotsPerInch.Width, _deviceContext.DotsPerInch.Height);
if (_layerFactory != null)
{
- return _layerFactory.CreateLayer(size);
+ return _layerFactory.CreateLayer(pixelSize.ToSizeWithDpi(dpi));
}
else
{
var platform = AvaloniaLocator.Current.GetRequiredService();
- var dpi = new Vector(_deviceContext.DotsPerInch.Width, _deviceContext.DotsPerInch.Height);
- var pixelSize = PixelSize.FromSizeWithDpi(size, dpi);
+
return (IDrawingContextLayerImpl)platform.CreateRenderTargetBitmap(pixelSize, dpi);
}
}
@@ -441,14 +459,40 @@ namespace Avalonia.Direct2D1.Media
_deviceContext.PushAxisAlignedClip(clip.Rect.ToDirect2D(), AntialiasMode.PerPrimitive);
}
+ public void PushClip(IPlatformRenderInterfaceRegion region)
+ {
+ throw new NotSupportedException();
+ }
+
public void PopClip()
{
_deviceContext.PopAxisAlignedClip();
}
+ public void PushLayer(Rect bounds)
+ {
+ var parameters = new LayerParameters
+ {
+ ContentBounds = bounds.ToDirect2D(),
+ MaskTransform = PrimitiveExtensions.Matrix3x2Identity,
+ Opacity = 1
+ };
+ var layer = _layerPool.Count != 0 ? _layerPool.Pop() : new Layer(_deviceContext);
+ _deviceContext.PushLayer(ref parameters, layer);
+
+ _layers.Push(layer);
+ }
+
+ void IDrawingContextImpl.PopLayer()
+ {
+ PopLayer();
+ }
+
readonly Stack _layers = new Stack();
private readonly Stack _layerPool = new Stack();
private RenderOptions _renderOptions;
+ private readonly Matrix? _postTransform;
+ private Matrix _transform = Matrix.Identity;
///
/// Pushes an opacity value.
@@ -574,7 +618,7 @@ namespace Avalonia.Direct2D1.Media
CompatibleRenderTargetOptions.None,
pixelSize.ToSizeWithDpi(dpi).ToSharpDX()))
{
- using (var ctx = new RenderTarget(intermediate).CreateDrawingContext())
+ using (var ctx = new RenderTarget(intermediate).CreateDrawingContext(true))
{
intermediate.Clear(null);
sceneBrushContent.Render(ctx,
diff --git a/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs
index fdefe21acd..ef4d91df9d 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs
@@ -98,7 +98,7 @@ namespace Avalonia.Direct2D1.Media
CompatibleRenderTargetOptions.None,
calc.IntermediateSize.ToSharpDX());
- using (var context = new RenderTarget(result).CreateDrawingContext())
+ using (var context = new RenderTarget(result).CreateDrawingContext(true))
{
var dpi = new Vector(target.DotsPerInch.Width, target.DotsPerInch.Height);
var rect = new Rect(bitmap.PixelSize.ToSizeWithDpi(dpi));
diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
index 5d38751bde..6d2d12504b 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
@@ -30,9 +30,10 @@ namespace Avalonia.Direct2D1.Media.Imaging
return new D2DRenderTargetBitmapImpl(bitmapRenderTarget);
}
- public IDrawingContextImpl CreateDrawingContext()
+ public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing)
{
- return new DrawingContextImpl( this, _renderTarget, null, () => Version++);
+ return new DrawingContextImpl( this, _renderTarget, useScaledDrawing,
+ null, () => Version++);
}
public bool IsCorrupted => false;
@@ -60,7 +61,7 @@ namespace Avalonia.Direct2D1.Media.Imaging
{
using (var wic = new WicRenderTargetBitmapImpl(PixelSize, Dpi))
{
- using (var dc = wic.CreateDrawingContext(null))
+ using (var dc = wic.CreateDrawingContext(true, null))
{
dc.DrawBitmap(
this,
diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs
index fa40e75fa7..1120366a8e 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs
@@ -34,14 +34,14 @@ namespace Avalonia.Direct2D1.Media
base.Dispose();
}
- public virtual IDrawingContextImpl CreateDrawingContext()
- => CreateDrawingContext(null);
+ public virtual IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing)
+ => CreateDrawingContext(useScaledDrawing, null);
public bool IsCorrupted => false;
- public IDrawingContextImpl CreateDrawingContext(Action finishedCallback)
+ public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing, Action finishedCallback)
{
- return new DrawingContextImpl(null, _renderTarget, finishedCallback: () =>
+ return new DrawingContextImpl(null, _renderTarget, useScaledDrawing, finishedCallback: () =>
{
Version++;
finishedCallback?.Invoke();
diff --git a/src/Windows/Avalonia.Direct2D1/RenderTarget.cs b/src/Windows/Avalonia.Direct2D1/RenderTarget.cs
index 4392e35058..ecefcd9dad 100644
--- a/src/Windows/Avalonia.Direct2D1/RenderTarget.cs
+++ b/src/Windows/Avalonia.Direct2D1/RenderTarget.cs
@@ -25,9 +25,9 @@ namespace Avalonia.Direct2D1
/// Creates a drawing context for a rendering session.
///
/// An .
- public IDrawingContextImpl CreateDrawingContext()
+ public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing)
{
- return new DrawingContextImpl(this, _renderTarget);
+ return new DrawingContextImpl(this, _renderTarget, useScaledDrawing);
}
public bool IsCorrupted => false;
diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs
index 385120505c..228ae6e460 100644
--- a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs
+++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs
@@ -19,7 +19,7 @@ namespace Avalonia.Direct2D1
/// Creates a drawing context for a rendering session.
///
/// An .
- public IDrawingContextImpl CreateDrawingContext()
+ public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing)
{
var size = GetWindowSize();
var dpi = GetWindowDpi();
@@ -32,7 +32,7 @@ namespace Avalonia.Direct2D1
Resize();
}
- return new DrawingContextImpl(this, _deviceContext, _swapChain);
+ return new DrawingContextImpl(this, _deviceContext, useScaledDrawing, _swapChain);
}
public bool IsCorrupted => false;
diff --git a/tests/Avalonia.RenderTests/Media/BitmapTests.cs b/tests/Avalonia.RenderTests/Media/BitmapTests.cs
index 1b16617f87..6ddeda1b5d 100644
--- a/tests/Avalonia.RenderTests/Media/BitmapTests.cs
+++ b/tests/Avalonia.RenderTests/Media/BitmapTests.cs
@@ -72,7 +72,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media
var r = AvaloniaLocator.Current.GetRequiredService();
using(var cpuContext = r.CreateBackendContext(null))
using (var target = cpuContext.CreateRenderTarget(new object[] { fb }))
- using (var ctx = target.CreateDrawingContext())
+ using (var ctx = target.CreateDrawingContext(false))
{
ctx.Clear(Colors.Transparent);
ctx.PushOpacity(0.8, new Rect(0, 0, 80, 80));
diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs
index f62afaf74d..ae62301d69 100644
--- a/tests/Avalonia.UnitTests/TestRoot.cs
+++ b/tests/Avalonia.UnitTests/TestRoot.cs
@@ -79,16 +79,16 @@ namespace Avalonia.UnitTests
public IRenderTarget CreateRenderTarget()
{
var dc = new Mock();
- dc.Setup(x => x.CreateLayer(It.IsAny())).Returns(() =>
+ dc.Setup(x => x.CreateLayer(It.IsAny())).Returns(() =>
{
var layerDc = new Mock();
var layer = new Mock();
- layer.Setup(x => x.CreateDrawingContext()).Returns(layerDc.Object);
+ layer.Setup(x => x.CreateDrawingContext(It.IsAny())).Returns(layerDc.Object);
return layer.Object;
});
var result = new Mock();
- result.Setup(x => x.CreateDrawingContext()).Returns(dc.Object);
+ result.Setup(x => x.CreateDrawingContext(It.IsAny())).Returns(dc.Object);
return result.Object;
}