diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs
index 4e6018e07..add34ca36 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs
@@ -1,95 +1,101 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Buffers;
-using System.Threading.Tasks;
-using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.Memory;
-using SixLabors.Primitives;
-
-namespace SixLabors.ImageSharp.Processing.Processors.Drawing
-{
- ///
- /// Combines two images together by blending the pixels.
- ///
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Buffers;
+using System.Threading.Tasks;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.ParallelUtils;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Memory;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Processors.Drawing
+{
+ ///
+ /// Combines two images together by blending the pixels.
+ ///
/// The pixel format of destination image.
- /// The pixel format os source image.
- internal class DrawImageProcessor : ImageProcessor
+ /// The pixel format os source image.
+ internal class DrawImageProcessor : ImageProcessor
where TPixelDst : struct, IPixel
- where TPixelSrc : struct, IPixel
+ where TPixelSrc : struct, IPixel
{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The image to blend with the currently processing image.
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The image to blend with the currently processing image.
/// The location to draw the blended image.
/// The blending mode to use when drawing the image.
/// The Alpha blending mode to use when drawing the image.
- /// The opacity of the image to blend. Must be between 0 and 1.
- public DrawImageProcessor(Image image, Point location, PixelColorBlendingMode colorBlendingMode, PixelAlphaCompositionMode alphaCompositionMode, float opacity)
- {
- Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
-
- this.Image = image;
- this.Opacity = opacity;
- this.Blender = PixelOperations.Instance.GetPixelBlender(colorBlendingMode, alphaCompositionMode);
- this.Location = location;
- }
-
- ///
- /// Gets the image to blend
- ///
- public Image Image { get; }
-
- ///
- /// Gets the opacity of the image to blend
- ///
- public float Opacity { get; }
-
- ///
- /// Gets the pixel blender
- ///
- public PixelBlender Blender { get; }
-
- ///
- /// Gets the location to draw the blended image
- ///
- public Point Location { get; }
-
- ///
- protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
- {
- Image targetImage = this.Image;
- PixelBlender blender = this.Blender;
- int locationY = this.Location.Y;
-
- // Align start/end positions.
- Rectangle bounds = targetImage.Bounds();
-
- int minX = Math.Max(this.Location.X, sourceRectangle.X);
- int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
- int targetX = minX - this.Location.X;
-
- int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
- int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);
-
- int width = maxX - minX;
-
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ public DrawImageProcessor(Image image, Point location, PixelColorBlendingMode colorBlendingMode, PixelAlphaCompositionMode alphaCompositionMode, float opacity)
+ {
+ Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
+
+ this.Image = image;
+ this.Opacity = opacity;
+ this.Blender = PixelOperations.Instance.GetPixelBlender(colorBlendingMode, alphaCompositionMode);
+ this.Location = location;
+ }
+
+ ///
+ /// Gets the image to blend
+ ///
+ public Image Image { get; }
+
+ ///
+ /// Gets the opacity of the image to blend
+ ///
+ public float Opacity { get; }
+
+ ///
+ /// Gets the pixel blender
+ ///
+ public PixelBlender Blender { get; }
+
+ ///
+ /// Gets the location to draw the blended image
+ ///
+ public Point Location { get; }
+
+ ///
+ protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
+ {
+ Image targetImage = this.Image;
+ PixelBlender blender = this.Blender;
+ int locationY = this.Location.Y;
+
+ // Align start/end positions.
+ Rectangle bounds = targetImage.Bounds();
+
+ int minX = Math.Max(this.Location.X, sourceRectangle.X);
+ int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
+ int targetX = minX - this.Location.X;
+
+ int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
+ int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);
+
+ int width = maxX - minX;
+
MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator;
- ParallelFor.WithConfiguration(
- minY,
- maxY,
- configuration,
- y =>
- {
- Span background = source.GetPixelRowSpan(y).Slice(minX, width);
- Span foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
- blender.Blend(memoryAllocator, background, background, foreground, this.Opacity);
- });
- }
- }
+ var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
+
+ ParallelHelper.IterateRows(
+ workingRect,
+ configuration,
+ rows =>
+ {
+ for (int y = rows.Min; y < rows.Max; y++)
+ {
+ Span background = source.GetPixelRowSpan(y).Slice(minX, width);
+ Span foreground =
+ targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
+ blender.Blend(memoryAllocator, background, background, foreground, this.Opacity);
+ }
+ });
+ }
+ }
}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
index 3285e75a7..4f2be309b 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
@@ -1,107 +1,107 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Buffers;
-using System.Threading.Tasks;
-using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.Memory;
-using SixLabors.Primitives;
-
-namespace SixLabors.ImageSharp.Processing.Processors.Drawing
-{
- ///
- /// Using the brush as a source of pixels colors blends the brush color with source.
- ///
- /// The pixel format.
- internal class FillProcessor : ImageProcessor
- where TPixel : struct, IPixel
- {
- ///
- /// The brush.
- ///
- private readonly IBrush brush;
- private readonly GraphicsOptions options;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The brush to source pixel colors from.
- /// The options
- public FillProcessor(IBrush brush, GraphicsOptions options)
- {
- this.brush = brush;
- this.options = options;
- }
-
- ///
- protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
- {
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- int startY = sourceRectangle.Y;
- int endY = sourceRectangle.Bottom;
-
- // Align start/end positions.
- int minX = Math.Max(0, startX);
- int maxX = Math.Min(source.Width, endX);
- int minY = Math.Max(0, startY);
- int maxY = Math.Min(source.Height, endY);
-
- int width = maxX - minX;
-
- // If there's no reason for blending, then avoid it.
- if (this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush))
- {
- ParallelFor.WithConfiguration(
- minY,
- maxY,
- configuration,
- y =>
- {
- source.GetPixelRowSpan(y).Slice(minX, width).Fill(solidBrush.Color);
- });
- }
- else
- {
- // Reset offset if necessary.
- if (minX > 0)
- {
- startX = 0;
- }
-
- if (minY > 0)
- {
- startY = 0;
- }
-
- using (IMemoryOwner amount = source.MemoryAllocator.Allocate(width))
- using (BrushApplicator applicator = this.brush.CreateApplicator(
- source,
- sourceRectangle,
- this.options))
- {
- amount.GetSpan().Fill(1f);
-
- ParallelFor.WithConfiguration(
- minY,
- maxY,
- configuration,
- y =>
- {
- int offsetY = y - startY;
- int offsetX = minX - startX;
-
- applicator.Apply(amount.GetSpan(), offsetX, offsetY);
- });
- }
- }
- }
-
- private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush)
- {
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Buffers;
+using System.Threading.Tasks;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Memory;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Processors.Drawing
+{
+ ///
+ /// Using the brush as a source of pixels colors blends the brush color with source.
+ ///
+ /// The pixel format.
+ internal class FillProcessor : ImageProcessor
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// The brush.
+ ///
+ private readonly IBrush brush;
+ private readonly GraphicsOptions options;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The brush to source pixel colors from.
+ /// The options
+ public FillProcessor(IBrush brush, GraphicsOptions options)
+ {
+ this.brush = brush;
+ this.options = options;
+ }
+
+ ///
+ protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
+ {
+ int startX = sourceRectangle.X;
+ int endX = sourceRectangle.Right;
+ int startY = sourceRectangle.Y;
+ int endY = sourceRectangle.Bottom;
+
+ // Align start/end positions.
+ int minX = Math.Max(0, startX);
+ int maxX = Math.Min(source.Width, endX);
+ int minY = Math.Max(0, startY);
+ int maxY = Math.Min(source.Height, endY);
+
+ int width = maxX - minX;
+
+ // If there's no reason for blending, then avoid it.
+ if (this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush))
+ {
+ ParallelFor.WithConfiguration(
+ minY,
+ maxY,
+ configuration,
+ y =>
+ {
+ source.GetPixelRowSpan(y).Slice(minX, width).Fill(solidBrush.Color);
+ });
+ }
+ else
+ {
+ // Reset offset if necessary.
+ if (minX > 0)
+ {
+ startX = 0;
+ }
+
+ if (minY > 0)
+ {
+ startY = 0;
+ }
+
+ using (IMemoryOwner amount = source.MemoryAllocator.Allocate(width))
+ using (BrushApplicator applicator = this.brush.CreateApplicator(
+ source,
+ sourceRectangle,
+ this.options))
+ {
+ amount.GetSpan().Fill(1f);
+
+ ParallelFor.WithConfiguration(
+ minY,
+ maxY,
+ configuration,
+ y =>
+ {
+ int offsetY = y - startY;
+ int offsetX = minX - startX;
+
+ applicator.Apply(amount.GetSpan(), offsetX, offsetY);
+ });
+ }
+ }
+ }
+
+ private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush)
+ {
solidBrush = this.brush as SolidBrush;
if (solidBrush == null)
@@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
return false;
}
- return this.options.IsOpaqueColorWithoutBlending(solidBrush.Color);
- }
- }
+ return this.options.IsOpaqueColorWithoutBlending(solidBrush.Color);
+ }
+ }
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Drawing/FillPatternTests.cs b/tests/ImageSharp.Tests/Drawing/FillPatternTests.cs
index 93715c586..b310c7afc 100644
--- a/tests/ImageSharp.Tests/Drawing/FillPatternTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/FillPatternTests.cs
@@ -54,172 +54,225 @@ namespace SixLabors.ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeFloodFilledWithPercent10()
{
- this.Test("Percent10", Rgba32.Blue, Brushes.Percent10(Rgba32.HotPink, Rgba32.LimeGreen),
+ this.Test(
+ "Percent10",
+ Rgba32.Blue,
+ Brushes.Percent10(Rgba32.HotPink, Rgba32.LimeGreen),
new[,]
- {
- { Rgba32.HotPink , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink , Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen}
- });
+ {
+ { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent10Transparent()
{
- Test("Percent10_Transparent", Rgba32.Blue, Brushes.Percent10(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.HotPink , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink , Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue}
- });
+ this.Test(
+ "Percent10_Transparent",
+ Rgba32.Blue,
+ Brushes.Percent10(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent20()
{
- Test("Percent20", Rgba32.Blue, Brushes.Percent20(Rgba32.HotPink, Rgba32.LimeGreen),
- new Rgba32[,] {
- { Rgba32.HotPink , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink , Rgba32.LimeGreen},
- { Rgba32.HotPink , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink , Rgba32.LimeGreen}
- });
+ this.Test(
+ "Percent20",
+ Rgba32.Blue,
+ Brushes.Percent20(Rgba32.HotPink, Rgba32.LimeGreen),
+ new Rgba32[,]
+ {
+ { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen },
+ { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent20_transparent()
{
- Test("Percent20_Transparent", Rgba32.Blue, Brushes.Percent20(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.HotPink , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink , Rgba32.Blue},
- { Rgba32.HotPink , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink , Rgba32.Blue}
- });
+ this.Test(
+ "Percent20_Transparent",
+ Rgba32.Blue,
+ Brushes.Percent20(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue },
+ { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithHorizontal()
{
- Test("Horizontal", Rgba32.Blue, Brushes.Horizontal(Rgba32.HotPink, Rgba32.LimeGreen),
- new Rgba32[,] {
- { Rgba32.LimeGreen , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink , Rgba32.HotPink},
- { Rgba32.LimeGreen , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen , Rgba32.LimeGreen}
- });
+ this.Test(
+ "Horizontal",
+ Rgba32.Blue,
+ Brushes.Horizontal(Rgba32.HotPink, Rgba32.LimeGreen),
+ new Rgba32[,]
+ {
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithHorizontal_transparent()
{
- Test("Horizontal_Transparent", Rgba32.Blue, Brushes.Horizontal(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.Blue , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink , Rgba32.HotPink},
- { Rgba32.Blue , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue , Rgba32.Blue}
- });
+ this.Test(
+ "Horizontal_Transparent",
+ Rgba32.Blue,
+ Brushes.Horizontal(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue }
+ });
}
-
-
[Fact]
public void ImageShouldBeFloodFilledWithMin()
{
- Test("Min", Rgba32.Blue, Brushes.Min(Rgba32.HotPink, Rgba32.LimeGreen),
- new Rgba32[,] {
- { Rgba32.LimeGreen , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen , Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen , Rgba32.LimeGreen},
- { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink , Rgba32.HotPink}
- });
+ this.Test(
+ "Min",
+ Rgba32.Blue,
+ Brushes.Min(Rgba32.HotPink, Rgba32.LimeGreen),
+ new Rgba32[,]
+ {
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithMin_transparent()
{
- Test("Min_Transparent", Rgba32.Blue, Brushes.Min(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.Blue , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue , Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue , Rgba32.Blue},
- { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink , Rgba32.HotPink},
- });
+ this.Test(
+ "Min_Transparent",
+ Rgba32.Blue,
+ Brushes.Min(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink, Rgba32.HotPink },
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithVertical()
{
- Test("Vertical", Rgba32.Blue, Brushes.Vertical(Rgba32.HotPink, Rgba32.LimeGreen),
- new Rgba32[,] {
- { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen}
- });
+ this.Test(
+ "Vertical",
+ Rgba32.Blue,
+ Brushes.Vertical(Rgba32.HotPink, Rgba32.LimeGreen),
+ new Rgba32[,]
+ {
+ { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithVertical_transparent()
{
- Test("Vertical_Transparent", Rgba32.Blue, Brushes.Vertical(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue}
- });
+ this.Test(
+ "Vertical_Transparent",
+ Rgba32.Blue,
+ Brushes.Vertical(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithForwardDiagonal()
{
- Test("ForwardDiagonal", Rgba32.Blue, Brushes.ForwardDiagonal(Rgba32.HotPink, Rgba32.LimeGreen),
- new Rgba32[,] {
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen}
- });
+ this.Test(
+ "ForwardDiagonal",
+ Rgba32.Blue,
+ Brushes.ForwardDiagonal(Rgba32.HotPink, Rgba32.LimeGreen),
+ new Rgba32[,]
+ {
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithForwardDiagonal_transparent()
{
- Test("ForwardDiagonal_Transparent", Rgba32.Blue, Brushes.ForwardDiagonal(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue}
- });
+ this.Test(
+ "ForwardDiagonal_Transparent",
+ Rgba32.Blue,
+ Brushes.ForwardDiagonal(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithBackwardDiagonal()
{
- Test("BackwardDiagonal", Rgba32.Blue, Brushes.BackwardDiagonal(Rgba32.HotPink, Rgba32.LimeGreen),
- new Rgba32[,] {
- { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen},
- { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink}
- });
+ this.Test(
+ "BackwardDiagonal",
+ Rgba32.Blue,
+ Brushes.BackwardDiagonal(Rgba32.HotPink, Rgba32.LimeGreen),
+ new Rgba32[,]
+ {
+ { Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink, Rgba32.LimeGreen },
+ { Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.LimeGreen, Rgba32.HotPink }
+ });
}
[Fact]
public void ImageShouldBeFloodFilledWithBackwardDiagonal_transparent()
{
- Test("BackwardDiagonal_Transparent", Rgba32.Blue, Brushes.BackwardDiagonal(Rgba32.HotPink),
- new Rgba32[,] {
- { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue},
- { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink}
- });
+ this.Test(
+ "BackwardDiagonal_Transparent",
+ Rgba32.Blue,
+ Brushes.BackwardDiagonal(Rgba32.HotPink),
+ new Rgba32[,]
+ {
+ { Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink, Rgba32.Blue },
+ { Rgba32.Blue, Rgba32.Blue, Rgba32.Blue, Rgba32.HotPink }
+ });
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs b/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
index e86d41f57..32f723e72 100644
--- a/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
@@ -1,20 +1,21 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using System;
+
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Primitives;
+using SixLabors.ImageSharp.Processing;
+using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+using SixLabors.Primitives;
using SixLabors.Shapes;
+
using Xunit;
+
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Drawing
{
- using System;
-
- using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
- using SixLabors.Primitives;
-
[GroupOutput("Drawing")]
public class FillSolidBrushTests
{
@@ -55,7 +56,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing
[Theory]
[WithSolidFilledImages(16, 16, "Red", PixelTypes.Rgba32, "Blue")]
[WithSolidFilledImages(16, 16, "Yellow", PixelTypes.Rgba32, "Khaki")]
- public void WhenColorIsOpaque_OverridePreviousColor(TestImageProvider provider, string newColorName)
+ public void WhenColorIsOpaque_OverridePreviousColor(
+ TestImageProvider provider,
+ string newColorName)
where TPixel : struct, IPixel
{
using (Image image = provider.GetImage())
@@ -63,7 +66,11 @@ namespace SixLabors.ImageSharp.Tests.Drawing
TPixel color = TestUtils.GetPixelOfNamedColor(newColorName);
image.Mutate(c => c.Fill(color));
- image.DebugSave(provider, newColorName, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
+ image.DebugSave(
+ provider,
+ newColorName,
+ appendPixelTypeToFileName: false,
+ appendSourceFileOrDescription: false);
image.ComparePixelBufferTo(color);
}
}
@@ -84,7 +91,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing
[Theory]
[WithSolidFilledImages(16, 16, "Red", PixelTypes.Rgba32, 5, 7, 3, 8)]
[WithSolidFilledImages(16, 16, "Red", PixelTypes.Rgba32, 8, 5, 6, 4)]
- public void FillRegion_WorksOnWrappedMemoryImage(TestImageProvider provider, int x0, int y0, int w, int h)
+ public void FillRegion_WorksOnWrappedMemoryImage(
+ TestImageProvider provider,
+ int x0,
+ int y0,
+ int w,
+ int h)
where TPixel : struct, IPixel
{
FormattableString testDetails = $"(x{x0},y{y0},w{w},h{h})";
@@ -105,27 +117,22 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{ false, "Blue", 1.0f, PixelColorBlendingMode.Normal, 0.5f },
{ false, "Green", 0.5f, PixelColorBlendingMode.Normal, 0.3f },
{ false, "HotPink", 0.8f, PixelColorBlendingMode.Normal, 0.8f },
-
{ false, "Blue", 0.5f, PixelColorBlendingMode.Multiply, 1.0f },
{ false, "Blue", 1.0f, PixelColorBlendingMode.Multiply, 0.5f },
{ false, "Green", 0.5f, PixelColorBlendingMode.Multiply, 0.3f },
{ false, "HotPink", 0.8f, PixelColorBlendingMode.Multiply, 0.8f },
-
{ false, "Blue", 0.5f, PixelColorBlendingMode.Add, 1.0f },
{ false, "Blue", 1.0f, PixelColorBlendingMode.Add, 0.5f },
{ false, "Green", 0.5f, PixelColorBlendingMode.Add, 0.3f },
{ false, "HotPink", 0.8f, PixelColorBlendingMode.Add, 0.8f },
-
{ true, "Blue", 0.5f, PixelColorBlendingMode.Normal, 1.0f },
{ true, "Blue", 1.0f, PixelColorBlendingMode.Normal, 0.5f },
{ true, "Green", 0.5f, PixelColorBlendingMode.Normal, 0.3f },
{ true, "HotPink", 0.8f, PixelColorBlendingMode.Normal, 0.8f },
-
{ true, "Blue", 0.5f, PixelColorBlendingMode.Multiply, 1.0f },
{ true, "Blue", 1.0f, PixelColorBlendingMode.Multiply, 0.5f },
{ true, "Green", 0.5f, PixelColorBlendingMode.Multiply, 0.3f },
{ true, "HotPink", 0.8f, PixelColorBlendingMode.Multiply, 0.8f },
-
{ true, "Blue", 0.5f, PixelColorBlendingMode.Add, 1.0f },
{ true, "Blue", 1.0f, PixelColorBlendingMode.Add, 0.5f },
{ true, "Green", 0.5f, PixelColorBlendingMode.Add, 0.3f },
@@ -155,8 +162,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
var options = new GraphicsOptions(false)
{
- ColorBlendingMode = blenderMode,
- BlendPercentage = blendPercentage
+ ColorBlendingMode = blenderMode, BlendPercentage = blendPercentage
};
if (triggerFillRegion)
@@ -185,11 +191,13 @@ namespace SixLabors.ImageSharp.Tests.Drawing
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
- PixelBlender blender = PixelOperations.Instance.GetPixelBlender(blenderMode, PixelAlphaCompositionMode.SrcOver);
+ PixelBlender blender = PixelOperations.Instance.GetPixelBlender(
+ blenderMode,
+ PixelAlphaCompositionMode.SrcOver);
TPixel expectedPixel = blender.Blend(bgColor, fillColor, blendPercentage);
image.ComparePixelBufferTo(expectedPixel);
}
}
}
-}
+}
\ No newline at end of file