diff --git a/src/ImageSharp.Drawing/Brushes/ImageBrush{TColor}.cs b/src/ImageSharp.Drawing/Brushes/ImageBrush{TColor}.cs index 080111f61..718705b39 100644 --- a/src/ImageSharp.Drawing/Brushes/ImageBrush{TColor}.cs +++ b/src/ImageSharp.Drawing/Brushes/ImageBrush{TColor}.cs @@ -119,7 +119,7 @@ namespace ImageSharp.Drawing.Brushes using (PinnedBuffer buffer = new PinnedBuffer(scanlineBuffer)) { - BufferPointer slice = buffer.Slice(offset); + BufferSpan slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { diff --git a/src/ImageSharp.Drawing/Brushes/PatternBrush{TColor}.cs b/src/ImageSharp.Drawing/Brushes/PatternBrush{TColor}.cs index 2b4d3ec73..df492a764 100644 --- a/src/ImageSharp.Drawing/Brushes/PatternBrush{TColor}.cs +++ b/src/ImageSharp.Drawing/Brushes/PatternBrush{TColor}.cs @@ -152,7 +152,7 @@ namespace ImageSharp.Drawing.Brushes using (PinnedBuffer buffer = new PinnedBuffer(scanlineBuffer)) { - BufferPointer slice = buffer.Slice(offset); + BufferSpan slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { diff --git a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs index 2c460e88e..46444e550 100644 --- a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs +++ b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs @@ -57,7 +57,7 @@ namespace ImageSharp.Drawing.Processors using (PinnedBuffer buffer = new PinnedBuffer(scanlineBuffer)) { - BufferPointer slice = buffer.Slice(offset); + BufferSpan slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { diff --git a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TColor}.cs b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TColor}.cs index 0c6e86643..257eeb3ae 100644 --- a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TColor}.cs +++ b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TColor}.cs @@ -143,7 +143,7 @@ namespace ImageSharp.Drawing.Brushes using (PinnedBuffer buffer = new PinnedBuffer(scanlineBuffer)) { - BufferPointer slice = buffer.Slice(offset); + BufferSpan slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { diff --git a/src/ImageSharp.Drawing/Brushes/SolidBrush{TColor}.cs b/src/ImageSharp.Drawing/Brushes/SolidBrush{TColor}.cs index e001829b0..125b07bca 100644 --- a/src/ImageSharp.Drawing/Brushes/SolidBrush{TColor}.cs +++ b/src/ImageSharp.Drawing/Brushes/SolidBrush{TColor}.cs @@ -91,7 +91,7 @@ namespace ImageSharp.Drawing.Brushes using (PinnedBuffer buffer = new PinnedBuffer(scanlineBuffer)) { - BufferPointer slice = buffer.Slice(offset); + BufferSpan slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { diff --git a/src/ImageSharp/Common/Memory/BufferSpan{T}.cs b/src/ImageSharp/Common/Memory/BufferSpan{T}.cs index f3cb85884..8ef88814c 100644 --- a/src/ImageSharp/Common/Memory/BufferSpan{T}.cs +++ b/src/ImageSharp/Common/Memory/BufferSpan{T}.cs @@ -106,6 +106,23 @@ namespace ImageSharp /// public IntPtr PointerAtOffset { get; private set; } + /// + /// Returns a reference to specified element of the span. + /// + /// The index + /// The reference to the specified element + public ref T this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + DebugGuard.MustBeLessThan(index, this.Length, nameof(index)); + + byte* ptr = (byte*)this.PointerAtOffset + BufferSpan.SizeOf(index); + return ref Unsafe.AsRef(ptr); + } + } + /// /// Convertes instance to a raw 'void*' pointer /// diff --git a/tests/ImageSharp.Tests/Common/BufferSpanTests.cs b/tests/ImageSharp.Tests/Common/BufferSpanTests.cs index f524bdb43..36cfe1b2a 100644 --- a/tests/ImageSharp.Tests/Common/BufferSpanTests.cs +++ b/tests/ImageSharp.Tests/Common/BufferSpanTests.cs @@ -209,6 +209,51 @@ namespace ImageSharp.Tests.Common } + public class Indexer + { + public static readonly TheoryData IndexerData = + new TheoryData() + { + { 10, 0, 0 }, + { 10, 2, 0 }, + { 16, 0, 3 }, + { 16, 2, 3 }, + { 10, 0, 9 }, + { 10, 1, 8 } + }; + + [Theory] + [MemberData(nameof(IndexerData))] + public void Read(int length, int start, int index) + { + Foo[] a = Foo.CreateArray(length); + fixed (Foo* p = a) + { + BufferSpan span = new BufferSpan(a, p, start); + + Foo element = span[index]; + + Assert.Equal(a[start + index], element); + } + } + + [Theory] + [MemberData(nameof(IndexerData))] + public void Write(int length, int start, int index) + { + Foo[] a = Foo.CreateArray(length); + fixed (Foo* p = a) + { + BufferSpan span = new BufferSpan(a, p, start); + + span[index] = new Foo(666, 666); + + Assert.Equal(new Foo(666, 666), a[start + index]); + } + } + } + + public class Copy { private static void AssertNotDefault(T[] data, int idx) @@ -443,6 +488,7 @@ namespace ImageSharp.Tests.Common } } + internal static bool ElementsAreEqual(Foo[] array, byte[] rawArray, int index) { fixed (Foo* pArray = array)