// -----------------------------------------------------------------------
//
// 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);
}
}
}
}
}
}