Browse Source

Refactored out common rendering code.

Moved platform-independent parts to RendererBase, make platform
renderers derive from this. Breaks GTK text rendering for some reason.
Need to fix.
pull/39/head
Steven Kirk 12 years ago
parent
commit
152e9870a8
  1. 71
      Cairo/Perspex.Cairo/Renderer.cs
  2. 1
      Perspex.SceneGraph/Perspex.SceneGraph.csproj
  3. 99
      Perspex.SceneGraph/Rendering/RendererBase.cs
  4. 72
      Windows/Perspex.Direct2D1/Renderer.cs

71
Cairo/Perspex.Cairo/Renderer.cs

@ -10,13 +10,15 @@ namespace Perspex.Cairo
using System.Runtime.InteropServices;
using global::Cairo;
using Perspex.Cairo.Media;
using Perspex.Media;
using Perspex.Platform;
using Perspex.Rendering;
using Matrix = Perspex.Matrix;
/// <summary>
/// A cairo renderer.
/// </summary>
public class Renderer : IRenderer
public class Renderer : RendererBase
{
/// <summary>
/// Initializes a new instance of the <see cref="Renderer"/> class.
@ -28,49 +30,22 @@ namespace Perspex.Cairo
{
}
/// <summary>
/// Gets the number of times <see cref="Render"/> has been called.
/// </summary>
public int RenderCount
{
get;
private set;
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="handle">A handle to the drawable.</param>
public void Render(IVisual visual, IPlatformHandle handle)
{
using (DrawingContext context = CreateContext(handle))
{
this.Render(visual, context);
}
++this.RenderCount;
}
/// <summary>
/// Resizes the renderer.
/// </summary>
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
public void Resize(int width, int height)
public override void Resize(int width, int height)
{
// Don't need to do anything here.
}
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
/// <summary>
/// Creates a cairo surface that targets a platform-specific resource.
/// </summary>
/// <param name="handle">The platform-specific handle.</param>
/// <returns>A surface.</returns>
private static DrawingContext CreateContext(IPlatformHandle handle)
/// <returns>A surface wrapped in an <see cref="IDrawingContext"/>.</returns>
protected override IDrawingContext CreateDrawingContext(IPlatformHandle handle)
{
switch (handle.HandleDescriptor)
{
@ -87,37 +62,7 @@ namespace Perspex.Cairo
}
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="context">The drawing context.</param>
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 (visual.ClipToBounds ? context.PushClip(visual.Bounds) : null)
using (context.PushTransform(transform))
{
visual.Render(context);
foreach (var child in visual.VisualChildren)
{
this.Render(child, context);
}
}
}
}
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
}
}

1
Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -87,6 +87,7 @@
<Compile Include="Rect.cs" />
<Compile Include="Rendering\IRenderRoot.cs" />
<Compile Include="Rendering\IRenderManager.cs" />
<Compile Include="Rendering\RendererBase.cs" />
<Compile Include="Rendering\RenderManager.cs" />
<Compile Include="Size.cs" />
<Compile Include="Thickness.cs" />

99
Perspex.SceneGraph/Rendering/RendererBase.cs

@ -0,0 +1,99 @@
// -----------------------------------------------------------------------
// <copyright file="RendererBase.cs" company="Steven Kirk">
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Rendering
{
using Perspex.Media;
using Perspex.Platform;
/// <summary>
/// Base class for standard renderers.
/// </summary>
/// <remarks>
/// This class provides implements the platform-independent parts of <see cref="IRenderer"/>.
/// </remarks>
public abstract class RendererBase : IRenderer
{
/// <summary>
/// Gets the number of times <see cref="Render"/> has been called.
/// </summary>
public int RenderCount
{
get;
private set;
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="handle">An optional platform-specific handle.</param>
public virtual void Render(IVisual visual, IPlatformHandle handle)
{
using (var context = this.CreateDrawingContext(handle))
{
this.Render(visual, context, Matrix.Identity, Matrix.Identity);
}
++this.RenderCount;
}
/// <summary>
/// Resizes the rendered viewport.
/// </summary>
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
public abstract void Resize(int width, int height);
/// <summary>
/// When overriden by a derived class creates an <see cref="IDrawingContext"/> for a
/// rendering session.
/// </summary>
/// <param name="handle">The handle to use to create the context.</param>
/// <returns>An <see cref="IDrawingContext"/>.</returns>
protected abstract IDrawingContext CreateDrawingContext(IPlatformHandle handle);
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="context">The drawing context.</param>
protected virtual void Render(IVisual visual, IDrawingContext context, Matrix translation, Matrix transform)
{
if (visual.IsVisible && visual.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 (visual.ClipToBounds ? context.PushClip(visual.Bounds) : null)
{
visual.Render(context);
d.Dispose();
foreach (var child in visual.VisualChildren)
{
this.Render(child, context, translation, transform);
}
}
}
}
}
}

72
Windows/Perspex.Direct2D1/Renderer.cs

@ -7,18 +7,16 @@
namespace Perspex.Direct2D1
{
using System;
using System.Linq;
using Perspex.Direct2D1.Media;
using Perspex.Media;
using Perspex.Platform;
using Perspex.Rendering;
using SharpDX;
using SharpDX.Direct2D1;
using Splat;
using DwFactory = SharpDX.DirectWrite.Factory;
using Matrix = Perspex.Matrix;
using Point = Perspex.Point;
public class Renderer : IRenderer
public class Renderer : RendererBase
{
/// <summary>
/// The render target.
@ -82,36 +80,12 @@ namespace Perspex.Direct2D1
private set;
}
/// <summary>
/// Gets the number of times <see cref="Render"/> has been called.
/// </summary>
public int RenderCount
{
get;
private set;
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="handle">Unused.</param>
public void Render(IVisual visual, IPlatformHandle handle)
{
using (DrawingContext context = new DrawingContext(this.renderTarget, this.DirectWriteFactory))
{
this.Render(visual, context, Matrix.Identity, Matrix.Identity);
}
++this.RenderCount;
}
/// <summary>
/// Resizes the renderer.
/// </summary>
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
public void Resize(int width, int height)
public override void Resize(int width, int height)
{
WindowRenderTarget window = this.renderTarget as WindowRenderTarget;
@ -126,43 +100,13 @@ namespace Perspex.Direct2D1
}
/// <summary>
/// Renders the specified visual.
/// Creates a drawing context for a rendering session.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="context">The drawing context.</param>
private void Render(IVisual visual, DrawingContext context, Matrix translation, Matrix transform)
/// <param name="handle">The platform handle. Unused.</param>
/// <returns>An <see cref="IDrawingContext"/>.</returns>
protected override IDrawingContext CreateDrawingContext(IPlatformHandle handle)
{
if (visual.IsVisible && visual.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 (visual.ClipToBounds ? context.PushClip(visual.Bounds) : null)
{
visual.Render(context);
d.Dispose();
foreach (var child in visual.VisualChildren)
{
this.Render(child, context, translation, transform);
}
}
}
return new DrawingContext(this.renderTarget, this.DirectWriteFactory);
}
}
}

Loading…
Cancel
Save