// -----------------------------------------------------------------------
//
// Copyright 2013 MIT Licence. See licence.md for more information.
//
// -----------------------------------------------------------------------
namespace Perspex.Windows
{
using System;
using System.Reactive.Disposables;
using Perspex.Media;
using Perspex.Windows.Media;
using SharpDX;
using SharpDX.Direct2D1;
using Matrix = Perspex.Media.Matrix;
///
/// Draws using Direct2D1.
///
public class DrawingContext : IDrawingContext, IDisposable
{
///
/// The Direct2D1 render target.
///
private RenderTarget renderTarget;
///
/// The DirectWrite factory.
///
private SharpDX.DirectWrite.Factory directWriteFactory;
///
/// Initializes a new instance of the class.
///
/// The render target to draw to.
/// The DirectWrite factory.
public DrawingContext(
RenderTarget renderTarget,
SharpDX.DirectWrite.Factory directWriteFactory)
{
this.renderTarget = renderTarget;
this.directWriteFactory = directWriteFactory;
this.renderTarget.BeginDraw();
}
///
/// Ends a draw operation.
///
public void Dispose()
{
this.renderTarget.EndDraw();
}
///
/// Draws the outline of a rectangle.
///
/// The pen.
/// The rectangle bounds.
public void DrawRectange(Pen pen, Rect rect)
{
using (SharpDX.Direct2D1.SolidColorBrush brush = this.Convert(pen.Brush))
{
this.renderTarget.DrawRectangle(
this.Convert(rect),
brush,
(float)pen.Thickness);
}
}
///
/// Draws text.
///
/// The foreground brush.
/// The text.
public void DrawText(Perspex.Media.Brush foreground, Rect rect, FormattedText text)
{
using (SharpDX.Direct2D1.SolidColorBrush brush = this.Convert(foreground))
using (SharpDX.DirectWrite.TextFormat format = TextService.Convert(this.directWriteFactory, text))
{
this.renderTarget.DrawText(
text.Text,
format,
this.Convert(rect),
brush);
}
}
///
/// Draws a filled rectangle.
///
/// The brush.
/// The rectangle bounds.
public void FillRectange(Perspex.Media.Brush brush, Rect rect)
{
using (SharpDX.Direct2D1.SolidColorBrush b = this.Convert(brush))
{
this.renderTarget.FillRectangle(
new RectangleF(
(float)rect.X,
(float)rect.Y,
(float)rect.Width,
(float)rect.Height),
b);
}
}
///
/// Pushes a matrix transformation.
///
/// The matrix
/// A disposable used to undo the transformation.
public IDisposable PushTransform(Matrix matrix)
{
Matrix3x2 m3x2 = this.Convert(matrix);
Matrix3x2 transform = this.renderTarget.Transform * m3x2;
this.renderTarget.Transform = transform;
return Disposable.Create(() =>
{
m3x2.Invert();
this.renderTarget.Transform = transform * m3x2;
});
}
///
/// Converts a brush to Direct2D.
///
/// The brush to convert.
/// The Direct2D brush.
private SharpDX.Direct2D1.SolidColorBrush Convert(Perspex.Media.Brush brush)
{
Perspex.Media.SolidColorBrush solidColorBrush = brush as Perspex.Media.SolidColorBrush;
if (solidColorBrush != null)
{
return new SharpDX.Direct2D1.SolidColorBrush(
this.renderTarget,
this.Convert(solidColorBrush.Color));
}
else
{
return new SharpDX.Direct2D1.SolidColorBrush(
this.renderTarget,
new Color4());
}
}
///
/// Converts a color to Direct2D.
///
/// The color to convert.
/// The Direct2D color.
private Color4 Convert(Perspex.Media.Color color)
{
return new Color4(
(float)(color.R / 255.0),
(float)(color.G / 255.0),
(float)(color.B / 255.0),
(float)(color.A / 255.0));
}
///
/// Converts a to a Direct2D
///
/// The .
/// The .
private Matrix3x2 Convert(Matrix matrix)
{
return new Matrix3x2(
(float)matrix.M11,
(float)matrix.M12,
(float)matrix.M21,
(float)matrix.M22,
(float)matrix.OffsetX,
(float)matrix.OffsetY);
}
///
/// Converts a to a
///
/// The .
/// The .
private RectangleF Convert(Rect rect)
{
return new RectangleF(
(float)rect.X,
(float)rect.Y,
(float)rect.Width,
(float)rect.Height);
}
}
}