// ----------------------------------------------------------------------- // // Copyright 2013 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Direct2D1 { using System; using System.Linq; using Perspex.Direct2D1.Media; using Perspex.Media; using Perspex.Platform; using SharpDX; using SharpDX.Direct2D1; using Splat; using DwFactory = SharpDX.DirectWrite.Factory; using Matrix = Perspex.Matrix; using Point = Perspex.Point; public class Renderer : IRenderer { /// /// The render target. /// private RenderTarget renderTarget; /// /// Initializes a new instance of the class. /// /// The window handle. /// The width of the window. /// The height of the window. public Renderer(IntPtr hwnd, double width, double height) { this.Direct2DFactory = Locator.Current.GetService(); this.DirectWriteFactory = Locator.Current.GetService(); RenderTargetProperties renderTargetProperties = new RenderTargetProperties { }; HwndRenderTargetProperties hwndProperties = new HwndRenderTargetProperties { Hwnd = hwnd, PixelSize = new Size2((int)width, (int)height), }; this.renderTarget = new WindowRenderTarget( this.Direct2DFactory, renderTargetProperties, hwndProperties); } /// /// Initializes a new instance of the class. /// /// The render target. public Renderer(RenderTarget renderTarget) { this.Direct2DFactory = Locator.Current.GetService(); this.DirectWriteFactory = Locator.Current.GetService(); this.renderTarget = renderTarget; } /// /// Gets the Direct2D factory. /// public Factory Direct2DFactory { get; private set; } /// /// Gets the DirectWrite factory. /// public DwFactory DirectWriteFactory { get; private set; } /// /// Renders the specified visual. /// /// The visual to render. /// Unused. public void Render(IVisual visual, IPlatformHandle handle) { using (DrawingContext context = new DrawingContext(this.renderTarget, this.DirectWriteFactory)) { this.Render(visual, context); } } /// /// Resizes the renderer. /// /// The new width. /// The new height. public void Resize(int width, int height) { WindowRenderTarget window = this.renderTarget as WindowRenderTarget; if (window == null) { throw new InvalidOperationException(string.Format( "A renderer with a target of type '{0}' cannot be resized.", this.renderTarget.GetType().Name)); } window.Resize(new Size2(width, height)); } /// /// Renders the specified visual. /// /// The visual to render. /// The drawing context. private void Render(IVisual visual, DrawingContext context) { if (visual.IsVisible && visual.Opacity > 0) { Matrix transform = Matrix.Identity; if (visual.RenderTransform != null) { Matrix current = context.CurrentTransform; Matrix offset = Matrix.Translation(visual.TransformOrigin.ToPixels(visual.Bounds.Size)); transform = -current * -offset * visual.RenderTransform.Value * offset * current; } transform *= Matrix.Translation(visual.Bounds.Position); using (context.PushClip(visual.Bounds)) using (context.PushTransform(transform)) { visual.Render(context); foreach (var child in visual.VisualChildren) { this.Render(child, context); } } } } } }