Browse Source

Documentation.

pull/81/head
Steven Kirk 11 years ago
parent
commit
f2170e3ad5
  1. 4
      Perspex.Controls/Shapes/Shape.cs
  2. 2
      Perspex.Input/AccessKeyHandler.cs
  3. 258
      Perspex.SceneGraph/Matrix.cs
  4. 14
      Perspex.SceneGraph/Media/FontStyle.cs
  5. 70
      Perspex.SceneGraph/Media/FontWeight.cs
  6. 83
      Perspex.SceneGraph/Media/FormattedText.cs
  7. 20
      Perspex.SceneGraph/Media/FormattedTextLine.cs
  8. 29
      Perspex.SceneGraph/Media/Imaging/Bitmap.cs
  9. 18
      Perspex.SceneGraph/Media/Imaging/IBitmap.cs
  10. 29
      Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs
  11. 21
      Perspex.SceneGraph/Media/MatrixTransform.cs
  12. 15
      Perspex.SceneGraph/Media/PathMarkupParser.cs
  13. 23
      Perspex.SceneGraph/Media/RotateTransform.cs
  14. 4
      Perspex.SceneGraph/Media/SolidColorBrush.cs
  15. 22
      Perspex.SceneGraph/Media/Stretch.cs
  16. 12
      Perspex.SceneGraph/Media/SweepDirection.cs
  17. 16
      Perspex.SceneGraph/Media/TextAlignment.cs
  18. 14
      Perspex.SceneGraph/Media/TextHitTestResult.cs
  19. 12
      Perspex.SceneGraph/Media/Transform.cs
  20. 28
      Perspex.SceneGraph/Media/TranslateTransform.cs
  21. 41
      Perspex.SceneGraph/Origin.cs
  22. 2
      Perspex.SceneGraph/Perspex.SceneGraph.csproj
  23. 13
      Perspex.SceneGraph/Platform/IBitmapImpl.cs
  24. 46
      Perspex.SceneGraph/Platform/IFormattedTextImpl.cs
  25. 16
      Perspex.SceneGraph/Platform/IGeometryImpl.cs
  26. 45
      Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs
  27. 13
      Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs
  28. 13
      Perspex.SceneGraph/Platform/IRenderer.cs
  29. 15
      Perspex.SceneGraph/Platform/IStreamGeometryImpl.cs
  30. 4
      Perspex.SceneGraph/Point.cs
  31. 39
      Perspex.SceneGraph/Rect.cs
  32. 15
      Perspex.SceneGraph/Rendering/IRenderManager.cs
  33. 16
      Perspex.SceneGraph/Rendering/IRenderRoot.cs
  34. 16
      Perspex.SceneGraph/Rendering/RenderManager.cs
  35. 6
      Perspex.SceneGraph/Rendering/RendererBase.cs
  36. 2
      Perspex.SceneGraph/Size.cs
  37. 18
      Perspex.SceneGraph/Thickness.cs
  38. 2
      Perspex.SceneGraph/Visual.cs
  39. 71
      Perspex.SceneGraph/VisualTree/VisualExtensions.cs
  40. 9
      Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs
  41. 4
      Windows/Perspex.Direct2D1/PrimitiveExtensions.cs

4
Perspex.Controls/Shapes/Shape.cs

@ -121,7 +121,7 @@ namespace Perspex.Controls.Shapes
if (this.Stretch != Stretch.None)
{
shapeSize = shapeBounds.Size;
translate = Matrix.Translation(-(Vector)shapeBounds.Position);
translate = Matrix.CreateTranslation(-(Vector)shapeBounds.Position);
}
if (double.IsInfinity(availableSize.Width))
@ -179,7 +179,7 @@ namespace Perspex.Controls.Shapes
break;
}
var t = translate * Matrix.Scaling(sx, sy);
var t = translate * Matrix.CreateScale(sx, sy);
if (this.transform != t)
{

2
Perspex.Input/AccessKeyHandler.cs

@ -158,7 +158,7 @@ namespace Perspex.Input
// If the menu is open, only match controls in the menu's visual tree.
if (menuIsOpen)
{
matches = matches.Where(x => this.MainMenu.IsVisualParentOf(x));
matches = matches.Where(x => this.MainMenu.IsVisualAncestorOf(x));
}
var match = matches.FirstOrDefault();

258
Perspex.SceneGraph/Matrix.cs

@ -1,4 +1,4 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// <copyright file="Matrix.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
@ -7,16 +7,29 @@
namespace Perspex
{
using System;
using System.Globalization;
/// <summary>
/// A 2x3 matrix.
/// </summary>
public struct Matrix
{
private double m11;
private double m12;
private double m21;
private double m22;
private double offsetX;
private double offsetY;
private double m31;
private double m32;
/// <summary>
/// Initializes a new instance of the <see cref="Matrix"/> struct.
/// </summary>
/// <param name="m11">The first element of the first row.</param>
/// <param name="m12">The second element of the first row.</param>
/// <param name="m21">The first element of the second row.</param>
/// <param name="m22">The second element of the second row.</param>
/// <param name="offsetX">The first element of the third row.</param>
/// <param name="offsetY">The second element of the third row.</param>
public Matrix(
double m11,
double m12,
@ -29,176 +42,279 @@ namespace Perspex
this.m12 = m12;
this.m21 = m21;
this.m22 = m22;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.m31 = offsetX;
this.m32 = offsetY;
}
/// <summary>
/// Returns the multiplicative identity matrix.
/// </summary>
public static Matrix Identity
{
get { return new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); }
}
public double Determinant
{
get { return (this.m11 * this.m22) - (this.m12 * this.m21); }
}
public bool HasInverse
{
get { return this.Determinant != 0; }
}
/// <summary>
/// Returns whether the matrix is the identity matrix.
/// </summary>
public bool IsIdentity
{
get { return this.Equals(Matrix.Identity); }
}
/// <summary>
/// The first element of the first row
/// </summary>
public double M11
{
get { return this.m11; }
}
/// <summary>
/// The second element of the first row
/// </summary>
public double M12
{
get { return this.m12; }
}
/// <summary>
/// The first element of the second row
/// </summary>
public double M21
{
get { return this.m21; }
}
/// <summary>
/// The second element of the second row
/// </summary>
public double M22
{
get { return this.m22; }
}
public double OffsetX
/// <summary>
/// The first element of the third row
/// </summary>
public double M31
{
get { return this.offsetX; }
get { return this.m31; }
}
public double OffsetY
/// <summary>
/// The second element of the third row
/// </summary>
public double M32
{
get { return this.offsetY; }
get { return this.m32; }
}
public static Matrix operator *(Matrix left, Matrix right)
/// <summary>
/// Multiplies two matrices together and returns the resulting matrix.
/// </summary>
/// <param name="value1">The first source matrix.</param>
/// <param name="value2">The second source matrix.</param>
/// <returns>The product matrix.</returns>
public static Matrix operator *(Matrix value1, Matrix value2)
{
return new Matrix(
(left.M11 * right.M11) + (left.M12 * right.M21),
(left.M11 * right.M12) + (left.M12 * right.M22),
(left.M21 * right.M11) + (left.M22 * right.M21),
(left.M21 * right.M12) + (left.M22 * right.M22),
(left.offsetX * right.M11) + (left.offsetY * right.M21) + right.offsetX,
(left.offsetX * right.M12) + (left.offsetY * right.M22) + right.offsetY);
}
public static Matrix operator -(Matrix matrix)
{
return matrix.Invert();
(value1.M11 * value2.M11) + (value1.M12 * value2.M21),
(value1.M11 * value2.M12) + (value1.M12 * value2.M22),
(value1.M21 * value2.M11) + (value1.M22 * value2.M21),
(value1.M21 * value2.M12) + (value1.M22 * value2.M22),
(value1.m31 * value2.M11) + (value1.m32 * value2.M21) + value2.m31,
(value1.m31 * value2.M12) + (value1.m32 * value2.M22) + value2.m32);
}
public static bool operator ==(Matrix matrix1, Matrix matrix2)
/// <summary>
/// Negates the given matrix by multiplying all values by -1.
/// </summary>
/// <param name="value">The source matrix.</param>
/// <returns>The negated matrix.</returns>
public static Matrix operator -(Matrix value)
{
return matrix1.Equals(matrix2);
return value.Invert();
}
public static bool operator !=(Matrix matrix1, Matrix matrix2)
/// <summary>
/// Returns a boolean indicating whether the given matrices are equal.
/// </summary>
/// <param name="value1">The first source matrix.</param>
/// <param name="value2">The second source matrix.</param>
/// <returns>True if the matrices are equal; False otherwise.</returns>
public static bool operator ==(Matrix value1, Matrix value2)
{
return !matrix1.Equals(matrix2);
return value1.Equals(value2);
}
public static bool Equals(Matrix matrix1, Matrix matrix2)
/// <summary>
/// Returns a boolean indicating whether the given matrices are not equal.
/// </summary>
/// <param name="value1">The first source matrix.</param>
/// <param name="value2">The second source matrix.</param>
/// <returns>True if the matrices are not equal; False if they are equal.</returns>
public static bool operator !=(Matrix value1, Matrix value2)
{
return matrix1.Equals(matrix2);
return !value1.Equals(value2);
}
public static Matrix Rotation(double angle)
/// <summary>
/// Creates a rotation matrix using the given rotation in radians.
/// </summary>
/// <param name="radians">The amount of rotation, in radians.</param>
/// <returns>A rotation matrix.</returns>
public static Matrix CreateRotation(double radians)
{
double cos = Math.Cos(angle);
double sin = Math.Sin(angle);
double cos = Math.Cos(radians);
double sin = Math.Sin(radians);
return new Matrix(cos, sin, -sin, cos, 0, 0);
}
public static Matrix Scaling(double x, double y)
/// <summary>
/// Creates a scale matrix from the given X and Y components.
/// </summary>
/// <param name="xScale">Value to scale by on the X-axis.</param>
/// <param name="yScale">Value to scale by on the Y-axis.</param>
/// <returns>A scaling matrix.</returns>
public static Matrix CreateScale(double xScale, double yScale)
{
return Scaling(new Vector(x, y));
return CreateScale(new Vector(xScale, yScale));
}
public static Matrix Scaling(Vector scale)
/// <summary>
/// Creates a scale matrix from the given vector scale.
/// </summary>
/// <param name="scales">The scale to use.</param>
/// <returns>A scaling matrix.</returns>
public static Matrix CreateScale(Vector scales)
{
return new Matrix(scale.X, 0, 0, scale.Y, 0, 0);
return new Matrix(scales.X, 0, 0, scales.Y, 0, 0);
}
public static Matrix Translation(Vector v)
/// <summary>
/// Creates a translation matrix from the given vector.
/// </summary>
/// <param name="position">The translation position.</param>
/// <returns>A translation matrix.</returns>
public static Matrix CreateTranslation(Vector position)
{
return Translation(v.X, v.Y);
return CreateTranslation(position.X, position.Y);
}
public static Matrix Translation(double x, double y)
/// <summary>
/// Creates a translation matrix from the given X and Y components.
/// </summary>
/// <param name="xPosition">The X position.</param>
/// <param name="yPosition">The Y position.</param>
/// <returns>A translation matrix.</returns>
public static Matrix CreateTranslation(double xPosition, double yPosition)
{
return new Matrix(1.0, 0.0, 0.0, 1.0, x, y);
return new Matrix(1.0, 0.0, 0.0, 1.0, xPosition, yPosition);
}
/// <summary>
/// Converts an ange in degrees to radians.
/// </summary>
/// <param name="angle">The angle in degrees.</param>
/// <returns>The angle in radians.</returns>
public static double ToRadians(double angle)
{
return angle * 0.0174532925;
}
public bool Equals(Matrix value)
/// <summary>
/// Calculates the determinant for this matrix.
/// </summary>
/// <returns>The determinant.</returns>
/// <remarks>
/// The determinant is calculated by expanding the matrix with a third column whose
/// values are (0,0,1).
/// </remarks>
public double GetDeterminant()
{
return (this.m11 * this.m22) - (this.m12 * this.m21);
}
/// <summary>
/// Returns a boolean indicating whether the matrix is equal to the other given matrix.
/// </summary>
/// <param name="other">The other matrix to test equality against.</param>
/// <returns>True if this matrix is equal to other; False otherwise.</returns>
public bool Equals(Matrix other)
{
return this.m11 == value.M11 &&
this.m12 == value.M12 &&
this.m21 == value.M21 &&
this.m22 == value.M22 &&
this.offsetX == value.OffsetX &&
this.offsetY == value.OffsetY;
return this.m11 == other.M11 &&
this.m12 == other.M12 &&
this.m21 == other.M21 &&
this.m22 == other.M22 &&
this.m31 == other.M31 &&
this.m32 == other.M32;
}
public override bool Equals(object o)
/// <summary>
/// Returns a boolean indicating whether the given Object is equal to this matrix instance.
/// </summary>
/// <param name="obj">The Object to compare against.</param>
/// <returns>True if the Object is equal to this matrix; False otherwise.</returns>
public override bool Equals(object obj)
{
if (!(o is Matrix))
if (!(obj is Matrix))
{
return false;
}
return this.Equals((Matrix)o);
return this.Equals((Matrix)obj);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode()
{
throw new NotImplementedException();
return this.M11.GetHashCode() + this.M12.GetHashCode() +
this.M21.GetHashCode() + this.M22.GetHashCode() +
this.M31.GetHashCode() + this.M32.GetHashCode();
}
/// <summary>
/// Returns a String representing this matrix instance.
/// </summary>
/// <returns>The string representation.</returns>
public override string ToString()
{
CultureInfo ci = CultureInfo.CurrentCulture;
return string.Format(
"{0},{1} {2},{3} {4},{5}",
this.m11,
this.m12,
this.m21,
this.m22,
this.offsetX,
this.offsetY);
ci,
"{{ {{M11:{0} M12:{1}}} {{M21:{2} M22:{3}}} {{M31:{4} M32:{5}}} }}",
this.M11.ToString(ci),
this.M12.ToString(ci),
this.M21.ToString(ci),
this.M22.ToString(ci),
this.M31.ToString(ci),
this.M32.ToString(ci));
}
/// <summary>
/// Inverts the Matrix.
/// </summary>
/// <returns>The inverted matrix.</returns>
public Matrix Invert()
{
if (!this.HasInverse)
if (this.GetDeterminant() == 0)
{
throw new InvalidOperationException("Transform is not invertible.");
}
double d = this.Determinant;
double d = this.GetDeterminant();
return new Matrix(
this.m22 / d,
-this.m12 / d,
-this.m21 / d,
this.m11 / d,
((this.m21 * this.offsetY) - (this.m22 * this.offsetX)) / d,
((this.m12 * this.offsetX) - (this.m11 * this.offsetY)) / d);
((this.m21 * this.m32) - (this.m22 * this.m31)) / d,
((this.m12 * this.m31) - (this.m11 * this.m32)) / d);
}
}
}

14
Perspex.SceneGraph/Media/FontStyle.cs

@ -6,10 +6,24 @@
namespace Perspex.Media
{
/// <summary>
/// Defines the available font styles.
/// </summary>
public enum FontStyle
{
/// <summary>
/// A normal font.
/// </summary>
Normal,
/// <summary>
/// An oblique font.
/// </summary>
Oblique,
/// <summary>
/// An italic font.
/// </summary>
Italic,
}
}

70
Perspex.SceneGraph/Media/FontWeight.cs

@ -6,23 +6,93 @@
namespace Perspex.Media
{
/// <summary>
/// Defines a set of predefined font weights.
/// </summary>
/// <remarks>
/// As well as the values defined by this enumeration you can also pass any integer value by
/// casting it to <see cref="FontWeight"/>, e.g. <code>(FontWeight)550</code>.
/// </remarks>
public enum FontWeight
{
/// <summary>
/// Specifies a "thin" font weight.
/// </summary>
Thin = 100,
/// <summary>
/// Specifies an "extra light" font weight.
/// </summary>
ExtraLight = 200,
/// <summary>
/// Specifies an "ultra light" font weight.
/// </summary>
UltraLight = 200,
/// <summary>
/// Specifies a "light" font weight.
/// </summary>
Light = 300,
/// <summary>
/// Specifies a "normal" font weight.
/// </summary>
Normal = 400,
/// <summary>
/// Specifies a "regular" font weight.
/// </summary>
Regular = 400,
/// <summary>
/// Specifies a "medium" font weight.
/// </summary>
Medium = 500,
/// <summary>
/// Specifies a "demi-bold" font weight.
/// </summary>
DemiBold = 600,
/// <summary>
/// Specifies a "semi-bold" font weight.
/// </summary>
SemiBold = 600,
/// <summary>
/// Specifies a "bold" font weight.
/// </summary>
Bold = 700,
/// <summary>
/// Specifies an "extra bold" font weight.
/// </summary>
ExtraBold = 800,
/// <summary>
/// Specifies an "ultra bold" font weight.
/// </summary>
UltraBold = 800,
/// <summary>
/// Specifies a "black" font weight.
/// </summary>
Black = 900,
/// <summary>
/// Specifies a "heavy" font weight.
/// </summary>
Heavy = 900,
/// <summary>
/// Specifies an "extra black" font weight.
/// </summary>
ExtraBlack = 950,
/// <summary>
/// Specifies an "ultra black" font weight.
/// </summary>
UltraBlack = 950
}
}

83
Perspex.SceneGraph/Media/FormattedText.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="FormattedText.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -11,8 +11,20 @@ namespace Perspex.Media
using Perspex.Platform;
using Splat;
/// <summary>
/// Represents a piece of text with formatting.
/// </summary>
public class FormattedText : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="FormattedText"/> class.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="fontFamilyName">The font family.</param>
/// <param name="fontSize">The font size.</param>
/// <param name="fontStyle">The font style.</param>
/// <param name="textAlignment">The text alignment.</param>
/// <param name="fontWeight">The font weight.</param>
public FormattedText(
string text,
string fontFamilyName,
@ -39,87 +51,148 @@ namespace Perspex.Media
fontWeight);
}
/// <summary>
/// Gets or sets the constraint of the text.
/// </summary>
public Size Constraint
{
get { return this.PlatformImpl.Constraint; }
set { this.PlatformImpl.Constraint = value; }
}
/// <summary>
/// Gets the font family.
/// </summary>
public string FontFamilyName
{
get;
private set;
}
/// <summary>
/// Gets the font size.
/// </summary>
public double FontSize
{
get;
private set;
}
/// <summary>
/// Gets the font style.
/// </summary>
public FontStyle FontStyle
{
get;
private set;
}
/// <summary>
/// Gets the font weight.
/// </summary>
public FontWeight FontWeight
{
get;
private set;
}
/// <summary>
/// Gets the text.
/// </summary>
public string Text
{
get;
private set;
}
/// <summary>
/// Gets platform-specific platform implementation.
/// </summary>
public IFormattedTextImpl PlatformImpl
{
get;
private set;
}
/// <summary>
/// Gets the text alignment.
/// </summary>
public TextAlignment TextAlignment
{
get;
private set;
}
/// <summary>
/// Disposes of unmanaged resources associated with the formatted text.
/// </summary>
public void Dispose()
{
this.PlatformImpl.Dispose();
}
/// <summary>
/// Gets the lines in the text.
/// </summary>
/// <returns>
/// A collection of <see cref="FormattedTextLine"/> objects.
/// </returns>
public IEnumerable<FormattedTextLine> GetLines()
{
return this.PlatformImpl.GetLines();
}
/// <summary>
/// Hit tests a point in the text.
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// A <see cref="TextHitTestResult"/> describing the result of the hit test.
/// </returns>
public TextHitTestResult HitTestPoint(Point point)
{
return this.PlatformImpl.HitTestPoint(point);
}
/// <summary>
/// Gets the bounds rectangle that the specified character occupies.
/// </summary>
/// <param name="index">The index of the character.</param>
/// <returns>The character bounds.</returns>
public Rect HitTestTextPosition(int index)
{
return this.PlatformImpl.HitTestTextPosition(index);
}
public IEnumerable<Rect> HitTestTextRange(int index, int length, Point origin = default(Point))
/// <summary>
/// Gets the bounds rectangles that the specified text range occupies.
/// </summary>
/// <param name="index">The index of the first character.</param>
/// <param name="length">The number of characters in the text range.</param>
/// <returns>The character bounds.</returns>
public IEnumerable<Rect> HitTestTextRange(int index, int length)
{
return this.PlatformImpl.HitTestTextRange(index, length, origin);
return this.PlatformImpl.HitTestTextRange(index, length);
}
/// <summary>
/// Gets the size of the text, taking <see cref="Constraint"/> into account.
/// </summary>
/// <returns>The bounds box of the text.</returns>
public Size Measure()
{
return this.PlatformImpl.Measure();
}
public void SetForegroundBrush(Brush brush, int startIndex, int count)
/// <summary>
/// Sets the foreground brush for the specified text range.
/// </summary>
/// <param name="brush">The brush.</param>
/// <param name="startIndex">The start of the text range.</param>
/// <param name="length">The length of the text range.</param>
public void SetForegroundBrush(Brush brush, int startIndex, int length)
{
this.PlatformImpl.SetForegroundBrush(brush, startIndex, count);
this.PlatformImpl.SetForegroundBrush(brush, startIndex, length);
}
}
}

20
Perspex.SceneGraph/Media/FormattedTextLine.cs

@ -1,21 +1,35 @@
// -----------------------------------------------------------------------
// <copyright file="FormattedTextLine.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Media
{
/// <summary>
/// Stores information about a line of <see cref="FormattedText"/>.
/// </summary>
public class FormattedTextLine
{
/// <summary>
/// Initializes a new instance of the <see cref="FormattedTextLine"/> class.
/// </summary>
/// <param name="length">The length of the line, in characters.</param>
/// <param name="height">The height of the line, in pixels.</param>
public FormattedTextLine(int length, double height)
{
this.Length = length;
this.Height = height;
}
public int Length { get; private set; }
/// <summary>
/// Gets the length of the line, in characters.
/// </summary>
public int Length { get; }
public double Height { get; private set; }
/// <summary>
/// Gets the height of the line, in pixels.
/// </summary>
public double Height { get; }
}
}

29
Perspex.SceneGraph/Media/Imaging/Bitmap.cs

@ -9,41 +9,70 @@ namespace Perspex.Media.Imaging
using Perspex.Platform;
using Splat;
/// <summary>
/// Holds a bitmap image.
/// </summary>
public class Bitmap : IBitmap
{
/// <summary>
/// Initializes a new instance of the <see cref="Bitmap"/> class.
/// </summary>
/// <param name="fileName">The filename of the bitmap.</param>
public Bitmap(string fileName)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
this.PlatformImpl = factory.LoadBitmap(fileName);
}
/// <summary>
/// Initializes a new instance of the <see cref="Bitmap"/> class.
/// </summary>
/// <param name="width">The width of the bitmap, in pixels.</param>
/// <param name="height">The height of the bitmap, in pixels.</param>
public Bitmap(int width, int height)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
this.PlatformImpl = factory.CreateBitmap(width, height);
}
/// <summary>
/// Initializes a new instance of the <see cref="Bitmap"/> class.
/// </summary>
/// <param name="impl">A platform-specific bitmap implementation.</param>
protected Bitmap(IBitmapImpl impl)
{
this.PlatformImpl = impl;
}
/// <summary>
/// Gets the width of the bitmap, in pixels.
/// </summary>
public int PixelWidth
{
get { return this.PlatformImpl.PixelWidth; }
}
/// <summary>
/// Gets the height of the bitmap, in pixels.
/// </summary>
public int PixelHeight
{
get { return this.PlatformImpl.PixelHeight; }
}
/// <summary>
/// Gets the platform-specific bitmap implementation.
/// </summary>
public IBitmapImpl PlatformImpl
{
get;
private set;
}
/// <summary>
/// Saves the bitmap to a file.
/// </summary>
/// <param name="fileName">The filename.</param>
public void Save(string fileName)
{
this.PlatformImpl.Save(fileName);

18
Perspex.SceneGraph/Media/Imaging/IBitmap.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="IBitmap.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,14 +8,30 @@ namespace Perspex.Media.Imaging
{
using Perspex.Platform;
/// <summary>
/// Represents a bitmap image.
/// </summary>
public interface IBitmap
{
/// <summary>
/// Gets the width of the bitmap, in pixels.
/// </summary>
int PixelWidth { get; }
/// <summary>
/// Gets the height of the bitmap, in pixels.
/// </summary>
int PixelHeight { get; }
/// <summary>
/// Gets the platform-specific bitmap implementation.
/// </summary>
IBitmapImpl PlatformImpl { get; }
/// <summary>
/// Saves the bitmap to a file.
/// </summary>
/// <param name="fileName">The filename.</param>
void Save(string fileName);
}
}

29
Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="RenderTargetBitmap.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -10,28 +10,55 @@ namespace Perspex.Media.Imaging
using Perspex.Platform;
using Splat;
/// <summary>
/// A bitmap that holds the rendering of a <see cref="IVisual"/>.
/// </summary>
public class RenderTargetBitmap : Bitmap, IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="RenderTargetBitmap"/> class.
/// </summary>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
public RenderTargetBitmap(int width, int height)
: base(CreateImpl(width, height))
{
}
/// <summary>
/// Gets the platform-specific bitmap implementation.
/// </summary>
public new IRenderTargetBitmapImpl PlatformImpl
{
get { return (IRenderTargetBitmapImpl)base.PlatformImpl; }
}
/// <summary>
/// Renders an <see cref="IVisual"/> into the bitmap.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <remarks>
/// Before calling this method, ensure that <paramref name="visual"/> has been measured.
/// </remarks>
public void Render(IVisual visual)
{
this.PlatformImpl.Render(visual);
}
/// <summary>
/// Disposes of the bitmap.
/// </summary>
public void Dispose()
{
this.PlatformImpl.Dispose();
}
/// <summary>
/// Creates a platform-specific imlementation for a <see cref="RenderTargetBitmap"/>.
/// </summary>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <returns>The platform-specific implementation.</returns>
private static IBitmapImpl CreateImpl(int width, int height)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();

21
Perspex.SceneGraph/Media/MatrixTransform.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="MatrixTransform.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,28 +8,47 @@ namespace Perspex.Media
{
using System;
/// <summary>
/// Transforms an <see cref="IVisual"/> according to a <see cref="Matrix"/>.
/// </summary>
public class MatrixTransform : Transform
{
/// <summary>
/// Defines the <see cref="Matrix"/> property.
/// </summary>
public static readonly PerspexProperty<Matrix> MatrixProperty =
PerspexProperty.Register<MatrixTransform, Matrix>("Matrix", Matrix.Identity);
/// <summary>
/// Initializes a new instance of the <see cref="MatrixTransform"/> class.
/// </summary>
public MatrixTransform()
{
this.GetObservable(MatrixProperty).Subscribe(_ => this.RaiseChanged());
}
/// <summary>
/// Initializes a new instance of the <see cref="MatrixTransform"/> class.
/// </summary>
/// <param name="matrix">The matrix.</param>
public MatrixTransform(Matrix matrix)
: this()
{
this.Matrix = matrix;
}
/// <summary>
/// Gets or sets the matrix.
/// </summary>
public Matrix Matrix
{
get { return this.GetValue(MatrixProperty); }
set { this.SetValue(MatrixProperty, value); }
}
/// <summary>
/// Gets the matrix.
/// </summary>
public override Matrix Value
{
get { return this.Matrix; }

15
Perspex.SceneGraph/Media/PathMarkupParser.cs

@ -12,6 +12,9 @@ namespace Perspex.Media
using System.IO;
using System.Text;
/// <summary>
/// Parses a path markup string.
/// </summary>
public class PathMarkupParser
{
private static readonly Dictionary<char, Command> Commands = new Dictionary<char, Command>
@ -36,12 +39,20 @@ namespace Perspex.Media
private StreamGeometryContext context;
/// <summary>
/// Initializes a new instance of the <see cref="PathMarkupParser"/> class.
/// </summary>
/// <param name="geometry">The geometry in which the path should be stored.</param>
/// <param name="context">The context for <paramref name="geometry"/>.</param>
public PathMarkupParser(StreamGeometry geometry, StreamGeometryContext context)
{
this.geometry = geometry;
this.context = context;
}
/// <summary>
/// Defines the command currently being processed.
/// </summary>
private enum Command
{
None,
@ -60,6 +71,10 @@ namespace Perspex.Media
Eof,
}
/// <summary>
/// Parses the specified markup string.
/// </summary>
/// <param name="s">The markup string.</param>
public void Parse(string s)
{
bool openFigure = false;

23
Perspex.SceneGraph/Media/RotateTransform.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="RotateTransform.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,31 +8,50 @@ namespace Perspex.Media
{
using System;
/// <summary>
/// Rotates an <see cref="IVisual"/>.
/// </summary>
public class RotateTransform : Transform
{
/// <summary>
/// Defines the <see cref="Angle"/> property.
/// </summary>
public static readonly PerspexProperty<double> AngleProperty =
PerspexProperty.Register<RotateTransform, double>("Angle");
/// <summary>
/// Initializes a new instance of the <see cref="RotateTransform"/> class.
/// </summary>
public RotateTransform()
{
this.GetObservable(AngleProperty).Subscribe(_ => this.RaiseChanged());
}
/// <summary>
/// Initializes a new instance of the <see cref="RotateTransform"/> class.
/// </summary>
/// <param name="angle">The angle, in degrees.</param>
public RotateTransform(double angle)
: this()
{
this.Angle = angle;
}
/// <summary>
/// Gets or sets the angle of rotation, in degrees.
/// </summary>
public double Angle
{
get { return this.GetValue(AngleProperty); }
set { this.SetValue(AngleProperty, value); }
}
/// <summary>
/// Gets the tranform's <see cref="Matrix"/>.
/// </summary>
public override Matrix Value
{
get { return Matrix.Rotation(Matrix.ToRadians(this.Angle)); }
get { return Matrix.CreateRotation(Matrix.ToRadians(this.Angle)); }
}
}
}

4
Perspex.SceneGraph/Media/SolidColorBrush.cs

@ -38,6 +38,10 @@ namespace Perspex.Media
private set;
}
/// <summary>
/// Returns a string representation of the brush.
/// </summary>
/// <returns>A string representation of the brush.</returns>
public override string ToString()
{
return this.Color.ToString();

22
Perspex.SceneGraph/Media/Stretch.cs

@ -6,11 +6,33 @@
namespace Perspex.Media
{
/// <summary>
/// Describes how content is resized to fill its allocated space.
/// </summary>
public enum Stretch
{
/// <summary>
/// The content preserves its original size.
/// </summary>
None,
/// <summary>
/// The content is resized to fill the destination dimensions. The aspect ratio is not
/// preserved.
/// </summary>
Fill,
/// <summary>
/// The content is resized to fit in the destination dimensions while preserving its
/// native aspect ratio.
/// </summary>
Uniform,
/// <summary>
/// The content is resized to completely fill the destination rectangle while preserving
/// its native aspect ratio. A portion of the content may not be visible if the aspect
/// ratio of the content does not match the aspect ratio of the allocated space.
/// </summary>
UniformToFill,
}
}

12
Perspex.SceneGraph/Media/SweepDirection.cs

@ -1,14 +1,24 @@
// -----------------------------------------------------------------------
// <copyright file="SweepDirection.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Media
{
/// <summary>
/// Defines the direction an which elliptical arc is drawn.
/// </summary>
public enum SweepDirection
{
/// <summary>
/// Specifies that arcs are drawn in a counter clockwise (negative-angle) direction.
/// </summary>
CounterClockwise,
/// <summary>
/// Specifies that arcs are drawn in a clockwise (positive-angle) direction.
/// </summary>
Clockwise,
}
}

16
Perspex.SceneGraph/Media/TextAlignment.cs

@ -1,15 +1,29 @@
// -----------------------------------------------------------------------
// <copyright file="TextAlignment.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Media
{
/// <summary>
/// Defines how text is aligned.
/// </summary>
public enum TextAlignment
{
/// <summary>
/// The text is left-aligned.
/// </summary>
Left,
/// <summary>
/// The text is centered.
/// </summary>
Center,
/// <summary>
/// The text is right-aligned.
/// </summary>
Right,
}
}

14
Perspex.SceneGraph/Media/TextHitTestResult.cs

@ -1,17 +1,29 @@
// -----------------------------------------------------------------------
// <copyright file="TextHitTestResult.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Media
{
/// <summary>
/// Holds a hit test result from a <see cref="FormattedText"/>.
/// </summary>
public class TextHitTestResult
{
/// <summary>
/// Gets or sets a value indicating whether the point is inside the bounds of the text.
/// </summary>
public bool IsInside { get; set; }
/// <summary>
/// Gets the index of the hit character in the text.
/// </summary>
public int TextPosition { get; set; }
/// <summary>
/// Gets a value indicating whether the hit is on the trailing edge of the character.
/// </summary>
public bool IsTrailing { get; set; }
}
}

12
Perspex.SceneGraph/Media/Transform.cs

@ -9,12 +9,24 @@ namespace Perspex.Media
using System;
using Perspex.Animation;
/// <summary>
/// Represents a transform on an <see cref="IVisual"/>.
/// </summary>
public abstract class Transform : Animatable
{
/// <summary>
/// Raised when the transform changes.
/// </summary>
public event EventHandler Changed;
/// <summary>
/// Gets the tranform's <see cref="Matrix"/>.
/// </summary>
public abstract Matrix Value { get; }
/// <summary>
/// Raises the <see cref="Changed"/> event.
/// </summary>
protected void RaiseChanged()
{
if (this.Changed != null)

28
Perspex.SceneGraph/Media/TranslateTransform.cs

@ -8,20 +8,37 @@ namespace Perspex.Media
{
using System;
/// <summary>
/// Translates (moves) an <see cref="IVisual"/>.
/// </summary>
public class TranslateTransform : Transform
{
/// <summary>
/// Defines the <see cref="X"/> property.
/// </summary>
public static readonly PerspexProperty<double> XProperty =
PerspexProperty.Register<TranslateTransform, double>("X");
/// <summary>
/// Defines the <see cref="Y"/> property.
/// </summary>
public static readonly PerspexProperty<double> YProperty =
PerspexProperty.Register<TranslateTransform, double>("Y");
/// <summary>
/// Initializes a new instance of the <see cref="TranslateTransform"/> class.
/// </summary>
public TranslateTransform()
{
this.GetObservable(XProperty).Subscribe(_ => this.RaiseChanged());
this.GetObservable(YProperty).Subscribe(_ => this.RaiseChanged());
}
/// <summary>
/// Initializes a new instance of the <see cref="TranslateTransform"/> class.
/// </summary>
/// <param name="x">Gets the horizontal offset of the translate.</param>
/// <param name="y">Gets the vertical offset of the translate.</param>
public TranslateTransform(double x, double y)
: this()
{
@ -29,21 +46,30 @@ namespace Perspex.Media
this.Y = y;
}
/// <summary>
/// Gets the horizontal offset of the translate.
/// </summary>
public double X
{
get { return this.GetValue(XProperty); }
set { this.SetValue(XProperty, value); }
}
/// <summary>
/// Gets the vertical offset of the translate.
/// </summary>
public double Y
{
get { return this.GetValue(YProperty); }
set { this.SetValue(YProperty, value); }
}
/// <summary>
/// Gets the tranform's <see cref="Matrix"/>.
/// </summary>
public override Matrix Value
{
get { return Matrix.Translation(this.X, this.Y); }
get { return Matrix.CreateTranslation(this.X, this.Y); }
}
}
}

41
Perspex.SceneGraph/Origin.cs

@ -6,44 +6,79 @@
namespace Perspex
{
using System;
using System.Globalization;
/// <summary>
/// Defines the reference point units of an <see cref="Origin"/>.
/// </summary>
public enum OriginUnit
{
/// <summary>
/// The origin's point is a percentage.
/// </summary>
Percent,
/// <summary>
/// The origin's point is in pixels.
/// </summary>
Pixels,
}
/// <summary>
/// Defines an origin for a <see cref="Perspex.Media.Transform"/>.
/// </summary>
public struct Origin
{
/// <summary>
/// The default origin, which is the center of the control.
/// </summary>
public static readonly Origin Default = new Origin(0.5, 0.5, OriginUnit.Percent);
private Point point;
private OriginUnit unit;
/// <summary>
/// Initializes a new instance of the <see cref="Origin"/> struct.
/// </summary>
/// <param name="x">The X point.</param>
/// <param name="y">The Y point</param>
/// <param name="unit">The origin unit.</param>
public Origin(double x, double y, OriginUnit unit)
: this(new Point(x, y), unit)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Origin"/> struct.
/// </summary>
/// <param name="point">The origin point.</param>
/// <param name="unit">The origin unit.</param>
public Origin(Point point, OriginUnit unit)
{
this.point = point;
this.unit = unit;
}
/// <summary>
/// Gets the origin point.
/// </summary>
public Point Point
{
get { return this.point; }
}
/// <summary>
/// Gets the origin unit.
/// </summary>
public OriginUnit Unit
{
get { return this.unit; }
}
/// <summary>
/// Converts an <see cref="Origin"/> into pixels.
/// </summary>
/// <param name="size">The size of the visual.</param>
/// <returns>The origin point in pixels.</returns>
public Point ToPixels(Size size)
{
return this.unit == OriginUnit.Pixels ?

2
Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -52,6 +52,7 @@
<Compile Include="Animation\CrossFade.cs" />
<Compile Include="Animation\IPageTransition.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Matrix.cs" />
<Compile Include="Media\Brush.cs" />
<Compile Include="Media\Brushes.cs" />
<Compile Include="Media\Color.cs" />
@ -64,7 +65,6 @@
<Compile Include="Media\Geometry.cs" />
<Compile Include="Media\IDrawingContext.cs" />
<Compile Include="IVisual.cs" />
<Compile Include="Matrix.cs" />
<Compile Include="Media\Imaging\Bitmap.cs" />
<Compile Include="Media\Imaging\IBitmap.cs" />
<Compile Include="Media\Imaging\RenderTargetBitmap.cs" />

13
Perspex.SceneGraph/Platform/IBitmapImpl.cs

@ -6,12 +6,25 @@
namespace Perspex.Platform
{
/// <summary>
/// Defines the platform-specific interface for a <see cref="Perspex.Media.Imaging.Bitmap"/>.
/// </summary>
public interface IBitmapImpl
{
/// <summary>
/// Gets the width of the bitmap, in pixels.
/// </summary>
int PixelWidth { get; }
/// <summary>
/// Gets the height of the bitmap, in pixels.
/// </summary>
int PixelHeight { get; }
/// <summary>
/// Saves the bitmap to a file.
/// </summary>
/// <param name="fileName">The filename.</param>
void Save(string fileName);
}
}

46
Perspex.SceneGraph/Platform/IFormattedTextImpl.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="IFormattedTextImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -10,20 +10,60 @@ namespace Perspex.Platform
using System.Collections.Generic;
using Perspex.Media;
/// <summary>
/// Defines the platform-specific interface for <see cref="FormattedText"/>.
/// </summary>
public interface IFormattedTextImpl : IDisposable
{
/// <summary>
/// Gets or sets the constraint of the text.
/// </summary>
Size Constraint { get; set; }
/// <summary>
/// Gets the lines in the text.
/// </summary>
/// <returns>
/// A collection of <see cref="FormattedTextLine"/> objects.
/// </returns>
IEnumerable<FormattedTextLine> GetLines();
/// <summary>
/// Hit tests a point in the text.
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// A <see cref="TextHitTestResult"/> describing the result of the hit test.
/// </returns>
TextHitTestResult HitTestPoint(Point point);
/// <summary>
/// Gets the bounds rectangle that the specified character occupies.
/// </summary>
/// <param name="index">The index of the character.</param>
/// <returns>The character bounds.</returns>
Rect HitTestTextPosition(int index);
IEnumerable<Rect> HitTestTextRange(int index, int length, Point origin);
/// <summary>
/// Gets the bounds rectangles that the specified text range occupies.
/// </summary>
/// <param name="index">The index of the first character.</param>
/// <param name="length">The number of characters in the text range.</param>
/// <returns>The character bounds.</returns>
IEnumerable<Rect> HitTestTextRange(int index, int length);
/// <summary>
/// Gets the size of the text, taking <see cref="Constraint"/> into account.
/// </summary>
/// <returns>The bounds box of the text.</returns>
Size Measure();
void SetForegroundBrush(Brush brush, int startIndex, int count);
/// <summary>
/// Sets the foreground brush for the specified text range.
/// </summary>
/// <param name="brush">The brush.</param>
/// <param name="startIndex">The start of the text range.</param>
/// <param name="length">The length of the text range.</param>
void SetForegroundBrush(Brush brush, int startIndex, int length);
}
}

16
Perspex.SceneGraph/Platform/IGeometryImpl.cs

@ -1,17 +1,31 @@
// -----------------------------------------------------------------------
// <copyright file="IGeometryImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Platform
{
/// <summary>
/// Defines the platform-specific interface for <see cref="Perspex.Media.Geometry"/>.
/// </summary>
public interface IGeometryImpl
{
/// <summary>
/// Gets the geometry's bounding rectangle.
/// </summary>
Rect Bounds { get; }
/// <summary>
/// Gets or sets a transform to apply to the geometry.
/// </summary>
Matrix Transform { get; set; }
/// <summary>
/// Gets the geometry's bounding rectangle with the specified stroke thickness.
/// </summary>
/// <param name="strokeThickness">The stroke thickness.</param>
/// <returns>The bounding rectangle.</returns>
Rect GetRenderBounds(double strokeThickness);
}
}

45
Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="IPlatformRenderInterface.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,24 +8,65 @@ namespace Perspex.Platform
{
using Perspex.Media;
/// <summary>
/// Defines the main platform-specific interface for the rendering subsystem.
/// </summary>
public interface IPlatformRenderInterface
{
/// <summary>
/// Creates a bitmap implementation.
/// </summary>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <returns>An <see cref="IBitmapImpl"/>.</returns>
IBitmapImpl CreateBitmap(int width, int height);
/// <summary>
/// Creates a formatted text implementation.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="fontFamilyName">The font family.</param>
/// <param name="fontSize">The font size.</param>
/// <param name="fontStyle">The font style.</param>
/// <param name="textAlignment">The text alignment.</param>
/// <param name="fontWeight">The font weight.</param>
/// <returns>An <see cref="IFormattedTextImpl"/>.</returns>
IFormattedTextImpl CreateFormattedText(
string text,
string fontFamily,
string fontFamilyName,
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight);
/// <summary>
/// Creates a stream geometry implementation.
/// </summary>
/// <returns>An <see cref="IStreamGeometryImpl"/>.</returns>
IStreamGeometryImpl CreateStreamGeometry();
/// <summary>
/// Creates a renderer.
/// </summary>
/// <param name="handle">The platform handle for the renderer.</param>
/// <param name="width">The initial width of the render.</param>
/// <param name="height">The initial height of the render.</param>
/// <returns>An <see cref="IRenderer"/>.</returns>
IRenderer CreateRenderer(IPlatformHandle handle, double width, double height);
/// <summary>
/// Creates a render target bitmap implementation.
/// </summary>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <returns>An <see cref="IRenderTargetBitmapImpl"/>.</returns>
IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height);
/// <summary>
/// Loads a bitmap implementation from a file..
/// </summary>
/// <param name="fileName">The filename of the bitmap.</param>
/// <returns>An <see cref="IBitmapImpl"/>.</returns>
IBitmapImpl LoadBitmap(string fileName);
}
}

13
Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="IRenderTargetBitmapImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,8 +8,19 @@ namespace Perspex.Platform
{
using System;
/// <summary>
/// Defines the platform-specific interface for a
/// <see cref="Perspex.Media.Imaging.RenderTargetBitmap"/>.
/// </summary>
public interface IRenderTargetBitmapImpl : IBitmapImpl, IDisposable
{
/// <summary>
/// Renders an <see cref="IVisual"/> into the bitmap.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <remarks>
/// Before calling this method, ensure that <paramref name="visual"/> has been measured.
/// </remarks>
void Render(IVisual visual);
}
}

13
Perspex.SceneGraph/Platform/IRenderer.cs

@ -1,13 +1,20 @@
// -----------------------------------------------------------------------
// <copyright file="IRenderer.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Platform
{
using System;
/// <summary>
/// Defines a renderer.
/// </summary>
/// <remarks>
/// The interface used to render <see cref="IVisual"/>s. You will usually want to inherit from
/// <see cref="Perspex.Rendering.RendererBase"/> rather than implementing the whole interface
/// as RenderBase has a default implementation for the non-platform specific parts of a
/// renderer.
/// </remarks>
public interface IRenderer
{
/// <summary>

15
Perspex.SceneGraph/Platform/IStreamGeometryImpl.cs

@ -1,15 +1,28 @@
// -----------------------------------------------------------------------
// <copyright file="IStreamGeometryImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Platform
{
/// <summary>
/// Defines the platform-specific interface for a <see cref="Perspex.Media.StreamGeometry"/>.
/// </summary>
public interface IStreamGeometryImpl : IGeometryImpl
{
/// <summary>
/// Clones the geometry.
/// </summary>
/// <returns>A cloned geometry.</returns>
IStreamGeometryImpl Clone();
/// <summary>
/// Opens the geometry to start defining it.
/// </summary>
/// <returns>
/// An <see cref="IStreamGeometryContextImpl"/> which can be used to define the geometry.
/// </returns>
IStreamGeometryContextImpl Open();
}
}

4
Perspex.SceneGraph/Point.cs

@ -134,8 +134,8 @@ namespace Perspex
public static Point operator *(Point point, Matrix matrix)
{
return new Point(
(point.X * matrix.M11) + (point.Y * matrix.M21) + matrix.OffsetX,
(point.X * matrix.M12) + (point.Y * matrix.M22) + matrix.OffsetY);
(point.X * matrix.M11) + (point.Y * matrix.M21) + matrix.M31,
(point.X * matrix.M12) + (point.Y * matrix.M22) + matrix.M32);
}
/// <summary>

39
Perspex.SceneGraph/Rect.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="Rect.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -221,6 +221,12 @@ namespace Perspex
return !(left == right);
}
/// <summary>
/// Multiplies a rectangle by a vector.
/// </summary>
/// <param name="rect">The rectangle.</param>
/// <param name="scale">The vector scale.</param>
/// <returns>The scaled rectangle.</returns>
public static Rect operator *(Rect rect, Vector scale)
{
double centerX = rect.x + (rect.width / 2);
@ -234,11 +240,23 @@ namespace Perspex
height);
}
/// <summary>
/// Transforms a rectangle by a matrix and returns the axis-aligned bounding box.
/// </summary>
/// <param name="rect">The rectangle.</param>
/// <param name="matrix">The matrix.</param>
/// <returns>The axis-aligned bounding box.</returns>
public static Rect operator *(Rect rect, Matrix matrix)
{
return new Rect(rect.TopLeft * matrix, rect.BottomRight * matrix);
}
/// <summary>
/// Divides a rectangle by a vector.
/// </summary>
/// <param name="rect">The rectangle.</param>
/// <param name="scale">The vector scale.</param>
/// <returns>The scaled rectangle.</returns>
public static Rect operator /(Rect rect, Vector scale)
{
double centerX = rect.x + (rect.width / 2);
@ -263,6 +281,11 @@ namespace Perspex
p.Y >= this.y && p.Y < this.y + this.height;
}
/// <summary>
/// Centers another rectangle in this rectangle.
/// </summary>
/// <param name="rect">The rectangle to center.</param>
/// <returns>The centered rectangle.</returns>
public Rect CenterIn(Rect rect)
{
return new Rect(
@ -318,6 +341,11 @@ namespace Perspex
this.Size.Deflate(thickness));
}
/// <summary>
/// Returns a boolean indicating whether the given object is equal to this rectangle.
/// </summary>
/// <param name="obj">The object to compare against.</param>
/// <returns>True if the object is equal to this rectangle; false otherwise.</returns>
public override bool Equals(object obj)
{
if (obj is Rect)
@ -328,6 +356,10 @@ namespace Perspex
return false;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode()
{
unchecked
@ -341,6 +373,11 @@ namespace Perspex
}
}
/// <summary>
/// Gets the intersection of two rectangles.
/// </summary>
/// <param name="rect">The other rectangle.</param>
/// <returns>The intersection.</returns>
public Rect Intersect(Rect rect)
{
double x = Math.Max(this.x, rect.x);

15
Perspex.SceneGraph/Rendering/IRenderManager.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="IRenderManager.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -9,12 +9,25 @@ namespace Perspex.Rendering
using System;
using System.Reactive;
/// <summary>
/// Defines the interface for a <see cref="RenderManager"/>.
/// </summary>
public interface IRenderManager
{
/// <summary>
/// Gets an observable that is fired whenever a render is required.
/// </summary>
IObservable<Unit> RenderNeeded { get; }
/// <summary>
/// Invalidates the render for the specified visual and raises <see cref="RenderNeeded"/>.
/// </summary>
/// <param name="visual">The visual.</param>
void InvalidateRender(IVisual visual);
/// <summary>
/// Called when rendering is finished.
/// </summary>
void RenderFinished();
}
}

16
Perspex.SceneGraph/Rendering/IRenderRoot.cs

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="IRenderRoot.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,12 +8,26 @@ namespace Perspex.Rendering
{
using Perspex.Platform;
/// <summary>
/// Represents the root of a renderable tree.
/// </summary>
public interface IRenderRoot
{
/// <summary>
/// Gets the renderer for the tree.
/// </summary>
IRenderer Renderer { get; }
/// <summary>
/// Gets the render manager which schedules renders.
/// </summary>
IRenderManager RenderManager { get; }
/// <summary>
/// Translates a point to screen co-ordinates.
/// </summary>
/// <param name="p">The point.</param>
/// <returns>The point in screen co-ordinates.</returns>
Point TranslatePointToScreen(Point p);
}
}

16
Perspex.SceneGraph/Rendering/RenderManager.cs

@ -10,22 +10,35 @@ namespace Perspex.Rendering
using System.Reactive;
using System.Reactive.Subjects;
/// <summary>
/// Schedules the rendering of a tree.
/// </summary>
public class RenderManager : IRenderManager
{
private Subject<Unit> renderNeeded = new Subject<Unit>();
private bool renderQueued;
/// <summary>
/// Gets an observable that is fired whenever a render is required.
/// </summary>
public IObservable<Unit> RenderNeeded
{
get { return this.renderNeeded; }
}
/// <summary>
/// Gets a valuue indicating whether a render is queued.
/// </summary>
public bool RenderQueued
{
get { return this.renderQueued; }
}
/// <summary>
/// Invalidates the render for the specified visual and raises <see cref="RenderNeeded"/>.
/// </summary>
/// <param name="visual">The visual.</param>
public void InvalidateRender(IVisual visual)
{
if (!this.renderQueued)
@ -35,6 +48,9 @@ namespace Perspex.Rendering
}
}
/// <summary>
/// Called when rendering is finished.
/// </summary>
public void RenderFinished()
{
this.renderQueued = false;

6
Perspex.SceneGraph/Rendering/RendererBase.cs

@ -71,16 +71,16 @@ namespace Perspex.Rendering
if (visual.IsVisible && opacity > 0)
{
// Translate any existing transform into this controls coordinate system.
Matrix offset = Matrix.Translation(visual.Bounds.Position);
Matrix offset = Matrix.CreateTranslation(visual.Bounds.Position);
transform = offset * transform * -offset;
// Update the current offset.
translation *= Matrix.Translation(visual.Bounds.Position);
translation *= Matrix.CreateTranslation(visual.Bounds.Position);
// Apply the control's render transform, if any.
if (visual.RenderTransform != null)
{
offset = Matrix.Translation(visual.TransformOrigin.ToPixels(visual.Bounds.Size));
offset = Matrix.CreateTranslation(visual.TransformOrigin.ToPixels(visual.Bounds.Size));
transform *= -offset * visual.RenderTransform.Value * offset;
}

2
Perspex.SceneGraph/Size.cs

@ -193,7 +193,7 @@ namespace Perspex
/// <summary>
/// Returns the string representation of the size.
/// </summary>
/// <returns>The string representation of the size</returns>
/// <returns>The string representation of the size.</returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", this.width, this.height);

18
Perspex.SceneGraph/Thickness.cs

@ -8,6 +8,9 @@ namespace Perspex
{
using System;
/// <summary>
/// Describes the thickness of a frame around a rectangle.
/// </summary>
public struct Thickness
{
/// <summary>
@ -152,6 +155,13 @@ namespace Perspex
a.Bottom + b.Bottom);
}
/// <summary>
/// Checks for equality between a thickness and an object.
/// </summary>
/// <param name="obj">The object.</param>
/// <returns>
/// True if <paramref name="obj"/> is a size that equals the current size.
/// </returns>
public override bool Equals(object obj)
{
if (obj is Thickness)
@ -166,6 +176,10 @@ namespace Perspex
return false;
}
/// <summary>
/// Returns a hash code for a <see cref="Thickness"/>.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode()
{
unchecked
@ -179,6 +193,10 @@ namespace Perspex
}
}
/// <summary>
/// Returns the string representation of the thickness.
/// </summary>
/// <returns>The string representation of the thickness.</returns>
public override string ToString()
{
return string.Format("{0},{1},{2},{3}", this.left, this.top, this.right, this.bottom);

2
Perspex.SceneGraph/Visual.cs

@ -262,7 +262,7 @@ namespace Perspex
{
var thisOffset = GetOffsetFromRoot(this).Item2;
var thatOffset = GetOffsetFromRoot(visual).Item2;
return Matrix.Translation(-thatOffset) * Matrix.Translation(thisOffset);
return Matrix.CreateTranslation(-thatOffset) * Matrix.CreateTranslation(thisOffset);
}
/// <summary>

71
Perspex.SceneGraph/VisualTree/VisualExtensions.cs

@ -10,8 +10,16 @@ namespace Perspex.VisualTree
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Provides extension methods for working with visual tree.
/// </summary>
public static class VisualExtensions
{
/// <summary>
/// Enumerates the ancestors of an <see cref="IVisual"/> in the visual tree.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The visual's ancestors.</returns>
public static IEnumerable<IVisual> GetVisualAncestors(this IVisual visual)
{
Contract.Requires<NullReferenceException>(visual != null);
@ -25,6 +33,11 @@ namespace Perspex.VisualTree
}
}
/// <summary>
/// Enumerates an <see cref="IVisual"/> and its ancestors in the visual tree.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The visual and its ancestors.</returns>
public static IEnumerable<IVisual> GetSelfAndVisualAncestors(this IVisual visual)
{
yield return visual;
@ -35,6 +48,12 @@ namespace Perspex.VisualTree
}
}
/// <summary>
/// Gets the first visual in the visual tree whose bounds contain a point.
/// </summary>
/// <param name="visual">The root visual to test.</param>
/// <param name="p">The point.</param>
/// <returns>The visuals at the requested point.</returns>
public static IVisual GetVisualAt(this IVisual visual, Point p)
{
Contract.Requires<NullReferenceException>(visual != null);
@ -42,6 +61,12 @@ namespace Perspex.VisualTree
return visual.GetVisualsAt(p).FirstOrDefault();
}
/// <summary>
/// Enumerates the visuals in the visual tree whose bounds contain a point.
/// </summary>
/// <param name="visual">The root visual to test.</param>
/// <param name="p">The point.</param>
/// <returns>The visuals at the requested point.</returns>
public static IEnumerable<IVisual> GetVisualsAt(this IVisual visual, Point p)
{
Contract.Requires<NullReferenceException>(visual != null);
@ -65,11 +90,21 @@ namespace Perspex.VisualTree
}
}
/// <summary>
/// Enumerates the children of an <see cref="IVisual"/> in the visual tree.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The visual children.</returns>
public static IEnumerable<IVisual> GetVisualChildren(this IVisual visual)
{
return visual.VisualChildren;
}
/// <summary>
/// Enumerates the descendents of an <see cref="IVisual"/> in the visual tree.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The visual's ancestors.</returns>
public static IEnumerable<IVisual> GetVisualDescendents(this IVisual visual)
{
foreach (IVisual child in visual.VisualChildren)
@ -83,6 +118,11 @@ namespace Perspex.VisualTree
}
}
/// <summary>
/// Enumerates an <see cref="IVisual"/> and its descendents in the visual tree.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The visual and its ancestors.</returns>
public static IEnumerable<IVisual> GetSelfAndVisualDescendents(this IVisual visual)
{
yield return visual;
@ -93,16 +133,36 @@ namespace Perspex.VisualTree
}
}
/// <summary>
/// Gets the visual parent of an <see cref="IVisual"/>.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The parent, or null if the visual is unparented.</returns>
public static IVisual GetVisualParent(this IVisual visual)
{
return visual.VisualParent;
}
/// <summary>
/// Gets the visual parent of an <see cref="IVisual"/>.
/// </summary>
/// <typeparam name="T">The type of the visual parent.</typeparam>
/// <param name="visual">The visual.</param>
/// <returns>
/// The parent, or null if the visual is unparented or its parent is not of type <typeparamref name="T"/>.
/// </returns>
public static T GetVisualParent<T>(this IVisual visual) where T : class
{
return visual.VisualParent as T;
}
/// <summary>
/// Gets the root visual for an <see cref="IVisual"/>.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>
/// The root visual or null if the visual is not rooted.
/// </returns>
public static IVisual GetVisualRoot(this IVisual visual)
{
Contract.Requires<NullReferenceException>(visual != null);
@ -118,7 +178,16 @@ namespace Perspex.VisualTree
return visual;
}
public static bool IsVisualParentOf(this IVisual visual, IVisual target)
/// <summary>
/// Tests whether an <see cref="IVisual"/> is an ancestor of another visual.
/// </summary>
/// <param name="visual">The visual.</param>
/// <param name="target">The potential descendent.</param>
/// <returns>
/// True if <paramref name="visual"/> is an ancestor of <paramref name="target"/>;
/// otherwise false.
/// </returns>
public static bool IsVisualAncestorOf(this IVisual visual, IVisual target)
{
return target.GetVisualAncestors().Any(x => x == visual);
}

9
Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs

@ -107,14 +107,9 @@ namespace Perspex.Direct2D1.Media
return new Rect(result.Left, result.Top, result.Width, result.Height);
}
public IEnumerable<Rect> HitTestTextRange(int index, int length, Point origin)
public IEnumerable<Rect> HitTestTextRange(int index, int length)
{
var result = this.TextLayout.HitTestTextRange(
index,
length,
(float)origin.X,
(float)origin.Y);
var result = this.TextLayout.HitTestTextRange(index, length, 0, 0);
return result.Select(x => new Rect(x.Left, x.Top, x.Width, x.Height));
}

4
Windows/Perspex.Direct2D1/PrimitiveExtensions.cs

@ -104,8 +104,8 @@ namespace Perspex.Direct2D1
(float)matrix.M12,
(float)matrix.M21,
(float)matrix.M22,
(float)matrix.OffsetX,
(float)matrix.OffsetY);
(float)matrix.M31,
(float)matrix.M32);
}
/// <summary>

Loading…
Cancel
Save