// ----------------------------------------------------------------------- // // Copyright 2013 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Direct2D1 { using System; using System.Linq; using Perspex.Direct2D1.Media; using Perspex.Platform; using SharpDX; using SharpDX.Direct2D1; using Splat; using DwFactory = SharpDX.DirectWrite.Factory; using Matrix = Perspex.Media.Matrix; /// /// Renders a . /// 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. public void Render(IVisual visual) { 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) { if (visual.Opacity < 1) { Layer layer = new Layer(this.renderTarget); LayerParameters p = new LayerParameters(); p.Opacity = (float)visual.Opacity; this.renderTarget.PushLayer(ref p, layer); } visual.Render(context); foreach (IVisual child in visual.VisualChildren) { Matrix translate = Matrix.Translation(child.Bounds.X, child.Bounds.Y); using (context.PushTransform(translate)) { this.Render(child, context); } } if (visual.Opacity < 1) { this.renderTarget.PopLayer(); } } } } }