// ----------------------------------------------------------------------- // // Copyright 2015 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Rendering { using System.Linq; using Perspex.Media; using Perspex.Platform; /// /// Base class for standard renderers. /// /// /// This class provides implements the platform-independent parts of . /// public abstract class RendererBase : IRenderer { /// /// Gets the number of times has been called. /// public int RenderCount { get; private set; } /// /// Renders the specified visual. /// /// The visual to render. /// An optional platform-specific handle. public virtual void Render(IVisual visual, IPlatformHandle handle) { using (var context = this.CreateDrawingContext(handle)) { this.Render(visual, context, Matrix.Identity, Matrix.Identity); } ++this.RenderCount; } /// /// Resizes the rendered viewport. /// /// The new width. /// The new height. public abstract void Resize(int width, int height); /// /// When overriden by a derived class creates an for a /// rendering session. /// /// The handle to use to create the context. /// An . protected abstract IDrawingContext CreateDrawingContext(IPlatformHandle handle); /// /// Renders the specified visual. /// /// The visual to render. /// The drawing context. protected virtual void Render(IVisual visual, IDrawingContext context, Matrix translation, Matrix transform) { var opacity = visual.Opacity; if (visual.IsVisible && opacity > 0) { // Translate any existing transform into this controls coordinate system. Matrix offset = Matrix.Translation(visual.Bounds.Position); transform = offset * transform * -offset; // Update the current offset. translation *= Matrix.Translation(visual.Bounds.Position); // Apply the control's render transform, if any. if (visual.RenderTransform != null) { offset = Matrix.Translation(visual.TransformOrigin.ToPixels(visual.Bounds.Size)); transform *= -offset * visual.RenderTransform.Value * offset; } // Draw the control and its children. var m = transform * translation; var d = context.PushTransform(m); using (context.PushOpacity(opacity)) using (visual.ClipToBounds ? context.PushClip(visual.Bounds) : null) { visual.Render(context); d.Dispose(); foreach (var child in visual.VisualChildren.OrderBy(x => x.ZIndex)) { this.Render(child, context, translation, transform); } } } } } }