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) if (this.Stretch != Stretch.None)
{ {
shapeSize = shapeBounds.Size; shapeSize = shapeBounds.Size;
translate = Matrix.Translation(-(Vector)shapeBounds.Position); translate = Matrix.CreateTranslation(-(Vector)shapeBounds.Position);
} }
if (double.IsInfinity(availableSize.Width)) if (double.IsInfinity(availableSize.Width))
@ -179,7 +179,7 @@ namespace Perspex.Controls.Shapes
break; break;
} }
var t = translate * Matrix.Scaling(sx, sy); var t = translate * Matrix.CreateScale(sx, sy);
if (this.transform != t) 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 the menu is open, only match controls in the menu's visual tree.
if (menuIsOpen) if (menuIsOpen)
{ {
matches = matches.Where(x => this.MainMenu.IsVisualParentOf(x)); matches = matches.Where(x => this.MainMenu.IsVisualAncestorOf(x));
} }
var match = matches.FirstOrDefault(); var match = matches.FirstOrDefault();

258
Perspex.SceneGraph/Matrix.cs

@ -1,4 +1,4 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="Matrix.cs" company="Steven Kirk"> // <copyright file="Matrix.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information. // Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright> // </copyright>
@ -7,16 +7,29 @@
namespace Perspex namespace Perspex
{ {
using System; using System;
using System.Globalization;
/// <summary>
/// A 2x3 matrix.
/// </summary>
public struct Matrix public struct Matrix
{ {
private double m11; private double m11;
private double m12; private double m12;
private double m21; private double m21;
private double m22; private double m22;
private double offsetX; private double m31;
private double offsetY; 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( public Matrix(
double m11, double m11,
double m12, double m12,
@ -29,176 +42,279 @@ namespace Perspex
this.m12 = m12; this.m12 = m12;
this.m21 = m21; this.m21 = m21;
this.m22 = m22; this.m22 = m22;
this.offsetX = offsetX; this.m31 = offsetX;
this.offsetY = offsetY; this.m32 = offsetY;
} }
/// <summary>
/// Returns the multiplicative identity matrix.
/// </summary>
public static Matrix Identity public static Matrix Identity
{ {
get { return new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); } get { return new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); }
} }
public double Determinant /// <summary>
{ /// Returns whether the matrix is the identity matrix.
get { return (this.m11 * this.m22) - (this.m12 * this.m21); } /// </summary>
}
public bool HasInverse
{
get { return this.Determinant != 0; }
}
public bool IsIdentity public bool IsIdentity
{ {
get { return this.Equals(Matrix.Identity); } get { return this.Equals(Matrix.Identity); }
} }
/// <summary>
/// The first element of the first row
/// </summary>
public double M11 public double M11
{ {
get { return this.m11; } get { return this.m11; }
} }
/// <summary>
/// The second element of the first row
/// </summary>
public double M12 public double M12
{ {
get { return this.m12; } get { return this.m12; }
} }
/// <summary>
/// The first element of the second row
/// </summary>
public double M21 public double M21
{ {
get { return this.m21; } get { return this.m21; }
} }
/// <summary>
/// The second element of the second row
/// </summary>
public double M22 public double M22
{ {
get { return this.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( return new Matrix(
(left.M11 * right.M11) + (left.M12 * right.M21), (value1.M11 * value2.M11) + (value1.M12 * value2.M21),
(left.M11 * right.M12) + (left.M12 * right.M22), (value1.M11 * value2.M12) + (value1.M12 * value2.M22),
(left.M21 * right.M11) + (left.M22 * right.M21), (value1.M21 * value2.M11) + (value1.M22 * value2.M21),
(left.M21 * right.M12) + (left.M22 * right.M22), (value1.M21 * value2.M12) + (value1.M22 * value2.M22),
(left.offsetX * right.M11) + (left.offsetY * right.M21) + right.offsetX, (value1.m31 * value2.M11) + (value1.m32 * value2.M21) + value2.m31,
(left.offsetX * right.M12) + (left.offsetY * right.M22) + right.offsetY); (value1.m31 * value2.M12) + (value1.m32 * value2.M22) + value2.m32);
}
public static Matrix operator -(Matrix matrix)
{
return matrix.Invert();
} }
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 cos = Math.Cos(radians);
double sin = Math.Sin(angle); double sin = Math.Sin(radians);
return new Matrix(cos, sin, -sin, cos, 0, 0); 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) public static double ToRadians(double angle)
{ {
return angle * 0.0174532925; 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 && return this.m11 == other.M11 &&
this.m12 == value.M12 && this.m12 == other.M12 &&
this.m21 == value.M21 && this.m21 == other.M21 &&
this.m22 == value.M22 && this.m22 == other.M22 &&
this.offsetX == value.OffsetX && this.m31 == other.M31 &&
this.offsetY == value.OffsetY; 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 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() 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() public override string ToString()
{ {
CultureInfo ci = CultureInfo.CurrentCulture;
return string.Format( return string.Format(
"{0},{1} {2},{3} {4},{5}", ci,
this.m11, "{{ {{M11:{0} M12:{1}}} {{M21:{2} M22:{3}}} {{M31:{4} M32:{5}}} }}",
this.m12, this.M11.ToString(ci),
this.m21, this.M12.ToString(ci),
this.m22, this.M21.ToString(ci),
this.offsetX, this.M22.ToString(ci),
this.offsetY); this.M31.ToString(ci),
this.M32.ToString(ci));
} }
/// <summary>
/// Inverts the Matrix.
/// </summary>
/// <returns>The inverted matrix.</returns>
public Matrix Invert() public Matrix Invert()
{ {
if (!this.HasInverse) if (this.GetDeterminant() == 0)
{ {
throw new InvalidOperationException("Transform is not invertible."); throw new InvalidOperationException("Transform is not invertible.");
} }
double d = this.Determinant; double d = this.GetDeterminant();
return new Matrix( return new Matrix(
this.m22 / d, this.m22 / d,
-this.m12 / d, -this.m12 / d,
-this.m21 / d, -this.m21 / d,
this.m11 / d, this.m11 / d,
((this.m21 * this.offsetY) - (this.m22 * this.offsetX)) / d, ((this.m21 * this.m32) - (this.m22 * this.m31)) / d,
((this.m12 * this.offsetX) - (this.m11 * this.offsetY)) / d); ((this.m12 * this.m31) - (this.m11 * this.m32)) / d);
} }
} }
} }

14
Perspex.SceneGraph/Media/FontStyle.cs

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

70
Perspex.SceneGraph/Media/FontWeight.cs

@ -6,23 +6,93 @@
namespace Perspex.Media 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 public enum FontWeight
{ {
/// <summary>
/// Specifies a "thin" font weight.
/// </summary>
Thin = 100, Thin = 100,
/// <summary>
/// Specifies an "extra light" font weight.
/// </summary>
ExtraLight = 200, ExtraLight = 200,
/// <summary>
/// Specifies an "ultra light" font weight.
/// </summary>
UltraLight = 200, UltraLight = 200,
/// <summary>
/// Specifies a "light" font weight.
/// </summary>
Light = 300, Light = 300,
/// <summary>
/// Specifies a "normal" font weight.
/// </summary>
Normal = 400, Normal = 400,
/// <summary>
/// Specifies a "regular" font weight.
/// </summary>
Regular = 400, Regular = 400,
/// <summary>
/// Specifies a "medium" font weight.
/// </summary>
Medium = 500, Medium = 500,
/// <summary>
/// Specifies a "demi-bold" font weight.
/// </summary>
DemiBold = 600, DemiBold = 600,
/// <summary>
/// Specifies a "semi-bold" font weight.
/// </summary>
SemiBold = 600, SemiBold = 600,
/// <summary>
/// Specifies a "bold" font weight.
/// </summary>
Bold = 700, Bold = 700,
/// <summary>
/// Specifies an "extra bold" font weight.
/// </summary>
ExtraBold = 800, ExtraBold = 800,
/// <summary>
/// Specifies an "ultra bold" font weight.
/// </summary>
UltraBold = 800, UltraBold = 800,
/// <summary>
/// Specifies a "black" font weight.
/// </summary>
Black = 900, Black = 900,
/// <summary>
/// Specifies a "heavy" font weight.
/// </summary>
Heavy = 900, Heavy = 900,
/// <summary>
/// Specifies an "extra black" font weight.
/// </summary>
ExtraBlack = 950, ExtraBlack = 950,
/// <summary>
/// Specifies an "ultra black" font weight.
/// </summary>
UltraBlack = 950 UltraBlack = 950
} }
} }

83
Perspex.SceneGraph/Media/FormattedText.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="FormattedText.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -11,8 +11,20 @@ namespace Perspex.Media
using Perspex.Platform; using Perspex.Platform;
using Splat; using Splat;
/// <summary>
/// Represents a piece of text with formatting.
/// </summary>
public class FormattedText : IDisposable 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( public FormattedText(
string text, string text,
string fontFamilyName, string fontFamilyName,
@ -39,87 +51,148 @@ namespace Perspex.Media
fontWeight); fontWeight);
} }
/// <summary>
/// Gets or sets the constraint of the text.
/// </summary>
public Size Constraint public Size Constraint
{ {
get { return this.PlatformImpl.Constraint; } get { return this.PlatformImpl.Constraint; }
set { this.PlatformImpl.Constraint = value; } set { this.PlatformImpl.Constraint = value; }
} }
/// <summary>
/// Gets the font family.
/// </summary>
public string FontFamilyName public string FontFamilyName
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Gets the font size.
/// </summary>
public double FontSize public double FontSize
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Gets the font style.
/// </summary>
public FontStyle FontStyle public FontStyle FontStyle
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Gets the font weight.
/// </summary>
public FontWeight FontWeight public FontWeight FontWeight
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Gets the text.
/// </summary>
public string Text public string Text
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Gets platform-specific platform implementation.
/// </summary>
public IFormattedTextImpl PlatformImpl public IFormattedTextImpl PlatformImpl
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Gets the text alignment.
/// </summary>
public TextAlignment TextAlignment public TextAlignment TextAlignment
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Disposes of unmanaged resources associated with the formatted text.
/// </summary>
public void Dispose() public void Dispose()
{ {
this.PlatformImpl.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() public IEnumerable<FormattedTextLine> GetLines()
{ {
return this.PlatformImpl.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) public TextHitTestResult HitTestPoint(Point point)
{ {
return this.PlatformImpl.HitTestPoint(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) public Rect HitTestTextPosition(int index)
{ {
return this.PlatformImpl.HitTestTextPosition(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() public Size Measure()
{ {
return this.PlatformImpl.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 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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Media namespace Perspex.Media
{ {
/// <summary>
/// Stores information about a line of <see cref="FormattedText"/>.
/// </summary>
public class FormattedTextLine 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) public FormattedTextLine(int length, double height)
{ {
this.Length = length; this.Length = length;
this.Height = height; 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 Perspex.Platform;
using Splat; using Splat;
/// <summary>
/// Holds a bitmap image.
/// </summary>
public class Bitmap : IBitmap 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) public Bitmap(string fileName)
{ {
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
this.PlatformImpl = factory.LoadBitmap(fileName); 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) public Bitmap(int width, int height)
{ {
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
this.PlatformImpl = factory.CreateBitmap(width, height); 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) protected Bitmap(IBitmapImpl impl)
{ {
this.PlatformImpl = impl; this.PlatformImpl = impl;
} }
/// <summary>
/// Gets the width of the bitmap, in pixels.
/// </summary>
public int PixelWidth public int PixelWidth
{ {
get { return this.PlatformImpl.PixelWidth; } get { return this.PlatformImpl.PixelWidth; }
} }
/// <summary>
/// Gets the height of the bitmap, in pixels.
/// </summary>
public int PixelHeight public int PixelHeight
{ {
get { return this.PlatformImpl.PixelHeight; } get { return this.PlatformImpl.PixelHeight; }
} }
/// <summary>
/// Gets the platform-specific bitmap implementation.
/// </summary>
public IBitmapImpl PlatformImpl public IBitmapImpl PlatformImpl
{ {
get; get;
private set; private set;
} }
/// <summary>
/// Saves the bitmap to a file.
/// </summary>
/// <param name="fileName">The filename.</param>
public void Save(string fileName) public void Save(string fileName)
{ {
this.PlatformImpl.Save(fileName); this.PlatformImpl.Save(fileName);

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

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

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

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="RenderTargetBitmap.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -10,28 +10,55 @@ namespace Perspex.Media.Imaging
using Perspex.Platform; using Perspex.Platform;
using Splat; using Splat;
/// <summary>
/// A bitmap that holds the rendering of a <see cref="IVisual"/>.
/// </summary>
public class RenderTargetBitmap : Bitmap, IDisposable 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) public RenderTargetBitmap(int width, int height)
: base(CreateImpl(width, height)) : base(CreateImpl(width, height))
{ {
} }
/// <summary>
/// Gets the platform-specific bitmap implementation.
/// </summary>
public new IRenderTargetBitmapImpl PlatformImpl public new IRenderTargetBitmapImpl PlatformImpl
{ {
get { return (IRenderTargetBitmapImpl)base.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) public void Render(IVisual visual)
{ {
this.PlatformImpl.Render(visual); this.PlatformImpl.Render(visual);
} }
/// <summary>
/// Disposes of the bitmap.
/// </summary>
public void Dispose() public void Dispose()
{ {
this.PlatformImpl.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) private static IBitmapImpl CreateImpl(int width, int height)
{ {
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();

21
Perspex.SceneGraph/Media/MatrixTransform.cs

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

15
Perspex.SceneGraph/Media/PathMarkupParser.cs

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

23
Perspex.SceneGraph/Media/RotateTransform.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="RotateTransform.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -8,31 +8,50 @@ namespace Perspex.Media
{ {
using System; using System;
/// <summary>
/// Rotates an <see cref="IVisual"/>.
/// </summary>
public class RotateTransform : Transform public class RotateTransform : Transform
{ {
/// <summary>
/// Defines the <see cref="Angle"/> property.
/// </summary>
public static readonly PerspexProperty<double> AngleProperty = public static readonly PerspexProperty<double> AngleProperty =
PerspexProperty.Register<RotateTransform, double>("Angle"); PerspexProperty.Register<RotateTransform, double>("Angle");
/// <summary>
/// Initializes a new instance of the <see cref="RotateTransform"/> class.
/// </summary>
public RotateTransform() public RotateTransform()
{ {
this.GetObservable(AngleProperty).Subscribe(_ => this.RaiseChanged()); 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) public RotateTransform(double angle)
: this() : this()
{ {
this.Angle = angle; this.Angle = angle;
} }
/// <summary>
/// Gets or sets the angle of rotation, in degrees.
/// </summary>
public double Angle public double Angle
{ {
get { return this.GetValue(AngleProperty); } get { return this.GetValue(AngleProperty); }
set { this.SetValue(AngleProperty, value); } set { this.SetValue(AngleProperty, value); }
} }
/// <summary>
/// Gets the tranform's <see cref="Matrix"/>.
/// </summary>
public override Matrix Value 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; private set;
} }
/// <summary>
/// Returns a string representation of the brush.
/// </summary>
/// <returns>A string representation of the brush.</returns>
public override string ToString() public override string ToString()
{ {
return this.Color.ToString(); return this.Color.ToString();

22
Perspex.SceneGraph/Media/Stretch.cs

@ -6,11 +6,33 @@
namespace Perspex.Media namespace Perspex.Media
{ {
/// <summary>
/// Describes how content is resized to fill its allocated space.
/// </summary>
public enum Stretch public enum Stretch
{ {
/// <summary>
/// The content preserves its original size.
/// </summary>
None, None,
/// <summary>
/// The content is resized to fill the destination dimensions. The aspect ratio is not
/// preserved.
/// </summary>
Fill, Fill,
/// <summary>
/// The content is resized to fit in the destination dimensions while preserving its
/// native aspect ratio.
/// </summary>
Uniform, 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, UniformToFill,
} }
} }

12
Perspex.SceneGraph/Media/SweepDirection.cs

@ -1,14 +1,24 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="SweepDirection.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Media namespace Perspex.Media
{ {
/// <summary>
/// Defines the direction an which elliptical arc is drawn.
/// </summary>
public enum SweepDirection public enum SweepDirection
{ {
/// <summary>
/// Specifies that arcs are drawn in a counter clockwise (negative-angle) direction.
/// </summary>
CounterClockwise, CounterClockwise,
/// <summary>
/// Specifies that arcs are drawn in a clockwise (positive-angle) direction.
/// </summary>
Clockwise, Clockwise,
} }
} }

16
Perspex.SceneGraph/Media/TextAlignment.cs

@ -1,15 +1,29 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="TextAlignment.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Media namespace Perspex.Media
{ {
/// <summary>
/// Defines how text is aligned.
/// </summary>
public enum TextAlignment public enum TextAlignment
{ {
/// <summary>
/// The text is left-aligned.
/// </summary>
Left, Left,
/// <summary>
/// The text is centered.
/// </summary>
Center, Center,
/// <summary>
/// The text is right-aligned.
/// </summary>
Right, Right,
} }
} }

14
Perspex.SceneGraph/Media/TextHitTestResult.cs

@ -1,17 +1,29 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="TextHitTestResult.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Media namespace Perspex.Media
{ {
/// <summary>
/// Holds a hit test result from a <see cref="FormattedText"/>.
/// </summary>
public class TextHitTestResult 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; } public bool IsInside { get; set; }
/// <summary>
/// Gets the index of the hit character in the text.
/// </summary>
public int TextPosition { get; set; } 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; } public bool IsTrailing { get; set; }
} }
} }

12
Perspex.SceneGraph/Media/Transform.cs

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

28
Perspex.SceneGraph/Media/TranslateTransform.cs

@ -8,20 +8,37 @@ namespace Perspex.Media
{ {
using System; using System;
/// <summary>
/// Translates (moves) an <see cref="IVisual"/>.
/// </summary>
public class TranslateTransform : Transform public class TranslateTransform : Transform
{ {
/// <summary>
/// Defines the <see cref="X"/> property.
/// </summary>
public static readonly PerspexProperty<double> XProperty = public static readonly PerspexProperty<double> XProperty =
PerspexProperty.Register<TranslateTransform, double>("X"); PerspexProperty.Register<TranslateTransform, double>("X");
/// <summary>
/// Defines the <see cref="Y"/> property.
/// </summary>
public static readonly PerspexProperty<double> YProperty = public static readonly PerspexProperty<double> YProperty =
PerspexProperty.Register<TranslateTransform, double>("Y"); PerspexProperty.Register<TranslateTransform, double>("Y");
/// <summary>
/// Initializes a new instance of the <see cref="TranslateTransform"/> class.
/// </summary>
public TranslateTransform() public TranslateTransform()
{ {
this.GetObservable(XProperty).Subscribe(_ => this.RaiseChanged()); this.GetObservable(XProperty).Subscribe(_ => this.RaiseChanged());
this.GetObservable(YProperty).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) public TranslateTransform(double x, double y)
: this() : this()
{ {
@ -29,21 +46,30 @@ namespace Perspex.Media
this.Y = y; this.Y = y;
} }
/// <summary>
/// Gets the horizontal offset of the translate.
/// </summary>
public double X public double X
{ {
get { return this.GetValue(XProperty); } get { return this.GetValue(XProperty); }
set { this.SetValue(XProperty, value); } set { this.SetValue(XProperty, value); }
} }
/// <summary>
/// Gets the vertical offset of the translate.
/// </summary>
public double Y public double Y
{ {
get { return this.GetValue(YProperty); } get { return this.GetValue(YProperty); }
set { this.SetValue(YProperty, value); } set { this.SetValue(YProperty, value); }
} }
/// <summary>
/// Gets the tranform's <see cref="Matrix"/>.
/// </summary>
public override Matrix Value 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 namespace Perspex
{ {
using System; /// <summary>
using System.Globalization; /// Defines the reference point units of an <see cref="Origin"/>.
/// </summary>
public enum OriginUnit public enum OriginUnit
{ {
/// <summary>
/// The origin's point is a percentage.
/// </summary>
Percent, Percent,
/// <summary>
/// The origin's point is in pixels.
/// </summary>
Pixels, Pixels,
} }
/// <summary>
/// Defines an origin for a <see cref="Perspex.Media.Transform"/>.
/// </summary>
public struct Origin 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); public static readonly Origin Default = new Origin(0.5, 0.5, OriginUnit.Percent);
private Point point; private Point point;
private OriginUnit unit; 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) public Origin(double x, double y, OriginUnit unit)
: this(new Point(x, y), 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) public Origin(Point point, OriginUnit unit)
{ {
this.point = point; this.point = point;
this.unit = unit; this.unit = unit;
} }
/// <summary>
/// Gets the origin point.
/// </summary>
public Point Point public Point Point
{ {
get { return this.point; } get { return this.point; }
} }
/// <summary>
/// Gets the origin unit.
/// </summary>
public OriginUnit Unit public OriginUnit Unit
{ {
get { return this.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) public Point ToPixels(Size size)
{ {
return this.unit == OriginUnit.Pixels ? return this.unit == OriginUnit.Pixels ?

2
Perspex.SceneGraph/Perspex.SceneGraph.csproj

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

13
Perspex.SceneGraph/Platform/IBitmapImpl.cs

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

46
Perspex.SceneGraph/Platform/IFormattedTextImpl.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="IFormattedTextImpl.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -10,20 +10,60 @@ namespace Perspex.Platform
using System.Collections.Generic; using System.Collections.Generic;
using Perspex.Media; using Perspex.Media;
/// <summary>
/// Defines the platform-specific interface for <see cref="FormattedText"/>.
/// </summary>
public interface IFormattedTextImpl : IDisposable public interface IFormattedTextImpl : IDisposable
{ {
/// <summary>
/// Gets or sets the constraint of the text.
/// </summary>
Size Constraint { get; set; } Size Constraint { get; set; }
/// <summary>
/// Gets the lines in the text.
/// </summary>
/// <returns>
/// A collection of <see cref="FormattedTextLine"/> objects.
/// </returns>
IEnumerable<FormattedTextLine> GetLines(); 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); 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); 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(); 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 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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Platform namespace Perspex.Platform
{ {
/// <summary>
/// Defines the platform-specific interface for <see cref="Perspex.Media.Geometry"/>.
/// </summary>
public interface IGeometryImpl public interface IGeometryImpl
{ {
/// <summary>
/// Gets the geometry's bounding rectangle.
/// </summary>
Rect Bounds { get; } Rect Bounds { get; }
/// <summary>
/// Gets or sets a transform to apply to the geometry.
/// </summary>
Matrix Transform { get; set; } 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); Rect GetRenderBounds(double strokeThickness);
} }
} }

45
Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="IPlatformRenderInterface.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -8,24 +8,65 @@ namespace Perspex.Platform
{ {
using Perspex.Media; using Perspex.Media;
/// <summary>
/// Defines the main platform-specific interface for the rendering subsystem.
/// </summary>
public interface IPlatformRenderInterface 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); 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( IFormattedTextImpl CreateFormattedText(
string text, string text,
string fontFamily, string fontFamilyName,
double fontSize, double fontSize,
FontStyle fontStyle, FontStyle fontStyle,
TextAlignment textAlignment, TextAlignment textAlignment,
FontWeight fontWeight); FontWeight fontWeight);
/// <summary>
/// Creates a stream geometry implementation.
/// </summary>
/// <returns>An <see cref="IStreamGeometryImpl"/>.</returns>
IStreamGeometryImpl CreateStreamGeometry(); 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); 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); 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); IBitmapImpl LoadBitmap(string fileName);
} }
} }

13
Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="IRenderTargetBitmapImpl.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -8,8 +8,19 @@ namespace Perspex.Platform
{ {
using System; using System;
/// <summary>
/// Defines the platform-specific interface for a
/// <see cref="Perspex.Media.Imaging.RenderTargetBitmap"/>.
/// </summary>
public interface IRenderTargetBitmapImpl : IBitmapImpl, IDisposable 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); void Render(IVisual visual);
} }
} }

13
Perspex.SceneGraph/Platform/IRenderer.cs

@ -1,13 +1,20 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="IRenderer.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Platform 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 public interface IRenderer
{ {
/// <summary> /// <summary>

15
Perspex.SceneGraph/Platform/IStreamGeometryImpl.cs

@ -1,15 +1,28 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="IStreamGeometryImpl.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
namespace Perspex.Platform namespace Perspex.Platform
{ {
/// <summary>
/// Defines the platform-specific interface for a <see cref="Perspex.Media.StreamGeometry"/>.
/// </summary>
public interface IStreamGeometryImpl : IGeometryImpl public interface IStreamGeometryImpl : IGeometryImpl
{ {
/// <summary>
/// Clones the geometry.
/// </summary>
/// <returns>A cloned geometry.</returns>
IStreamGeometryImpl Clone(); 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(); IStreamGeometryContextImpl Open();
} }
} }

4
Perspex.SceneGraph/Point.cs

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

39
Perspex.SceneGraph/Rect.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="Rect.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -221,6 +221,12 @@ namespace Perspex
return !(left == right); 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) public static Rect operator *(Rect rect, Vector scale)
{ {
double centerX = rect.x + (rect.width / 2); double centerX = rect.x + (rect.width / 2);
@ -234,11 +240,23 @@ namespace Perspex
height); 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) public static Rect operator *(Rect rect, Matrix matrix)
{ {
return new Rect(rect.TopLeft * matrix, rect.BottomRight * 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) public static Rect operator /(Rect rect, Vector scale)
{ {
double centerX = rect.x + (rect.width / 2); double centerX = rect.x + (rect.width / 2);
@ -263,6 +281,11 @@ namespace Perspex
p.Y >= this.y && p.Y < this.y + this.height; 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) public Rect CenterIn(Rect rect)
{ {
return new Rect( return new Rect(
@ -318,6 +341,11 @@ namespace Perspex
this.Size.Deflate(thickness)); 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) public override bool Equals(object obj)
{ {
if (obj is Rect) if (obj is Rect)
@ -328,6 +356,10 @@ namespace Perspex
return false; return false;
} }
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode() public override int GetHashCode()
{ {
unchecked 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) public Rect Intersect(Rect rect)
{ {
double x = Math.Max(this.x, rect.x); 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 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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -9,12 +9,25 @@ namespace Perspex.Rendering
using System; using System;
using System.Reactive; using System.Reactive;
/// <summary>
/// Defines the interface for a <see cref="RenderManager"/>.
/// </summary>
public interface IRenderManager public interface IRenderManager
{ {
/// <summary>
/// Gets an observable that is fired whenever a render is required.
/// </summary>
IObservable<Unit> RenderNeeded { get; } 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); void InvalidateRender(IVisual visual);
/// <summary>
/// Called when rendering is finished.
/// </summary>
void RenderFinished(); void RenderFinished();
} }
} }

16
Perspex.SceneGraph/Rendering/IRenderRoot.cs

@ -1,6 +1,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// <copyright file="IRenderRoot.cs" company="Steven Kirk"> // <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> // </copyright>
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -8,12 +8,26 @@ namespace Perspex.Rendering
{ {
using Perspex.Platform; using Perspex.Platform;
/// <summary>
/// Represents the root of a renderable tree.
/// </summary>
public interface IRenderRoot public interface IRenderRoot
{ {
/// <summary>
/// Gets the renderer for the tree.
/// </summary>
IRenderer Renderer { get; } IRenderer Renderer { get; }
/// <summary>
/// Gets the render manager which schedules renders.
/// </summary>
IRenderManager RenderManager { get; } 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); Point TranslatePointToScreen(Point p);
} }
} }

16
Perspex.SceneGraph/Rendering/RenderManager.cs

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

6
Perspex.SceneGraph/Rendering/RendererBase.cs

@ -71,16 +71,16 @@ namespace Perspex.Rendering
if (visual.IsVisible && opacity > 0) if (visual.IsVisible && opacity > 0)
{ {
// Translate any existing transform into this controls coordinate system. // 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; transform = offset * transform * -offset;
// Update the current 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. // Apply the control's render transform, if any.
if (visual.RenderTransform != null) 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; transform *= -offset * visual.RenderTransform.Value * offset;
} }

2
Perspex.SceneGraph/Size.cs

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

18
Perspex.SceneGraph/Thickness.cs

@ -8,6 +8,9 @@ namespace Perspex
{ {
using System; using System;
/// <summary>
/// Describes the thickness of a frame around a rectangle.
/// </summary>
public struct Thickness public struct Thickness
{ {
/// <summary> /// <summary>
@ -152,6 +155,13 @@ namespace Perspex
a.Bottom + b.Bottom); 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) public override bool Equals(object obj)
{ {
if (obj is Thickness) if (obj is Thickness)
@ -166,6 +176,10 @@ namespace Perspex
return false; return false;
} }
/// <summary>
/// Returns a hash code for a <see cref="Thickness"/>.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode() public override int GetHashCode()
{ {
unchecked 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() public override string ToString()
{ {
return string.Format("{0},{1},{2},{3}", this.left, this.top, this.right, this.bottom); 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 thisOffset = GetOffsetFromRoot(this).Item2;
var thatOffset = GetOffsetFromRoot(visual).Item2; var thatOffset = GetOffsetFromRoot(visual).Item2;
return Matrix.Translation(-thatOffset) * Matrix.Translation(thisOffset); return Matrix.CreateTranslation(-thatOffset) * Matrix.CreateTranslation(thisOffset);
} }
/// <summary> /// <summary>

71
Perspex.SceneGraph/VisualTree/VisualExtensions.cs

@ -10,8 +10,16 @@ namespace Perspex.VisualTree
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
/// <summary>
/// Provides extension methods for working with visual tree.
/// </summary>
public static class VisualExtensions 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) public static IEnumerable<IVisual> GetVisualAncestors(this IVisual visual)
{ {
Contract.Requires<NullReferenceException>(visual != null); 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) public static IEnumerable<IVisual> GetSelfAndVisualAncestors(this IVisual visual)
{ {
yield return 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) public static IVisual GetVisualAt(this IVisual visual, Point p)
{ {
Contract.Requires<NullReferenceException>(visual != null); Contract.Requires<NullReferenceException>(visual != null);
@ -42,6 +61,12 @@ namespace Perspex.VisualTree
return visual.GetVisualsAt(p).FirstOrDefault(); 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) public static IEnumerable<IVisual> GetVisualsAt(this IVisual visual, Point p)
{ {
Contract.Requires<NullReferenceException>(visual != null); 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) public static IEnumerable<IVisual> GetVisualChildren(this IVisual visual)
{ {
return visual.VisualChildren; 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) public static IEnumerable<IVisual> GetVisualDescendents(this IVisual visual)
{ {
foreach (IVisual child in visual.VisualChildren) 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) public static IEnumerable<IVisual> GetSelfAndVisualDescendents(this IVisual visual)
{ {
yield return 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) public static IVisual GetVisualParent(this IVisual visual)
{ {
return visual.VisualParent; 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 public static T GetVisualParent<T>(this IVisual visual) where T : class
{ {
return visual.VisualParent as T; 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) public static IVisual GetVisualRoot(this IVisual visual)
{ {
Contract.Requires<NullReferenceException>(visual != null); Contract.Requires<NullReferenceException>(visual != null);
@ -118,7 +178,16 @@ namespace Perspex.VisualTree
return visual; 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); 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); 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( var result = this.TextLayout.HitTestTextRange(index, length, 0, 0);
index,
length,
(float)origin.X,
(float)origin.Y);
return result.Select(x => new Rect(x.Left, x.Top, x.Width, x.Height)); 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.M12,
(float)matrix.M21, (float)matrix.M21,
(float)matrix.M22, (float)matrix.M22,
(float)matrix.OffsetX, (float)matrix.M31,
(float)matrix.OffsetY); (float)matrix.M32);
} }
/// <summary> /// <summary>

Loading…
Cancel
Save