From c047b1cab87d5da34628d90171f09a37162ad93d Mon Sep 17 00:00:00 2001 From: Jeremy Kuhne Date: Mon, 9 Dec 2024 20:07:24 -0800 Subject: [PATCH 1/2] Collapse Rect code to a single struct This allows making the fields private, which will allow making relevant members readonly for perf. --- .../Media/BoundsDrawingContextWalker.cs | 4 +- .../System/Windows/Media/MatrixTransform.cs | 4 +- .../System/Windows/Media/Transform.cs | 4 +- .../System/Windows/Media/Visual.cs | 6 +- .../Windows/Media3D/Viewport3DVisual.cs | 4 +- .../src/Shared/MS/Internal/MatrixUtil.cs | 74 +-- .../System/Windows/Generated/Rect.cs | 364 --------------- .../src/WindowsBase/System/Windows/Rect.cs | 422 +++++++++++++++--- .../src/WindowsBase/WindowsBase.csproj | 1 - 9 files changed, 365 insertions(+), 518 deletions(-) delete mode 100644 src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Generated/Rect.cs diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/BoundsDrawingContextWalker.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/BoundsDrawingContextWalker.cs index 2d2b0e6aae3..bd1c6840677 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/BoundsDrawingContextWalker.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/BoundsDrawingContextWalker.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -565,7 +565,7 @@ private void AddBounds(ref Rect bounds) // So, we need to transform the Rect to world to bound it if (!_transform.IsIdentity) { - MatrixUtil.TransformRect(ref bounds, ref _transform); + Rect.TransformRect(ref bounds, ref _transform); } AddTransformedBounds(ref bounds); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MatrixTransform.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MatrixTransform.cs index 0847b9394fc..b2c4d308c22 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MatrixTransform.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MatrixTransform.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -104,7 +104,7 @@ internal override string ConvertToString(string format, IFormatProvider provider internal override void TransformRect(ref Rect rect) { Matrix matrix = Matrix; - MatrixUtil.TransformRect(ref rect, ref matrix); + Rect.TransformRect(ref rect, ref matrix); } internal override void MultiplyValueByMatrix(ref Matrix result, ref Matrix matrixToMultiplyBy) diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Transform.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Transform.cs index a6661882051..2525d30fbef 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Transform.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Transform.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -66,7 +66,7 @@ private static Transform MakeIdentityTransform() internal virtual void TransformRect(ref Rect rect) { Matrix matrix = Value; - MatrixUtil.TransformRect(ref rect, ref matrix); + Rect.TransformRect(ref rect, ref matrix); } /// diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs index 280aee3e258..793b70b84d3 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -577,7 +577,7 @@ private Rect CalculateSubgraphBoundsOuterSpace(bool renderBounds) if ((transform != null) && (!transform.IsIdentity)) { Matrix m = transform.Value; - MatrixUtil.TransformRect(ref bboxSubgraph, ref m); + Rect.TransformRect(ref bboxSubgraph, ref m); } // Apply Offset. @@ -1109,7 +1109,7 @@ internal void PrecomputeRecursive(out Rect bboxSubgraph) if ((transform != null) && (!transform.IsIdentity)) { Matrix m = transform.Value; - MatrixUtil.TransformRect(ref bboxSubgraph, ref m); + Rect.TransformRect(ref bboxSubgraph, ref m); } if (!bboxSubgraph.IsEmpty) diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Viewport3DVisual.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Viewport3DVisual.cs index 51ca2ee4653..e3bd7f472a6 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Viewport3DVisual.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Viewport3DVisual.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -577,7 +577,7 @@ internal override Rect CalculateSubgraphBoundsInnerSpace(bool renderBounds) Matrix3D viewProjMatrix = camera.GetViewMatrix() * camera.GetProjectionMatrix(aspectRatio); Rect projectedBounds2D = MILUtilities.ProjectBounds(ref viewProjMatrix, ref _bboxChildrenSubgraph3D); Matrix homoToLocal = M3DUtil.GetHomogeneousToViewportTransform(viewport); - MatrixUtil.TransformRect(ref projectedBounds2D, ref homoToLocal); + Rect.TransformRect(ref projectedBounds2D, ref homoToLocal); return projectedBounds2D; } diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/MatrixUtil.cs b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/MatrixUtil.cs index 00e53c80fad..a9781e2112a 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/MatrixUtil.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/MatrixUtil.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -22,78 +22,6 @@ internal enum MatrixTypes internal static class MatrixUtil { - /// - /// TransformRect - Internal helper for perf - /// - /// The Rect to transform. - /// The Matrix with which to transform the Rect. - internal static void TransformRect(ref Rect rect, ref Matrix matrix) - { - if (rect.IsEmpty) - { - return; - } - - MatrixTypes matrixType = matrix._type; - - // If the matrix is identity, don't worry. - if (matrixType == MatrixTypes.TRANSFORM_IS_IDENTITY) - { - return; - } - - // Scaling - if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_SCALING)) - { - rect._x *= matrix._m11; - rect._y *= matrix._m22; - rect._width *= matrix._m11; - rect._height *= matrix._m22; - - // Ensure the width is always positive. For example, if there was a reflection about the - // y axis followed by a translation into the visual area, the width could be negative. - if (rect._width < 0.0) - { - rect._x += rect._width; - rect._width = -rect._width; - } - - // Ensure the height is always positive. For example, if there was a reflection about the - // x axis followed by a translation into the visual area, the height could be negative. - if (rect._height < 0.0) - { - rect._y += rect._height; - rect._height = -rect._height; - } - } - - // Translation - if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_TRANSLATION)) - { - // X - rect._x += matrix._offsetX; - - // Y - rect._y += matrix._offsetY; - } - - if (matrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) - { - // Al Bunny implementation. - Point point0 = matrix.Transform(rect.TopLeft); - Point point1 = matrix.Transform(rect.TopRight); - Point point2 = matrix.Transform(rect.BottomRight); - Point point3 = matrix.Transform(rect.BottomLeft); - - // Width and height is always positive here. - rect._x = Math.Min(Math.Min(point0.X, point1.X), Math.Min(point2.X, point3.X)); - rect._y = Math.Min(Math.Min(point0.Y, point1.Y), Math.Min(point2.Y, point3.Y)); - - rect._width = Math.Max(Math.Max(point0.X, point1.X), Math.Max(point2.X, point3.X)) - rect._x; - rect._height = Math.Max(Math.Max(point0.Y, point1.Y), Math.Max(point2.Y, point3.Y)) - rect._y; - } - } - /// /// Multiplies two transformations, where the behavior is matrix1 *= matrix2. /// This code exists so that we can efficient combine matrices without copying diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Generated/Rect.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Generated/Rect.cs deleted file mode 100644 index 81c7a5849ab..00000000000 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Generated/Rect.cs +++ /dev/null @@ -1,364 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// -// -// This file was generated, please do not edit it directly. -// -// Please see MilCodeGen.html for more information. -// - -using MS.Internal; -using System.ComponentModel; -using System.Windows.Markup; -using System.Windows.Converters; -// These types are aliased to match the unamanaged names used in interop - -namespace System.Windows -{ - [Serializable] - [TypeConverter(typeof(RectConverter))] - [ValueSerializer(typeof(RectValueSerializer))] // Used by MarkupWriter - partial struct Rect : IFormattable - { - //------------------------------------------------------ - // - // Public Methods - // - //------------------------------------------------------ - - #region Public Methods - - - - - /// - /// Compares two Rect instances for exact equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which are logically equal may fail. - /// Furthermore, using this equality operator, Double.NaN is not equal to itself. - /// - /// - /// bool - true if the two Rect instances are exactly equal, false otherwise - /// - /// The first Rect to compare - /// The second Rect to compare - public static bool operator == (Rect rect1, Rect rect2) - { - return rect1.X == rect2.X && - rect1.Y == rect2.Y && - rect1.Width == rect2.Width && - rect1.Height == rect2.Height; - } - - /// - /// Compares two Rect instances for exact inequality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which are logically equal may fail. - /// Furthermore, using this equality operator, Double.NaN is not equal to itself. - /// - /// - /// bool - true if the two Rect instances are exactly unequal, false otherwise - /// - /// The first Rect to compare - /// The second Rect to compare - public static bool operator != (Rect rect1, Rect rect2) - { - return !(rect1 == rect2); - } - /// - /// Compares two Rect instances for object equality. In this equality - /// Double.NaN is equal to itself, unlike in numeric equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which - /// are logically equal may fail. - /// - /// - /// bool - true if the two Rect instances are exactly equal, false otherwise - /// - /// The first Rect to compare - /// The second Rect to compare - public static bool Equals (Rect rect1, Rect rect2) - { - if (rect1.IsEmpty) - { - return rect2.IsEmpty; - } - else - { - return rect1.X.Equals(rect2.X) && - rect1.Y.Equals(rect2.Y) && - rect1.Width.Equals(rect2.Width) && - rect1.Height.Equals(rect2.Height); - } - } - - /// - /// Equals - compares this Rect with the passed in object. In this equality - /// Double.NaN is equal to itself, unlike in numeric equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which - /// are logically equal may fail. - /// - /// - /// bool - true if the object is an instance of Rect and if it's equal to "this". - /// - /// The object to compare to "this" - public override bool Equals(object o) - { - if ((null == o) || !(o is Rect)) - { - return false; - } - - Rect value = (Rect)o; - return Rect.Equals(this,value); - } - - /// - /// Equals - compares this Rect with the passed in object. In this equality - /// Double.NaN is equal to itself, unlike in numeric equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which - /// are logically equal may fail. - /// - /// - /// bool - true if "value" is equal to "this". - /// - /// The Rect to compare to "this" - public bool Equals(Rect value) - { - return Rect.Equals(this, value); - } - /// - /// Returns the HashCode for this Rect - /// - /// - /// int - the HashCode for this Rect - /// - public override int GetHashCode() - { - if (IsEmpty) - { - return 0; - } - else - { - // Perform field-by-field XOR of HashCodes - return X.GetHashCode() ^ - Y.GetHashCode() ^ - Width.GetHashCode() ^ - Height.GetHashCode(); - } - } - - /// - /// Parse - returns an instance converted from the provided string using - /// the culture "en-US" - /// string with Rect data - /// - public static Rect Parse(string source) - { - IFormatProvider formatProvider = System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS; - - TokenizerHelper th = new TokenizerHelper(source, formatProvider); - - Rect value; - - String firstToken = th.NextTokenRequired(); - - // The token will already have had whitespace trimmed so we can do a - // simple string compare. - if (firstToken == "Empty") - { - value = Empty; - } - else - { - value = new Rect( - Convert.ToDouble(firstToken, formatProvider), - Convert.ToDouble(th.NextTokenRequired(), formatProvider), - Convert.ToDouble(th.NextTokenRequired(), formatProvider), - Convert.ToDouble(th.NextTokenRequired(), formatProvider)); - } - - // There should be no more tokens in this string. - th.LastTokenRequired(); - - return value; - } - - #endregion Public Methods - - //------------------------------------------------------ - // - // Public Properties - // - //------------------------------------------------------ - - - - - #region Public Properties - - - - #endregion Public Properties - - //------------------------------------------------------ - // - // Protected Methods - // - //------------------------------------------------------ - - #region Protected Methods - - - - - - #endregion ProtectedMethods - - //------------------------------------------------------ - // - // Internal Methods - // - //------------------------------------------------------ - - #region Internal Methods - - - - - - - - - - #endregion Internal Methods - - //------------------------------------------------------ - // - // Internal Properties - // - //------------------------------------------------------ - - #region Internal Properties - - - /// - /// Creates a string representation of this object based on the current culture. - /// - /// - /// A string representation of this object. - /// - public override string ToString() - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(null /* format string */, null /* format provider */); - } - - /// - /// Creates a string representation of this object based on the IFormatProvider - /// passed in. If the provider is null, the CurrentCulture is used. - /// - /// - /// A string representation of this object. - /// - public string ToString(IFormatProvider provider) - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(null /* format string */, provider); - } - - /// - /// Creates a string representation of this object based on the format string - /// and IFormatProvider passed in. - /// If the provider is null, the CurrentCulture is used. - /// See the documentation for IFormattable for more information. - /// - /// - /// A string representation of this object. - /// - string IFormattable.ToString(string format, IFormatProvider provider) - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(format, provider); - } - - /// - /// Creates a string representation of this object based on the format string - /// and IFormatProvider passed in. - /// If the provider is null, the CurrentCulture is used. - /// See the documentation for IFormattable for more information. - /// - /// - /// A string representation of this object. - /// - internal string ConvertToString(string format, IFormatProvider provider) - { - if (IsEmpty) - { - return "Empty"; - } - - // Helper to get the numeric list separator for a given culture. - char separator = MS.Internal.TokenizerHelper.GetNumericListSeparator(provider); - return String.Format(provider, - "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}", - separator, - _x, - _y, - _width, - _height); - } - - - - #endregion Internal Properties - - //------------------------------------------------------ - // - // Dependency Properties - // - //------------------------------------------------------ - - #region Dependency Properties - - - - #endregion Dependency Properties - - //------------------------------------------------------ - // - // Internal Fields - // - //------------------------------------------------------ - - #region Internal Fields - - - internal double _x; - internal double _y; - internal double _width; - internal double _height; - - #endregion Internal Fields - - - - #region Constructors - - //------------------------------------------------------ - // - // Constructors - // - //------------------------------------------------------ - - - - - #endregion Constructors - } -} diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs index 78a84564b94..7e85ec40996 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs @@ -1,9 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. using MS.Internal; using System.Windows.Media; +using System.ComponentModel; +using System.Windows.Markup; +using System.Windows.Converters; namespace System.Windows { @@ -12,9 +14,15 @@ namespace System.Windows /// X, Y (Location) and Width and Height (Size). As a result, Rects cannot have negative /// Width or Height. /// - public partial struct Rect + [Serializable] + [TypeConverter(typeof(RectConverter))] + [ValueSerializer(typeof(RectValueSerializer))] // Used by MarkupWriter + public struct Rect : IFormattable { - #region Constructors + private double _x; + private double _y; + private double _width; + private double _height; /// /// Constructor which sets the initial values to the values of the parameters @@ -46,13 +54,13 @@ public Rect(double x, { if (width < 0 || height < 0) { - throw new System.ArgumentException(SR.Size_WidthAndHeightCannotBeNegative); + throw new ArgumentException(SR.Size_WidthAndHeightCannotBeNegative); } - _x = x; - _y = y; - _width = width; - _height = height; + _x = x; + _y = y; + _width = width; + _height = height; } /// @@ -74,7 +82,7 @@ public Rect(Point point1, /// which results from point + vector. /// public Rect(Point point, - Vector vector): this(point, point+vector) + Vector vector) : this(point, point + vector) { } @@ -84,7 +92,7 @@ public Rect(Point point, /// public Rect(Size size) { - if(size.IsEmpty) + if (size.IsEmpty) { this = s_empty; } @@ -96,10 +104,6 @@ public Rect(Size size) } } - #endregion Constructors - - #region Statics - /// /// Empty - a static property which provides an Empty rectangle. X and Y are positive-infinity /// and Width and Height are negative infinity. This is the only situation where Width or @@ -113,10 +117,6 @@ public static Rect Empty } } - #endregion Statics - - #region Public Properties - /// /// IsEmpty - this returns true if this rect is the Empty rectangle. /// Note: If width or height are 0 this Rectangle still contains a 0 or 1 dimensional set @@ -146,9 +146,9 @@ public Point Location { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotModifyEmptyRect); + throw new InvalidOperationException(SR.Rect_CannotModifyEmptyRect); } - + _x = value._x; _y = value._y; } @@ -175,7 +175,7 @@ public Size Size { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotModifyEmptyRect); + throw new InvalidOperationException(SR.Rect_CannotModifyEmptyRect); } _width = value._width; @@ -199,12 +199,12 @@ public double X { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotModifyEmptyRect); + throw new InvalidOperationException(SR.Rect_CannotModifyEmptyRect); } _x = value; } -} + } /// /// Y - The Y coordinate of the Location @@ -221,7 +221,7 @@ public double Y { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotModifyEmptyRect); + throw new InvalidOperationException(SR.Rect_CannotModifyEmptyRect); } _y = value; @@ -243,12 +243,12 @@ public double Width { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotModifyEmptyRect); + throw new InvalidOperationException(SR.Rect_CannotModifyEmptyRect); } - + if (value < 0) { - throw new System.ArgumentException(SR.Size_WidthCannotBeNegative); + throw new ArgumentException(SR.Size_WidthCannotBeNegative); } _width = value; @@ -270,12 +270,12 @@ public double Height { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotModifyEmptyRect); + throw new InvalidOperationException(SR.Rect_CannotModifyEmptyRect); } if (value < 0) { - throw new System.ArgumentException(SR.Size_HeightCannotBeNegative); + throw new ArgumentException(SR.Size_HeightCannotBeNegative); } _height = value; @@ -316,7 +316,7 @@ public double Right { if (IsEmpty) { - return Double.NegativeInfinity; + return double.NegativeInfinity; } return _x + _width; @@ -333,7 +333,7 @@ public double Bottom { if (IsEmpty) { - return Double.NegativeInfinity; + return double.NegativeInfinity; } return _y + _height; @@ -387,9 +387,6 @@ public Point BottomRight return new Point(Right, Bottom); } } - #endregion Public Properties - - #region Public Methods /// /// Contains - Returns true if the Point is within the rectangle, inclusive of the edges. @@ -422,7 +419,7 @@ public bool Contains(double x, double y) return false; } - return ContainsInternal(x,y); + return ContainsInternal(x, y); } /// @@ -439,8 +436,8 @@ public bool Contains(Rect rect) return (_x <= rect._x && _y <= rect._y && - _x+_width >= rect._x+rect._width && - _y+_height >= rect._y+rect._height ); + _x + _width >= rect._x + rect._width && + _y + _height >= rect._y + rect._height); } /// @@ -474,15 +471,15 @@ public bool IntersectsWith(Rect rect) /// The rect to intersect with this public void Intersect(Rect rect) { - if (!this.IntersectsWith(rect)) + if (!IntersectsWith(rect)) { this = Empty; } else { - double left = Math.Max(Left, rect.Left); - double top = Math.Max(Top, rect.Top); - + double left = Math.Max(Left, rect.Left); + double top = Math.Max(Top, rect.Top); + // Max with 0 to prevent double weirdness from causing us to be (-epsilon..0) _width = Math.Max(Math.Min(Right, rect.Right) - left, 0); _height = Math.Max(Math.Min(Bottom, rect.Bottom) - top, 0); @@ -516,23 +513,23 @@ public void Union(Rect rect) double left = Math.Min(Left, rect.Left); double top = Math.Min(Top, rect.Top); - + // We need this check so that the math does not result in NaN - if ((rect.Width == Double.PositiveInfinity) || (Width == Double.PositiveInfinity)) + if ((rect.Width == double.PositiveInfinity) || (Width == double.PositiveInfinity)) { - _width = Double.PositiveInfinity; + _width = double.PositiveInfinity; } else { - // Max with 0 to prevent double weirdness from causing us to be (-epsilon..0) + // Max with 0 to prevent double weirdness from causing us to be (-epsilon..0) double maxRight = Math.Max(Right, rect.Right); _width = Math.Max(maxRight - left, 0); } // We need this check so that the math does not result in NaN - if ((rect.Height == Double.PositiveInfinity) || (Height == Double.PositiveInfinity)) + if ((rect.Height == double.PositiveInfinity) || (Height == double.PositiveInfinity)) { - _height = Double.PositiveInfinity; + _height = double.PositiveInfinity; } else { @@ -580,7 +577,7 @@ public void Offset(Vector offsetVector) { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotCallMethod); + throw new InvalidOperationException(SR.Rect_CannotCallMethod); } _x += offsetVector._x; @@ -595,7 +592,7 @@ public void Offset(double offsetX, double offsetY) { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotCallMethod); + throw new InvalidOperationException(SR.Rect_CannotCallMethod); } _x += offsetX; @@ -640,12 +637,12 @@ public void Inflate(double width, double height) { if (IsEmpty) { - throw new System.InvalidOperationException(SR.Rect_CannotCallMethod); + throw new InvalidOperationException(SR.Rect_CannotCallMethod); } _x -= width; _y -= height; - + // Do two additions rather than multiplication by 2 to avoid spurious overflow // That is: (A + 2 * B) != ((A + B) + B) if 2*B overflows. // Note that multiplication by 2 might work in this case because A should start @@ -659,7 +656,7 @@ public void Inflate(double width, double height) // maintains the invariant that either the Rect is Empty or _width and _height are // non-negative, even if the user parameters were NaN, though this isn't strictly maintained // by other methods. - if ( !(_width >= 0 && _height >= 0) ) + if (!(_width >= 0 && _height >= 0)) { this = s_empty; } @@ -696,19 +693,91 @@ public static Rect Inflate(Rect rect, double width, double height) /// The Matrix by which to transform. public static Rect Transform(Rect rect, Matrix matrix) { - MatrixUtil.TransformRect(ref rect, ref matrix); + TransformRect(ref rect, ref matrix); return rect; } - + /// /// Updates rectangle to be the bounds of the original value transformed /// by the matrix. - /// The Empty Rect is not affected by this call. + /// The Empty Rect is not affected by this call. /// /// Matrix public void Transform(Matrix matrix) { - MatrixUtil.TransformRect(ref this, ref matrix); + TransformRect(ref this, ref matrix); + } + + /// + /// TransformRect - Internal helper for perf + /// + /// The Rect to transform. + /// The Matrix with which to transform the Rect. + internal static void TransformRect(ref Rect rect, ref Matrix matrix) + { + if (rect.IsEmpty) + { + return; + } + + MatrixTypes matrixType = matrix._type; + + // If the matrix is identity, don't worry. + if (matrixType == MatrixTypes.TRANSFORM_IS_IDENTITY) + { + return; + } + + // Scaling + if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_SCALING)) + { + rect._x *= matrix._m11; + rect._y *= matrix._m22; + rect._width *= matrix._m11; + rect._height *= matrix._m22; + + // Ensure the width is always positive. For example, if there was a reflection about the + // y axis followed by a translation into the visual area, the width could be negative. + if (rect._width < 0.0) + { + rect._x += rect._width; + rect._width = -rect._width; + } + + // Ensure the height is always positive. For example, if there was a reflection about the + // x axis followed by a translation into the visual area, the height could be negative. + if (rect._height < 0.0) + { + rect._y += rect._height; + rect._height = -rect._height; + } + } + + // Translation + if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_TRANSLATION)) + { + // X + rect._x += matrix._offsetX; + + // Y + rect._y += matrix._offsetY; + } + + if (matrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) + { + // Al Bunny implementation. + Point point0 = matrix.Transform(rect.TopLeft); + Point point1 = matrix.Transform(rect.TopRight); + Point point2 = matrix.Transform(rect.BottomRight); + Point point3 = matrix.Transform(rect.BottomLeft); + + // Width and height is always positive here. + rect._x = Math.Min(Math.Min(point0.X, point1.X), Math.Min(point2.X, point3.X)); + rect._y = Math.Min(Math.Min(point0.Y, point1.Y), Math.Min(point2.Y, point3.Y)); + + rect._width = Math.Max(Math.Max(point0.X, point1.X), Math.Max(point2.X, point3.X)) - rect._x; + rect._height = Math.Max(Math.Max(point0.Y, point1.Y), Math.Max(point2.Y, point3.Y)) - rect._y; + } } /// @@ -749,10 +818,6 @@ public void Scale(double scaleX, double scaleY) } } - #endregion Public Methods - - #region Private Methods - /// /// ContainsInternal - Performs just the "point inside" logic /// @@ -776,19 +841,238 @@ static private Rect CreateEmptyRect() Rect rect = new Rect(); // We can't set these via the property setters because negatives widths // are rejected in those APIs. - rect._x = Double.PositiveInfinity; - rect._y = Double.PositiveInfinity; - rect._width = Double.NegativeInfinity; - rect._height = Double.NegativeInfinity; + rect._x = double.PositiveInfinity; + rect._y = double.PositiveInfinity; + rect._width = double.NegativeInfinity; + rect._height = double.NegativeInfinity; return rect; } - #endregion Private Methods + private readonly static Rect s_empty = CreateEmptyRect(); - #region Private Fields + /// + /// Compares two Rect instances for exact equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which are logically equal may fail. + /// Furthermore, using this equality operator, Double.NaN is not equal to itself. + /// + /// + /// bool - true if the two Rect instances are exactly equal, false otherwise + /// + /// The first Rect to compare + /// The second Rect to compare + public static bool operator ==(Rect rect1, Rect rect2) + { + return rect1.X == rect2.X && + rect1.Y == rect2.Y && + rect1.Width == rect2.Width && + rect1.Height == rect2.Height; + } - private readonly static Rect s_empty = CreateEmptyRect(); + /// + /// Compares two Rect instances for exact inequality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which are logically equal may fail. + /// Furthermore, using this equality operator, Double.NaN is not equal to itself. + /// + /// + /// bool - true if the two Rect instances are exactly unequal, false otherwise + /// + /// The first Rect to compare + /// The second Rect to compare + public static bool operator !=(Rect rect1, Rect rect2) + { + return !(rect1 == rect2); + } - #endregion Private Fields + /// + /// Compares two Rect instances for object equality. In this equality + /// Double.NaN is equal to itself, unlike in numeric equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which + /// are logically equal may fail. + /// + /// + /// bool - true if the two Rect instances are exactly equal, false otherwise + /// + /// The first Rect to compare + /// The second Rect to compare + public static bool Equals(Rect rect1, Rect rect2) + { + if (rect1.IsEmpty) + { + return rect2.IsEmpty; + } + else + { + return rect1.X.Equals(rect2.X) && + rect1.Y.Equals(rect2.Y) && + rect1.Width.Equals(rect2.Width) && + rect1.Height.Equals(rect2.Height); + } + } + + /// + /// Equals - compares this Rect with the passed in object. In this equality + /// Double.NaN is equal to itself, unlike in numeric equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which + /// are logically equal may fail. + /// + /// + /// bool - true if the object is an instance of Rect and if it's equal to "this". + /// + /// The object to compare to "this" + public override bool Equals(object o) + { + if ((null == o) || !(o is Rect)) + { + return false; + } + + Rect value = (Rect)o; + return Equals(this, value); + } + + /// + /// Equals - compares this Rect with the passed in object. In this equality + /// Double.NaN is equal to itself, unlike in numeric equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which + /// are logically equal may fail. + /// + /// + /// bool - true if "value" is equal to "this". + /// + /// The Rect to compare to "this" + public bool Equals(Rect value) + { + return Equals(this, value); + } + + /// + /// Returns the HashCode for this Rect + /// + /// + /// int - the HashCode for this Rect + /// + public override int GetHashCode() + { + if (IsEmpty) + { + return 0; + } + else + { + // Perform field-by-field XOR of HashCodes + return X.GetHashCode() ^ + Y.GetHashCode() ^ + Width.GetHashCode() ^ + Height.GetHashCode(); + } + } + + /// + /// Parse - returns an instance converted from the provided string using + /// the culture "en-US" + /// string with Rect data + /// + public static Rect Parse(string source) + { + IFormatProvider formatProvider = TypeConverterHelper.InvariantEnglishUS; + + TokenizerHelper th = new TokenizerHelper(source, formatProvider); + + Rect value; + + string firstToken = th.NextTokenRequired(); + + // The token will already have had whitespace trimmed so we can do a + // simple string compare. + if (firstToken == "Empty") + { + value = Empty; + } + else + { + value = new Rect( + Convert.ToDouble(firstToken, formatProvider), + Convert.ToDouble(th.NextTokenRequired(), formatProvider), + Convert.ToDouble(th.NextTokenRequired(), formatProvider), + Convert.ToDouble(th.NextTokenRequired(), formatProvider)); + } + + // There should be no more tokens in this string. + th.LastTokenRequired(); + + return value; + } + + /// + /// Creates a string representation of this object based on the current culture. + /// + /// + /// A string representation of this object. + /// + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + /// + /// Creates a string representation of this object based on the IFormatProvider + /// passed in. If the provider is null, the CurrentCulture is used. + /// + /// + /// A string representation of this object. + /// + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + /// + /// Creates a string representation of this object based on the format string + /// and IFormatProvider passed in. + /// If the provider is null, the CurrentCulture is used. + /// See the documentation for IFormattable for more information. + /// + /// + /// A string representation of this object. + /// + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + /// + /// Creates a string representation of this object based on the format string + /// and IFormatProvider passed in. + /// If the provider is null, the CurrentCulture is used. + /// See the documentation for IFormattable for more information. + /// + /// + /// A string representation of this object. + /// + internal string ConvertToString(string format, IFormatProvider provider) + { + if (IsEmpty) + { + return "Empty"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}", + separator, + _x, + _y, + _width, + _height); + } } } diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj b/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj index 9910284e9b2..11dd6898a18 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj @@ -218,7 +218,6 @@ - From ee3d3a0b50866f2c03ccc9eb534d257c0fba1276 Mon Sep 17 00:00:00 2001 From: Jeremy Kuhne Date: Mon, 9 Dec 2024 20:08:01 -0800 Subject: [PATCH 2/2] Add readonly to appropriate members in Rect. This allows the compiler to generate more optimized code. --- .../src/WindowsBase/System/Windows/Rect.cs | 255 ++++-------------- .../src/WindowsBase/ref/WindowsBase.cs | 52 ++-- 2 files changed, 85 insertions(+), 222 deletions(-) diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs index 7e85ec40996..b5579c213c6 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Rect.cs @@ -24,11 +24,18 @@ public struct Rect : IFormattable private double _width; private double _height; + private static readonly Rect s_empty = new Rect + { + _x = double.PositiveInfinity, + _y = double.PositiveInfinity, + _width = double.NegativeInfinity, + _height = double.NegativeInfinity + }; + /// /// Constructor which sets the initial values to the values of the parameters /// - public Rect(Point location, - Size size) + public Rect(Point location, Size size) { if (size.IsEmpty) { @@ -47,10 +54,7 @@ public Rect(Point location, /// Constructor which sets the initial values to the values of the parameters. /// Width and Height must be non-negative /// - public Rect(double x, - double y, - double width, - double height) + public Rect(double x, double y, double width, double height) { if (width < 0 || height < 0) { @@ -66,8 +70,7 @@ public Rect(double x, /// /// Constructor which sets the initial values to bound the two points provided. /// - public Rect(Point point1, - Point point2) + public Rect(Point point1, Point point2) { _x = Math.Min(point1._x, point2._x); _y = Math.Min(point1._y, point2._y); @@ -81,8 +84,7 @@ public Rect(Point point1, /// Constructor which sets the initial values to bound the point provided and the point /// which results from point + vector. /// - public Rect(Point point, - Vector vector) : this(point, point + vector) + public Rect(Point point, Vector vector) : this(point, point + vector) { } @@ -109,20 +111,14 @@ public Rect(Size size) /// and Width and Height are negative infinity. This is the only situation where Width or /// Height can be negative. /// - public static Rect Empty - { - get - { - return s_empty; - } - } + public static Rect Empty => s_empty; /// /// IsEmpty - this returns true if this rect is the Empty rectangle. /// Note: If width or height are 0 this Rectangle still contains a 0 or 1 dimensional set /// of points, so this method should not be used to check for 0 area. /// - public bool IsEmpty + public readonly bool IsEmpty { get { @@ -138,10 +134,7 @@ public bool IsEmpty /// public Point Location { - get - { - return new Point(_x, _y); - } + readonly get => new Point(_x, _y); set { if (IsEmpty) @@ -159,12 +152,7 @@ public Point Location /// public Size Size { - get - { - if (IsEmpty) - return Size.Empty; - return new Size(_width, _height); - } + readonly get => IsEmpty ? Size.Empty : new(_width, _height); set { if (value.IsEmpty) @@ -191,10 +179,7 @@ public Size Size /// public double X { - get - { - return _x; - } + readonly get => _x; set { if (IsEmpty) @@ -213,10 +198,7 @@ public double X /// public double Y { - get - { - return _y; - } + readonly get => _y; set { if (IsEmpty) @@ -235,10 +217,7 @@ public double Y /// public double Width { - get - { - return _width; - } + readonly get => _width; set { if (IsEmpty) @@ -262,10 +241,7 @@ public double Width /// public double Height { - get - { - return _height; - } + readonly get => _height; set { if (IsEmpty) @@ -286,107 +262,49 @@ public double Height /// Left Property - This is a read-only alias for X /// If this is the empty rectangle, the value will be positive infinity. /// - public double Left - { - get - { - return _x; - } - } + public readonly double Left => _x; /// /// Top Property - This is a read-only alias for Y /// If this is the empty rectangle, the value will be positive infinity. /// - public double Top - { - get - { - return _y; - } - } + public readonly double Top => _y; /// /// Right Property - This is a read-only alias for X + Width /// If this is the empty rectangle, the value will be negative infinity. /// - public double Right - { - get - { - if (IsEmpty) - { - return double.NegativeInfinity; - } - - return _x + _width; - } - } + public readonly double Right => IsEmpty ? double.NegativeInfinity : _x + _width; /// /// Bottom Property - This is a read-only alias for Y + Height /// If this is the empty rectangle, the value will be negative infinity. /// - public double Bottom - { - get - { - if (IsEmpty) - { - return double.NegativeInfinity; - } - - return _y + _height; - } - } + public readonly double Bottom => IsEmpty ? double.NegativeInfinity : _y + _height; /// /// TopLeft Property - This is a read-only alias for the Point which is at X, Y /// If this is the empty rectangle, the value will be positive infinity, positive infinity. /// - public Point TopLeft - { - get - { - return new Point(Left, Top); - } - } + public readonly Point TopLeft => new(Left, Top); /// /// TopRight Property - This is a read-only alias for the Point which is at X + Width, Y /// If this is the empty rectangle, the value will be negative infinity, positive infinity. /// - public Point TopRight - { - get - { - return new Point(Right, Top); - } - } + public readonly Point TopRight => new(Right, Top); /// /// BottomLeft Property - This is a read-only alias for the Point which is at X, Y + Height /// If this is the empty rectangle, the value will be positive infinity, negative infinity. /// - public Point BottomLeft - { - get - { - return new Point(Left, Bottom); - } - } + public readonly Point BottomLeft => new(Left, Bottom); /// /// BottomRight Property - This is a read-only alias for the Point which is at X + Width, Y + Height /// If this is the empty rectangle, the value will be negative infinity, negative infinity. /// - public Point BottomRight - { - get - { - return new Point(Right, Bottom); - } - } + public readonly Point BottomRight => new(Right, Bottom); /// /// Contains - Returns true if the Point is within the rectangle, inclusive of the edges. @@ -397,10 +315,7 @@ public Point BottomRight /// Returns true if the Point is within the rectangle. /// Returns false otherwise /// - public bool Contains(Point point) - { - return Contains(point._x, point._y); - } + public readonly bool Contains(Point point) => Contains(point._x, point._y); /// /// Contains - Returns true if the Point represented by x,y is within the rectangle inclusive of the edges. @@ -412,33 +327,19 @@ public bool Contains(Point point) /// Returns true if the Point represented by x,y is within the rectangle. /// Returns false otherwise. /// - public bool Contains(double x, double y) - { - if (IsEmpty) - { - return false; - } - - return ContainsInternal(x, y); - } + public readonly bool Contains(double x, double y) => !IsEmpty && ContainsInternal(x, y); /// /// Contains - Returns true if the Rect non-Empty and is entirely contained within the /// rectangle, inclusive of the edges. /// Returns false otherwise /// - public bool Contains(Rect rect) - { - if (IsEmpty || rect.IsEmpty) - { - return false; - } - - return (_x <= rect._x && - _y <= rect._y && - _x + _width >= rect._x + rect._width && - _y + _height >= rect._y + rect._height); - } + public readonly bool Contains(Rect rect) => !IsEmpty + && !rect.IsEmpty + && _x <= rect._x + && _y <= rect._y + && _x + _width >= rect._x + rect._width + && _y + _height >= rect._y + rect._height; /// /// IntersectsWith - Returns true if the Rect intersects with this rectangle @@ -451,18 +352,12 @@ public bool Contains(Rect rect) /// or Height /// /// Rect - public bool IntersectsWith(Rect rect) - { - if (IsEmpty || rect.IsEmpty) - { - return false; - } - - return (rect.Left <= Right) && - (rect.Right >= Left) && - (rect.Top <= Bottom) && - (rect.Bottom >= Top); - } + public readonly bool IntersectsWith(Rect rect) => !IsEmpty + && !rect.IsEmpty + && (rect.Left <= Right) + && (rect.Right >= Left) + && (rect.Top <= Bottom) + && (rect.Bottom >= Top); /// /// Intersect - Update this rectangle to be the intersection of this and rect @@ -555,10 +450,7 @@ public static Rect Union(Rect rect1, Rect rect2) /// /// Union - Update this rectangle to be the union of this and point. /// - public void Union(Point point) - { - Union(new Rect(point, point)); - } + public void Union(Point point) => Union(new Rect(point, point)); /// /// Union - Return the result of the union of rect and point. @@ -826,7 +718,7 @@ public void Scale(double scaleX, double scaleY) /// /// The x-coord of the point to test /// The y-coord of the point to test - private bool ContainsInternal(double x, double y) + private readonly bool ContainsInternal(double x, double y) { // We include points on the edge as "contained". // We do "x - _width <= _x" instead of "x <= _x + _width" @@ -836,20 +728,6 @@ private bool ContainsInternal(double x, double y) (y >= _y) && (y - _height <= _y)); } - static private Rect CreateEmptyRect() - { - Rect rect = new Rect(); - // We can't set these via the property setters because negatives widths - // are rejected in those APIs. - rect._x = double.PositiveInfinity; - rect._y = double.PositiveInfinity; - rect._width = double.NegativeInfinity; - rect._height = double.NegativeInfinity; - return rect; - } - - private readonly static Rect s_empty = CreateEmptyRect(); - /// /// Compares two Rect instances for exact equality. /// Note that double values can acquire error when operated upon, such that @@ -923,16 +801,7 @@ public static bool Equals(Rect rect1, Rect rect2) /// bool - true if the object is an instance of Rect and if it's equal to "this". /// /// The object to compare to "this" - public override bool Equals(object o) - { - if ((null == o) || !(o is Rect)) - { - return false; - } - - Rect value = (Rect)o; - return Equals(this, value); - } + public override readonly bool Equals(object o) => o is Rect rect && Equals(this, rect); /// /// Equals - compares this Rect with the passed in object. In this equality @@ -945,10 +814,7 @@ public override bool Equals(object o) /// bool - true if "value" is equal to "this". /// /// The Rect to compare to "this" - public bool Equals(Rect value) - { - return Equals(this, value); - } + public readonly bool Equals(Rect value) => Equals(this, value); /// /// Returns the HashCode for this Rect @@ -956,7 +822,7 @@ public bool Equals(Rect value) /// /// int - the HashCode for this Rect /// - public override int GetHashCode() + public override readonly int GetHashCode() { if (IsEmpty) { @@ -1014,11 +880,7 @@ public static Rect Parse(string source) /// /// A string representation of this object. /// - public override string ToString() - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(null /* format string */, null /* format provider */); - } + public override readonly string ToString() => ConvertToString(format: null, provider: null); /// /// Creates a string representation of this object based on the IFormatProvider @@ -1027,7 +889,7 @@ public override string ToString() /// /// A string representation of this object. /// - public string ToString(IFormatProvider provider) + public readonly string ToString(IFormatProvider provider) { // Delegate to the internal method which implements all ToString calls. return ConvertToString(null /* format string */, provider); @@ -1042,7 +904,7 @@ public string ToString(IFormatProvider provider) /// /// A string representation of this object. /// - string IFormattable.ToString(string format, IFormatProvider provider) + readonly string IFormattable.ToString(string format, IFormatProvider provider) { // Delegate to the internal method which implements all ToString calls. return ConvertToString(format, provider); @@ -1057,7 +919,7 @@ string IFormattable.ToString(string format, IFormatProvider provider) /// /// A string representation of this object. /// - internal string ConvertToString(string format, IFormatProvider provider) + internal readonly string ConvertToString(string format, IFormatProvider provider) { if (IsEmpty) { @@ -1066,13 +928,14 @@ internal string ConvertToString(string format, IFormatProvider provider) // Helper to get the numeric list separator for a given culture. char separator = TokenizerHelper.GetNumericListSeparator(provider); - return string.Format(provider, - "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}", - separator, - _x, - _y, - _width, - _height); + return string.Format( + provider, + $"{{1:{format}}}{{0}}{{2:{format}}}{{0}}{{3:{format}}}{{0}}{{4:{format}}}", + separator, + _x, + _y, + _width, + _height); } } } diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/ref/WindowsBase.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/ref/WindowsBase.cs index 063dcb9925a..3b9bde2e196 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/ref/WindowsBase.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/ref/WindowsBase.cs @@ -1,4 +1,4 @@ -namespace System.Collections.Specialized +namespace System.Collections.Specialized { public partial class CollectionChangedEventManager : System.Windows.WeakEventManager { @@ -947,36 +947,36 @@ public partial struct Rect : System.IFormattable public Rect(System.Windows.Point location, System.Windows.Size size) { throw null; } public Rect(System.Windows.Point point, System.Windows.Vector vector) { throw null; } public Rect(System.Windows.Size size) { throw null; } - public double Bottom { get { throw null; } } - public System.Windows.Point BottomLeft { get { throw null; } } - public System.Windows.Point BottomRight { get { throw null; } } + public readonly double Bottom { get { throw null; } } + public readonly System.Windows.Point BottomLeft { get { throw null; } } + public readonly System.Windows.Point BottomRight { get { throw null; } } public static System.Windows.Rect Empty { get { throw null; } } - public double Height { get { throw null; } set { } } - public bool IsEmpty { get { throw null; } } - public double Left { get { throw null; } } - public System.Windows.Point Location { get { throw null; } set { } } - public double Right { get { throw null; } } - public System.Windows.Size Size { get { throw null; } set { } } - public double Top { get { throw null; } } - public System.Windows.Point TopLeft { get { throw null; } } - public System.Windows.Point TopRight { get { throw null; } } - public double Width { get { throw null; } set { } } - public double X { get { throw null; } set { } } - public double Y { get { throw null; } set { } } - public bool Contains(double x, double y) { throw null; } - public bool Contains(System.Windows.Point point) { throw null; } - public bool Contains(System.Windows.Rect rect) { throw null; } - public override bool Equals(object o) { throw null; } - public bool Equals(System.Windows.Rect value) { throw null; } + public double Height { readonly get { throw null; } set { } } + public readonly bool IsEmpty { get { throw null; } } + public readonly double Left { get { throw null; } } + public System.Windows.Point Location { readonly get { throw null; } set { } } + public readonly double Right { get { throw null; } } + public System.Windows.Size Size { readonly get { throw null; } set { } } + public readonly double Top { get { throw null; } } + public readonly System.Windows.Point TopLeft { get { throw null; } } + public readonly System.Windows.Point TopRight { get { throw null; } } + public double Width { readonly get { throw null; } set { } } + public double X { readonly get { throw null; } set { } } + public double Y { readonly get { throw null; } set { } } + public readonly bool Contains(double x, double y) { throw null; } + public readonly bool Contains(System.Windows.Point point) { throw null; } + public readonly bool Contains(System.Windows.Rect rect) { throw null; } + public override readonly bool Equals(object o) { throw null; } + public readonly bool Equals(System.Windows.Rect value) { throw null; } public static bool Equals(System.Windows.Rect rect1, System.Windows.Rect rect2) { throw null; } - public override int GetHashCode() { throw null; } + public override readonly int GetHashCode() { throw null; } public void Inflate(double width, double height) { } public static System.Windows.Rect Inflate(System.Windows.Rect rect, double width, double height) { throw null; } public static System.Windows.Rect Inflate(System.Windows.Rect rect, System.Windows.Size size) { throw null; } public void Inflate(System.Windows.Size size) { } public void Intersect(System.Windows.Rect rect) { } public static System.Windows.Rect Intersect(System.Windows.Rect rect1, System.Windows.Rect rect2) { throw null; } - public bool IntersectsWith(System.Windows.Rect rect) { throw null; } + public readonly bool IntersectsWith(System.Windows.Rect rect) { throw null; } public void Offset(double offsetX, double offsetY) { } public static System.Windows.Rect Offset(System.Windows.Rect rect, double offsetX, double offsetY) { throw null; } public static System.Windows.Rect Offset(System.Windows.Rect rect, System.Windows.Vector offsetVector) { throw null; } @@ -985,9 +985,9 @@ public void Offset(System.Windows.Vector offsetVector) { } public static bool operator !=(System.Windows.Rect rect1, System.Windows.Rect rect2) { throw null; } public static System.Windows.Rect Parse(string source) { throw null; } public void Scale(double scaleX, double scaleY) { } - string System.IFormattable.ToString(string format, System.IFormatProvider provider) { throw null; } - public override string ToString() { throw null; } - public string ToString(System.IFormatProvider provider) { throw null; } + readonly string System.IFormattable.ToString(string format, System.IFormatProvider provider) { throw null; } + public override readonly string ToString() { throw null; } + public readonly string ToString(System.IFormatProvider provider) { throw null; } public void Transform(System.Windows.Media.Matrix matrix) { } public static System.Windows.Rect Transform(System.Windows.Rect rect, System.Windows.Media.Matrix matrix) { throw null; } public void Union(System.Windows.Point point) { }