diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj b/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj
index 5b9fe95541a..3b8b307afa9 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj
@@ -747,6 +747,7 @@
+
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DoubleCollection.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DoubleCollection.cs
new file mode 100644
index 00000000000..f4a965d79e8
--- /dev/null
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DoubleCollection.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using MS.Utility;
+
+namespace System.Windows.Media;
+
+public sealed partial class DoubleCollection
+{
+ ///
+ /// Initializes a new instance using a . Elements are copied.
+ ///
+ ///
+ internal DoubleCollection(params ReadOnlySpan values)
+ {
+ _collection = new FrugalStructList(values.Length);
+
+ foreach (double item in values)
+ {
+ _collection.Add(item);
+ }
+ }
+}
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DrawingDrawingContext.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DrawingDrawingContext.cs
index 83bf679df99..b7e0da92bb7 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DrawingDrawingContext.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/DrawingDrawingContext.cs
@@ -931,11 +931,10 @@ internal override void PushGuidelineY1(
// Convert compact record to generic GuidelineSet.
//
- GuidelineSet guidelineCollection = new GuidelineSet(
- null, // x guidelines
- new double[] { coordinate, 0 }, // y guidelines
- true // dynamic flag
- );
+ GuidelineSet guidelineCollection = new(guidelinesX: ReadOnlySpan.Empty,
+ guidelinesY: [coordinate, 0],
+ isDynamic: true);
+
guidelineCollection.Freeze();
//
@@ -977,15 +976,9 @@ internal override void PushGuidelineY2(
// Convert compact record to generic GuidelineSet.
//
- GuidelineSet guidelineCollection = new GuidelineSet(
- null, // x guidelines
- new double[]
- {
- leadingCoordinate,
- offsetToDrivenCoordinate
- }, // y guidelines
- true // dynamic flag
- );
+ GuidelineSet guidelineCollection = new(guidelinesX: ReadOnlySpan.Empty,
+ guidelinesY: [leadingCoordinate, offsetToDrivenCoordinate],
+ isDynamic: true);
guidelineCollection.Freeze();
//
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/DoubleCollection.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/DoubleCollection.cs
index 00ed4afa61d..2acc631ef70 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/DoubleCollection.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/DoubleCollection.cs
@@ -13,8 +13,6 @@
using System.Windows.Markup;
using System.Windows.Media.Converters;
-// These types are aliased to match the unamanaged names used in interop
-
namespace System.Windows.Media
{
///
@@ -878,7 +876,6 @@ public double Current
//
//------------------------------------------------------
-
///
/// Initializes a new instance that is empty.
///
@@ -934,12 +931,6 @@ public DoubleCollection(IEnumerable collection)
}
}
-
-
-
-
-
-
WritePostscript();
}
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GuidelineCollection.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GuidelineCollection.cs
index 31b407ac04b..8c4bc6d425e 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GuidelineCollection.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GuidelineCollection.cs
@@ -40,21 +40,42 @@ public GuidelineSet()
/// Array of X coordinates that defines a set of vertical guidelines.
/// Array of Y coordinates that defines a set of horizontal guidelines.
/// Usage flag: when true then rendering machine will detect animation state and apply subpixel animation behavior.
- internal GuidelineSet(double[] guidelinesX, double[] guidelinesY, bool isDynamic)
+ internal GuidelineSet(ReadOnlySpan guidelinesX, ReadOnlySpan guidelinesY)
{
- if (guidelinesX != null)
+ if (!guidelinesX.IsEmpty)
{
- // Dynamic guideline is defined by a pair of numbers: (coordinate, shift),
- // so the legnth of array should be even.
+ GuidelinesX = new DoubleCollection(guidelinesX);
+ }
+
+ if (!guidelinesY.IsEmpty)
+ {
+ GuidelinesY = new DoubleCollection(guidelinesY);
+ }
+ }
+
+ ///
+ /// Constructs a new GuidelineSet object.
+ /// This constructor is internal for now, till we'll find a solution
+ /// for multi-path dynamic guideline implementation. If/when it'll happen,
+ /// it should become "public" so that the next constructor (without "isDynamic'
+ /// argument) may go away.
+ ///
+ /// Array of X coordinates that defines a set of vertical guidelines.
+ /// Array of Y coordinates that defines a set of horizontal guidelines.
+ /// Usage flag: when true then rendering machine will detect animation state and apply subpixel animation behavior.
+ internal GuidelineSet(ReadOnlySpan guidelinesX, ReadOnlySpan guidelinesY, bool isDynamic)
+ {
+ if (!guidelinesX.IsEmpty)
+ {
+ // Dynamic guideline is defined by a pair of numbers: (coordinate, shift), so the length of array should be even.
Debug.Assert(!isDynamic || guidelinesX.Length % 2 == 0);
GuidelinesX = new DoubleCollection(guidelinesX);
}
- if (guidelinesY != null)
+ if (!guidelinesY.IsEmpty)
{
- // Dynamic guideline is defined by a pair of numbers: (coordinate, shift),
- // so the legnth of array should be even.
+ // Dynamic guideline is defined by a pair of numbers: (coordinate, shift), so the length of array should be even.
Debug.Assert(!isDynamic || guidelinesY.Length % 2 == 0);
GuidelinesY = new DoubleCollection(guidelinesY);
@@ -70,14 +91,14 @@ internal GuidelineSet(double[] guidelinesX, double[] guidelinesY, bool isDynamic
/// Array of Y coordinates that defines a set of horizontal guidelines.
public GuidelineSet(double[] guidelinesX, double[] guidelinesY)
{
- if (guidelinesX != null)
+ if (guidelinesX is not null)
{
- GuidelinesX = new DoubleCollection(guidelinesX);
+ GuidelinesX = new DoubleCollection(guidelinesX.AsSpan());
}
- if (guidelinesY != null)
+ if (guidelinesY is not null)
{
- GuidelinesY = new DoubleCollection(guidelinesY);
+ GuidelinesY = new DoubleCollection(guidelinesY.AsSpan());
}
}
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs
index 196a9614f6f..8107256468a 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs
@@ -979,14 +979,13 @@ private void updatePixelSnappingGuidelines()
}
else
{
- DoubleCollection xLines = this.VisualXSnappingGuidelines;
+ DoubleCollection xLines = VisualXSnappingGuidelines;
- if(xLines == null)
+ if (xLines is null)
{
- xLines = new DoubleCollection();
- xLines.Add(0d);
- xLines.Add(this.RenderSize.Width);
- this.VisualXSnappingGuidelines = xLines;
+ xLines = new DoubleCollection(0d, RenderSize.Width);
+
+ VisualXSnappingGuidelines = xLines;
}
else
{
@@ -997,13 +996,12 @@ private void updatePixelSnappingGuidelines()
xLines[lastGuideline] = this.RenderSize.Width;
}
- DoubleCollection yLines = this.VisualYSnappingGuidelines;
- if(yLines == null)
+ DoubleCollection yLines = VisualYSnappingGuidelines;
+ if (yLines is null)
{
- yLines = new DoubleCollection();
- yLines.Add(0d);
- yLines.Add(this.RenderSize.Height);
- this.VisualYSnappingGuidelines = yLines;
+ yLines = new DoubleCollection(0d, RenderSize.Height);
+
+ VisualYSnappingGuidelines = yLines;
}
else
{
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasFeedbackAdorner.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasFeedbackAdorner.cs
index a0f118b5c72..9f68328bdc1 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasFeedbackAdorner.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasFeedbackAdorner.cs
@@ -34,12 +34,12 @@ internal InkCanvasFeedbackAdorner(InkCanvas inkCanvas)
// Initialize the internal data
_inkCanvas = inkCanvas;
- _adornerBorderPen = new Pen(Brushes.Black, 1.0);
- DoubleCollection dashes = new DoubleCollection();
- dashes.Add(4.5);
- dashes.Add(4.5);
- _adornerBorderPen.DashStyle = new DashStyle(dashes, 2.25);
- _adornerBorderPen.DashCap = PenLineCap.Flat;
+ _adornerBorderPen = new Pen(Brushes.Black, 1.0)
+ {
+ DashStyle = new DashStyle(new DoubleCollection(4.5, 4.5), 2.25),
+ DashCap = PenLineCap.Flat
+ };
+ _adornerBorderPen.Freeze();
}
///
@@ -167,7 +167,7 @@ internal void UpdateBounds(Rect rect)
private double _offsetX = 0;
private double _offsetY = 0;
- private Pen _adornerBorderPen;
+ private readonly Pen _adornerBorderPen;
private const int CornerResizeHandleSize = 8;
private const double BorderMargin = 8f;
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasSelectionAdorner.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasSelectionAdorner.cs
index 7cf65defd42..6a81ac31c82 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasSelectionAdorner.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InkCanvasSelectionAdorner.cs
@@ -30,12 +30,11 @@ internal InkCanvasSelectionAdorner(UIElement adornedElement)
"InkCanvasSelectionAdorner only should be used by InkCanvas internally");
// Initialize the internal data.
- _adornerBorderPen = new Pen(Brushes.Black, 1.0);
- DoubleCollection dashes = new DoubleCollection();
- dashes.Add(4.5);
- dashes.Add(4.5);
- _adornerBorderPen.DashStyle = new DashStyle(dashes, 2.25);
- _adornerBorderPen.DashCap = PenLineCap.Flat;
+ _adornerBorderPen = new Pen(Brushes.Black, 1.0)
+ {
+ DashStyle = new DashStyle(new DoubleCollection(4.5, 4.5), 2.25),
+ DashCap = PenLineCap.Flat
+ };
_adornerBorderPen.Freeze();
_adornerPenBrush = new Pen(new SolidColorBrush(Color.FromRgb(132, 146, 222)), 1);
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs
index 094eb22b5b7..cdcb876f708 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs
@@ -3963,20 +3963,20 @@ internal class GridLinesRenderer : DrawingVisual
///
static GridLinesRenderer()
{
- s_oddDashPen = new Pen(Brushes.Blue, c_penWidth);
- DoubleCollection oddDashArray = new DoubleCollection();
- oddDashArray.Add(c_dashLength);
- oddDashArray.Add(c_dashLength);
- s_oddDashPen.DashStyle = new DashStyle(oddDashArray, 0);
- s_oddDashPen.DashCap = PenLineCap.Flat;
+ DoubleCollection dashArray = new DoubleCollection(DashLength, DashLength);
+
+ s_oddDashPen = new Pen(Brushes.Blue, PenWidth)
+ {
+ DashStyle = new DashStyle(dashArray, 0),
+ DashCap = PenLineCap.Flat
+ };
s_oddDashPen.Freeze();
- s_evenDashPen = new Pen(Brushes.Yellow, c_penWidth);
- DoubleCollection evenDashArray = new DoubleCollection();
- evenDashArray.Add(c_dashLength);
- evenDashArray.Add(c_dashLength);
- s_evenDashPen.DashStyle = new DashStyle(evenDashArray, c_dashLength);
- s_evenDashPen.DashCap = PenLineCap.Flat;
+ s_evenDashPen = new Pen(Brushes.Yellow, PenWidth)
+ {
+ DashStyle = new DashStyle(dashArray, DashLength),
+ DashCap = PenLineCap.Flat
+ };
s_evenDashPen.Freeze();
}
@@ -4029,11 +4029,10 @@ private static void DrawGridLine(
drawingContext.DrawLine(s_evenDashPen, start, end);
}
- private const double c_dashLength = 4.0; //
- private const double c_penWidth = 1.0; //
+ private const double DashLength = 4.0; //
+ private const double PenWidth = 1.0; //
private static readonly Pen s_oddDashPen; // first pen to draw dash
private static readonly Pen s_evenDashPen; // second pen to draw dash
- private static readonly Point c_zeroPoint = new Point(0, 0);
}
#endregion Private Structures Classes
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TickBar.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TickBar.cs
index 59c50dd102d..96571b630d4 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TickBar.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TickBar.cs
@@ -430,11 +430,11 @@ protected override void OnRender(DrawingContext dc)
Pen pen = new Pen(Fill, 1.0d);
bool snapsToDevicePixels = SnapsToDevicePixels;
- DoubleCollection xLines = snapsToDevicePixels ? new DoubleCollection() : null;
- DoubleCollection yLines = snapsToDevicePixels ? new DoubleCollection() : null;
+ DoubleCollection xLines = snapsToDevicePixels ? new DoubleCollection(4) : null;
+ DoubleCollection yLines = snapsToDevicePixels ? new DoubleCollection(6) : null;
// Is it Vertical?
- if ((Placement == TickBarPlacement.Left) || (Placement == TickBarPlacement.Right))
+ if (Placement is TickBarPlacement.Left or TickBarPlacement.Right)
{
// Reduce tick interval if it is more than would be visible on the screen
double interval = TickFrequency;
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CaretElement.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CaretElement.cs
index dda1e5c2cbb..bb2eaeed5e9 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CaretElement.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CaretElement.cs
@@ -683,7 +683,9 @@ internal void OnRenderCaretSubElement(DrawingContext context)
// Snap the caret to device pixels.
if (!_italic || threadLocalStore.Bidi)
{
- GuidelineSet guidelineSet = new GuidelineSet(new double[] { -(_systemCaretWidth / 2), _systemCaretWidth / 2 }, null);
+ GuidelineSet guidelineSet = new(guidelinesX: [-(_systemCaretWidth / 2), _systemCaretWidth / 2],
+ guidelinesY: ReadOnlySpan.Empty);
+
context.PushGuidelineSet(guidelineSet);
contextPushedCount++;
}
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CompositionAdorner.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CompositionAdorner.cs
index d6377ca7507..8331e525e80 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CompositionAdorner.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CompositionAdorner.cs
@@ -146,8 +146,6 @@ protected override void OnRender(DrawingContext drawingContext)
// Render the each of the composition string attribute from the attribute ranges.
for (int i = 0; i < _attributeRanges.Count; i++)
{
- DoubleCollection dashArray;
-
// Get the composition attribute range from the attribute range lists
AttributeRange attributeRange = (AttributeRange)_attributeRanges[i];
@@ -186,14 +184,10 @@ protected override void OnRender(DrawingContext drawingContext)
{
case UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_DOT:
// Add the dot length and specify the start/end line cap as the round
- dashArray = new DoubleCollection();
- dashArray.Add(DotLength);
- dashArray.Add(DotLength);
-
- pen.DashStyle = new DashStyle(dashArray, 0);
- pen.DashCap = System.Windows.Media.PenLineCap.Round;
- pen.StartLineCap = System.Windows.Media.PenLineCap.Round;
- pen.EndLineCap = System.Windows.Media.PenLineCap.Round;
+ pen.DashStyle = new DashStyle(new DoubleCollection(DotLength, DotLength), 0);
+ pen.DashCap = PenLineCap.Round;
+ pen.StartLineCap = PenLineCap.Round;
+ pen.EndLineCap = PenLineCap.Round;
// Update the line height for the dot line. Dot line will be more thickness than
// other line to show it clearly.
@@ -205,21 +199,17 @@ protected override void OnRender(DrawingContext drawingContext)
double dashLength = height * (lineBold ? BoldDashRatio : NormalDashRatio);
double dashGapLength = height * (lineBold ? BoldDashGapRatio : NormalDashGapRatio);
- // Add the dash and dash gap legth
- dashArray = new DoubleCollection();
- dashArray.Add(dashLength);
- dashArray.Add(dashGapLength);
-
- pen.DashStyle = new DashStyle(dashArray, 0);
- pen.DashCap = System.Windows.Media.PenLineCap.Round;
- pen.StartLineCap = System.Windows.Media.PenLineCap.Round;
- pen.EndLineCap = System.Windows.Media.PenLineCap.Round;
+ // Add the dash and dash gap length
+ pen.DashStyle = new DashStyle(new DoubleCollection(dashLength, dashGapLength), 0);
+ pen.DashCap = PenLineCap.Round;
+ pen.StartLineCap = PenLineCap.Round;
+ pen.EndLineCap = PenLineCap.Round;
break;
case UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_SOLID:
- pen.StartLineCap = System.Windows.Media.PenLineCap.Round;
- pen.EndLineCap = System.Windows.Media.PenLineCap.Round;
+ pen.StartLineCap = PenLineCap.Round;
+ pen.EndLineCap = PenLineCap.Round;
break;
diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/AlphaFlattener/Primitive.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/AlphaFlattener/Primitive.cs
index 96676c6073d..9fe25907d40 100644
--- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/AlphaFlattener/Primitive.cs
+++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/AlphaFlattener/Primitive.cs
@@ -560,10 +560,10 @@ protected int PushAll(DrawingContext dc)
{
Rect bounds = GetRectBounds(true);
- double[] snapx = new double[] { bounds.Left, bounds.Right };
- double[] snapy = new double[] { bounds.Top, bounds.Bottom };
+ ReadOnlySpan snapX = [bounds.Left, bounds.Right];
+ ReadOnlySpan snapY = [bounds.Top, bounds.Bottom];
- dc.PushGuidelineSet(new GuidelineSet(snapx, snapy));
+ dc.PushGuidelineSet(new GuidelineSet(snapX, snapY));
level++;
}