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