diff --git a/src/Avalonia.Visuals/Rendering/Renderer.cs b/src/Avalonia.Visuals/Rendering/Renderer.cs index 36b0ad1846..12ed088bbc 100644 --- a/src/Avalonia.Visuals/Rendering/Renderer.cs +++ b/src/Avalonia.Visuals/Rendering/Renderer.cs @@ -5,6 +5,7 @@ using System; using Avalonia.Platform; using Avalonia.VisualTree; using System.Collections.Generic; +using Avalonia.Threading; namespace Avalonia.Rendering { @@ -14,6 +15,7 @@ namespace Avalonia.Rendering private readonly IRenderRoot _root; private IRenderTarget _renderTarget; private bool _dirty; + private bool _renderQueued; public Renderer(IRenderRoot root, IRenderLoop renderLoop) { @@ -39,7 +41,7 @@ namespace Avalonia.Rendering public IEnumerable HitTest(Point p, Func filter) { - throw new NotImplementedException(); + return HitTest(_root, p, filter); } public void Render(Rect rect) @@ -63,14 +65,45 @@ namespace Avalonia.Rendering finally { _dirty = false; + _renderQueued = false; + } + } + + static IEnumerable HitTest( + IVisual visual, + Point p, + Func filter) + { + Contract.Requires(visual != null); + + if (filter?.Invoke(visual) != false) + { + bool containsPoint = BoundsTracker.GetTransformedBounds((Visual)visual)?.Contains(p) == true; + + if ((containsPoint || !visual.ClipToBounds) && visual.VisualChildren.Count > 0) + { + foreach (var child in visual.VisualChildren.SortByZIndex()) + { + foreach (var result in HitTest(child, p, filter)) + { + yield return result; + } + } + } + + if (containsPoint) + { + yield return visual; + } } } private void OnRenderLoopTick(object sender, EventArgs e) { - if (_dirty) + if (_dirty && !_renderQueued) { - _root.Invalidate(new Rect(_root.ClientSize)); + _renderQueued = true; + Dispatcher.UIThread.InvokeAsync(() => Render(new Rect(_root.ClientSize))); } } } diff --git a/src/Avalonia.Visuals/Rendering/RendererMixin.cs b/src/Avalonia.Visuals/Rendering/RendererMixin.cs index 3a24e1a22f..c922eb50e1 100644 --- a/src/Avalonia.Visuals/Rendering/RendererMixin.cs +++ b/src/Avalonia.Visuals/Rendering/RendererMixin.cs @@ -42,34 +42,35 @@ namespace Avalonia.Rendering /// The visual to render. public static void Render(this IRenderTarget renderTarget, IVisual visual) { - ////using (var ctx = renderTarget.CreateDrawingContext()) - ////{ - //// ctx.Render(visual); - //// s_frameNum++; - //// if (DrawFpsCounter) - //// { - //// s_currentFrames++; - //// var now = s_stopwatch.Elapsed; - //// var elapsed = now - s_lastMeasure; - //// if (elapsed.TotalSeconds > 1) - //// { - //// s_fps = (int) (s_currentFrames/elapsed.TotalSeconds); - //// s_currentFrames = 0; - //// s_lastMeasure = now; - //// } - //// var pt = new Point(40, 40); - //// using ( - //// var txt = new FormattedText("Frame #" + s_frameNum + " FPS: " + s_fps, "Arial", 18, - //// FontStyle.Normal, - //// TextAlignment.Left, - //// FontWeight.Normal, - //// TextWrapping.NoWrap)) - //// { - //// ctx.FillRectangle(Brushes.White, new Rect(pt, txt.Measure())); - //// ctx.DrawText(Brushes.Black, pt, txt); - //// } - //// } - ////} + using (var ctx = new DrawingContext(renderTarget.CreateDrawingContext())) + { + ctx.Render(visual); + s_frameNum++; + if (DrawFpsCounter) + { + s_currentFrames++; + var now = s_stopwatch.Elapsed; + var elapsed = now - s_lastMeasure; + if (elapsed.TotalSeconds > 1) + { + s_fps = (int)(s_currentFrames / elapsed.TotalSeconds); + s_currentFrames = 0; + s_lastMeasure = now; + } + var pt = new Point(40, 40); + var txt = new FormattedText( + "Frame #" + s_frameNum + " FPS: " + s_fps, + "Arial", + 18, + Size.Infinity, + FontStyle.Normal, + TextAlignment.Left, + FontWeight.Normal, + TextWrapping.NoWrap); + ctx.FillRectangle(Brushes.White, new Rect(pt, txt.Measure())); + ctx.DrawText(Brushes.Black, pt, txt); + } + } } /// diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 39aa3bac1b..0e60886c4c 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -76,7 +76,7 @@ namespace Avalonia.Direct2D1 public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop) { - return new DeferredRenderer(root, renderLoop); + return new Renderer(root, renderLoop); } public IRenderTarget CreateRenderTarget(IPlatformHandle handle) diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index ec33f3e2e1..604022d1ec 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -28,7 +28,7 @@ namespace Avalonia.Direct2D1.Media fontFamily, fontSize, (DWrite.FontStyle)fontStyle, - (DWrite.TextAlignment)textAlignment, + textAlignment.ToDirect2D(), (DWrite.FontWeight)fontWeight, wrapping == TextWrapping.Wrap ? DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap, (float)constraint.Width, diff --git a/tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.v2.ncrunchproject b/tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.v2.ncrunchproject index 0c8a7ff2ac..6e89ef281e 100644 --- a/tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.v2.ncrunchproject +++ b/tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.v2.ncrunchproject @@ -23,8 +23,5 @@ AutoDetect STA x86 - - - AbnormalReferenceResolution \ No newline at end of file diff --git a/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v2.ncrunchproject b/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v2.ncrunchproject index 3f48b966ba..1f00ab7c74 100644 --- a/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v2.ncrunchproject +++ b/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v2.ncrunchproject @@ -23,7 +23,4 @@ AutoDetect STA x86 - - - \ No newline at end of file